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
54#include <bits/binders.h>
55#include <bits/ranges_util.h>
56#include <bits/refwrap.h>
58#define __glibcxx_want_algorithm_default_value_type
59#define __glibcxx_want_ranges
60#define __glibcxx_want_ranges_as_const
61#define __glibcxx_want_ranges_as_rvalue
62#define __glibcxx_want_ranges_cache_latest
63#define __glibcxx_want_ranges_cartesian_product
64#define __glibcxx_want_ranges_concat
65#define __glibcxx_want_ranges_chunk
66#define __glibcxx_want_ranges_chunk_by
67#define __glibcxx_want_ranges_enumerate
68#define __glibcxx_want_ranges_indices
69#define __glibcxx_want_ranges_join_with
70#define __glibcxx_want_ranges_repeat
71#define __glibcxx_want_ranges_slide
72#define __glibcxx_want_ranges_stride
73#define __glibcxx_want_ranges_to_container
74#define __glibcxx_want_ranges_to_input
75#define __glibcxx_want_ranges_zip
76#include <bits/version.h>
78#ifdef __glibcxx_generator // C++ >= 23 && __glibcxx_coroutine
79# include <bits/elements_of.h>
83 * @defgroup ranges Ranges
85 * Components for dealing with ranges of elements.
88namespace std _GLIBCXX_VISIBILITY(default)
90_GLIBCXX_BEGIN_NAMESPACE_VERSION
93 // [range.access] customization point objects
94 // [range.req] range and view concepts
95 // [range.dangling] dangling iterator handling
96 // Defined in <bits/ranges_base.h>
98 // [view.interface] View interface
99 // [range.subrange] Sub-ranges
100 // Defined in <bits/ranges_util.h>
102 // C++20 24.6 [range.factories] Range factories
104 /// A view that contains no elements.
105 template<typename _Tp> requires is_object_v<_Tp>
107 : public view_interface<empty_view<_Tp>>
110 static constexpr _Tp* begin() noexcept { return nullptr; }
111 static constexpr _Tp* end() noexcept { return nullptr; }
112 static constexpr _Tp* data() noexcept { return nullptr; }
113 static constexpr size_t size() noexcept { return 0; }
114 static constexpr bool empty() noexcept { return true; }
117 template<typename _Tp>
118 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
122#if __cpp_lib_ranges >= 202207L // C++ >= 23
123 // P2494R2 Relaxing range adaptors to allow for move only types
124 template<typename _Tp>
125 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
127 template<typename _Tp>
128 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
131 template<__boxable _Tp>
132 struct __box : std::optional<_Tp>
134 using std::optional<_Tp>::optional;
138 noexcept(is_nothrow_default_constructible_v<_Tp>)
139 requires default_initializable<_Tp>
140 : std::optional<_Tp>{std::in_place}
143 __box(const __box&) = default;
144 __box(__box&&) = default;
146 using std::optional<_Tp>::operator=;
148 // _GLIBCXX_RESOLVE_LIB_DEFECTS
149 // 3477. Simplify constraints for semiregular-box
150 // 3572. copyable-box should be fully constexpr
152 operator=(const __box& __that)
153 noexcept(is_nothrow_copy_constructible_v<_Tp>)
154 requires (!copyable<_Tp>) && copy_constructible<_Tp>
156 if (this != std::__addressof(__that))
159 this->emplace(*__that);
167 operator=(__box&& __that)
168 noexcept(is_nothrow_move_constructible_v<_Tp>)
169 requires (!movable<_Tp>)
171 if (this != std::__addressof(__that))
174 this->emplace(std::move(*__that));
182 template<typename _Tp>
183 concept __boxable_copyable
184 = copy_constructible<_Tp>
185 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
186 && is_nothrow_copy_constructible_v<_Tp>));
187 template<typename _Tp>
188 concept __boxable_movable
189 = (!copy_constructible<_Tp>)
190 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
192 // For types which are already copyable (or since C++23, movable)
193 // this specialization of the box wrapper stores the object directly
194 // without going through std::optional. It provides just the subset of
195 // the primary template's API that we currently use.
196 template<__boxable _Tp>
197 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
201 [[no_unique_address]] _Tp _M_value = _Tp();
204 __box() requires default_initializable<_Tp> = default;
207 __box(const _Tp& __t)
208 noexcept(is_nothrow_copy_constructible_v<_Tp>)
209 requires copy_constructible<_Tp>
215 noexcept(is_nothrow_move_constructible_v<_Tp>)
216 : _M_value(std::move(__t))
219 template<typename... _Args>
220 requires constructible_from<_Tp, _Args...>
222 __box(in_place_t, _Args&&... __args)
223 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
224 : _M_value(std::forward<_Args>(__args)...)
227 __box(const __box&) = default;
228 __box(__box&&) = default;
229 __box& operator=(const __box&) requires copyable<_Tp> = default;
230 __box& operator=(__box&&) requires movable<_Tp> = default;
232 // When _Tp is nothrow_copy_constructible but not copy_assignable,
233 // copy assignment is implemented via destroy-then-copy-construct.
235 operator=(const __box& __that) noexcept
236 requires (!copyable<_Tp>) && copy_constructible<_Tp>
238 static_assert(is_nothrow_copy_constructible_v<_Tp>);
239 if (this != std::__addressof(__that))
242 std::construct_at(std::__addressof(_M_value), *__that);
247 // Likewise for move assignment.
249 operator=(__box&& __that) noexcept
250 requires (!movable<_Tp>)
252 static_assert(is_nothrow_move_constructible_v<_Tp>);
253 if (this != std::__addressof(__that))
256 std::construct_at(std::__addressof(_M_value), std::move(*__that));
262 has_value() const noexcept
266 operator*() & noexcept
270 operator*() const & noexcept
274 operator*() && noexcept
275 { return std::move(_M_value); }
277 constexpr const _Tp&&
278 operator*() const && noexcept
279 { return std::move(_M_value); }
282 operator->() noexcept
283 { return std::__addressof(_M_value); }
286 operator->() const noexcept
287 { return std::__addressof(_M_value); }
289 } // namespace __detail
291 /// A view that contains exactly one element.
292#if __cpp_lib_ranges >= 202207L // C++ >= 23
293 template<move_constructible _Tp>
295 template<copy_constructible _Tp>
297 requires is_object_v<_Tp>
298 class single_view : public view_interface<single_view<_Tp>>
301 single_view() requires default_initializable<_Tp> = default;
304 single_view(const _Tp& __t)
305 noexcept(is_nothrow_copy_constructible_v<_Tp>)
306 requires copy_constructible<_Tp>
311 single_view(_Tp&& __t)
312 noexcept(is_nothrow_move_constructible_v<_Tp>)
313 : _M_value(std::move(__t))
316 // _GLIBCXX_RESOLVE_LIB_DEFECTS
317 // 3428. single_view's in place constructor should be explicit
318 template<typename... _Args>
319 requires constructible_from<_Tp, _Args...>
321 single_view(in_place_t, _Args&&... __args)
322 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
323 : _M_value{in_place, std::forward<_Args>(__args)...}
331 begin() const noexcept
336 { return data() + 1; }
340 { return data() + 1; }
342 // _GLIBCXX_RESOLVE_LIB_DEFECTS
343 // 4035. single_view should provide empty
344 static constexpr bool
348 static constexpr size_t
354 { return _M_value.operator->(); }
357 data() const noexcept
358 { return _M_value.operator->(); }
361 [[no_unique_address]] __detail::__box<_Tp> _M_value;
364 template<typename _Tp>
365 single_view(_Tp) -> single_view<_Tp>;
369 template<typename _Wp>
370 constexpr auto __to_signed_like(_Wp __w) noexcept
372 if constexpr (!integral<_Wp>)
373 return iter_difference_t<_Wp>();
374 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
375 return iter_difference_t<_Wp>(__w);
376 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
377 return ptrdiff_t(__w);
378 else if constexpr (sizeof(long long) > sizeof(_Wp))
379 return (long long)(__w);
380#ifdef __SIZEOF_INT128__
381 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
382 return __int128(__w);
385 return __max_diff_type(__w);
388 template<typename _Wp>
389 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
391 template<typename _It>
392 concept __decrementable = incrementable<_It>
395 { --__i } -> same_as<_It&>;
396 { __i-- } -> same_as<_It>;
399 template<typename _It>
400 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
401 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
403 { __i += __n } -> same_as<_It&>;
404 { __i -= __n } -> same_as<_It&>;
408 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
411 template<typename _Winc>
412 struct __iota_view_iter_cat
415 template<incrementable _Winc>
416 struct __iota_view_iter_cat<_Winc>
417 { using iterator_category = input_iterator_tag; };
418 } // namespace __detail
420 template<weakly_incrementable _Winc,
421 semiregular _Bound = unreachable_sentinel_t>
422 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
424 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
429 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
435 using namespace __detail;
436 if constexpr (__advanceable<_Winc>)
437 return random_access_iterator_tag{};
438 else if constexpr (__decrementable<_Winc>)
439 return bidirectional_iterator_tag{};
440 else if constexpr (incrementable<_Winc>)
441 return forward_iterator_tag{};
443 return input_iterator_tag{};
447 using iterator_concept = decltype(_S_iter_concept());
448 // iterator_category defined in __iota_view_iter_cat
449 using value_type = _Winc;
450 using difference_type = __detail::__iota_diff_t<_Winc>;
452 _Iterator() requires default_initializable<_Winc> = default;
455 _Iterator(_Winc __value)
456 : _M_value(__value) { }
459 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
474 operator++(int) requires incrementable<_Winc>
482 operator--() requires __detail::__decrementable<_Winc>
489 operator--(int) requires __detail::__decrementable<_Winc>
497 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
499 using __detail::__is_integer_like;
500 using __detail::__is_signed_integer_like;
501 if constexpr (__is_integer_like<_Winc>
502 && !__is_signed_integer_like<_Winc>)
504 if (__n >= difference_type(0))
505 _M_value += static_cast<_Winc>(__n);
507 _M_value -= static_cast<_Winc>(-__n);
515 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
517 using __detail::__is_integer_like;
518 using __detail::__is_signed_integer_like;
519 if constexpr (__is_integer_like<_Winc>
520 && !__is_signed_integer_like<_Winc>)
522 if (__n >= difference_type(0))
523 _M_value -= static_cast<_Winc>(__n);
525 _M_value += static_cast<_Winc>(-__n);
533 operator[](difference_type __n) const
534 requires __detail::__advanceable<_Winc>
535 { return _Winc(_M_value + __n); }
537 friend constexpr bool
538 operator==(const _Iterator& __x, const _Iterator& __y)
539 requires equality_comparable<_Winc>
540 { return __x._M_value == __y._M_value; }
542 friend constexpr bool
543 operator<(const _Iterator& __x, const _Iterator& __y)
544 requires totally_ordered<_Winc>
545 { return __x._M_value < __y._M_value; }
547 friend constexpr bool
548 operator>(const _Iterator& __x, const _Iterator& __y)
549 requires totally_ordered<_Winc>
550 { return __y < __x; }
552 friend constexpr bool
553 operator<=(const _Iterator& __x, const _Iterator& __y)
554 requires totally_ordered<_Winc>
555 { return !(__y < __x); }
557 friend constexpr bool
558 operator>=(const _Iterator& __x, const _Iterator& __y)
559 requires totally_ordered<_Winc>
560 { return !(__x < __y); }
562#ifdef __cpp_lib_three_way_comparison
563 friend constexpr auto
564 operator<=>(const _Iterator& __x, const _Iterator& __y)
565 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
566 { return __x._M_value <=> __y._M_value; }
569 friend constexpr _Iterator
570 operator+(_Iterator __i, difference_type __n)
571 requires __detail::__advanceable<_Winc>
577 friend constexpr _Iterator
578 operator+(difference_type __n, _Iterator __i)
579 requires __detail::__advanceable<_Winc>
580 { return __i += __n; }
582 friend constexpr _Iterator
583 operator-(_Iterator __i, difference_type __n)
584 requires __detail::__advanceable<_Winc>
590 friend constexpr difference_type
591 operator-(const _Iterator& __x, const _Iterator& __y)
592 requires __detail::__advanceable<_Winc>
594 using __detail::__is_integer_like;
595 using __detail::__is_signed_integer_like;
596 using _Dt = difference_type;
597 if constexpr (__is_integer_like<_Winc>)
599 if constexpr (__is_signed_integer_like<_Winc>)
600 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
602 return (__y._M_value > __x._M_value)
603 ? _Dt(-_Dt(__y._M_value - __x._M_value))
604 : _Dt(__x._M_value - __y._M_value);
607 return __x._M_value - __y._M_value;
611 _Winc _M_value = _Winc();
621 _M_equal(const _Iterator& __x) const
622 { return __x._M_value == _M_bound; }
625 _M_distance_from(const _Iterator& __x) const
626 { return _M_bound - __x._M_value; }
628 _Bound _M_bound = _Bound();
631 _Sentinel() = default;
634 _Sentinel(_Bound __bound)
635 : _M_bound(__bound) { }
637 friend constexpr bool
638 operator==(const _Iterator& __x, const _Sentinel& __y)
639 { return __y._M_equal(__x); }
641 friend constexpr iter_difference_t<_Winc>
642 operator-(const _Iterator& __x, const _Sentinel& __y)
643 requires sized_sentinel_for<_Bound, _Winc>
644 { return -__y._M_distance_from(__x); }
646 friend constexpr iter_difference_t<_Winc>
647 operator-(const _Sentinel& __x, const _Iterator& __y)
648 requires sized_sentinel_for<_Bound, _Winc>
649 { return __x._M_distance_from(__y); }
654 _Winc _M_value = _Winc();
655 [[no_unique_address]] _Bound _M_bound = _Bound();
658 iota_view() requires default_initializable<_Winc> = default;
661 iota_view(_Winc __value)
666 iota_view(type_identity_t<_Winc> __value,
667 type_identity_t<_Bound> __bound)
668 : _M_value(__value), _M_bound(__bound)
670 if constexpr (totally_ordered_with<_Winc, _Bound>)
671 __glibcxx_assert( bool(__value <= __bound) );
675 iota_view(_Iterator __first, _Iterator __last)
676 requires same_as<_Winc, _Bound>
677 : iota_view(__first._M_value, __last._M_value)
681 iota_view(_Iterator __first, unreachable_sentinel_t __last)
682 requires same_as<_Bound, unreachable_sentinel_t>
683 : iota_view(__first._M_value, __last)
687 iota_view(_Iterator __first, _Sentinel __last)
688 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
689 : iota_view(__first._M_value, __last._M_bound)
693 begin() const { return _Iterator{_M_value}; }
698 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
699 return unreachable_sentinel;
701 return _Sentinel{_M_bound};
705 end() const requires same_as<_Winc, _Bound>
706 { return _Iterator{_M_bound}; }
708 // _GLIBCXX_RESOLVE_LIB_DEFECTS
709 // 4001. iota_view should provide empty
712 { return _M_value == _M_bound; }
716 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
717 || (integral<_Winc> && integral<_Bound>)
718 || sized_sentinel_for<_Bound, _Winc>
720 using __detail::__is_integer_like;
721 using __detail::__to_unsigned_like;
722 if constexpr (integral<_Winc> && integral<_Bound>)
724 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
725 return _Up(_M_bound) - _Up(_M_value);
727 else if constexpr (__is_integer_like<_Winc>)
728 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
730 return __to_unsigned_like(_M_bound - _M_value);
734 template<typename _Winc, typename _Bound>
735 requires (!__detail::__is_integer_like<_Winc>
736 || !__detail::__is_integer_like<_Bound>
737 || (__detail::__is_signed_integer_like<_Winc>
738 == __detail::__is_signed_integer_like<_Bound>))
739 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
741 template<typename _Winc, typename _Bound>
742 inline constexpr bool
743 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
747 template<typename _Tp>
748 inline constexpr empty_view<_Tp> empty{};
752 template<typename _Tp>
753 concept __can_single_view
754 = requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
755 } // namespace __detail
759 template<__detail::__can_single_view _Tp>
761 operator() [[nodiscard]] (_Tp&& __e) const
762 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
763 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
766 inline constexpr _Single single{};
770 template<typename... _Args>
771 concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); };
772 } // namespace __detail
776 template<__detail::__can_iota_view _Tp>
778 operator() [[nodiscard]] (_Tp&& __e) const
779 { return iota_view(std::forward<_Tp>(__e)); }
781 template<typename _Tp, typename _Up>
782 requires __detail::__can_iota_view<_Tp, _Up>
784 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const
785 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
788 inline constexpr _Iota iota{};
790#ifdef __cpp_lib_ranges_indices // C++ >= 26
793 template<ranges::__detail::__is_integer_like _Tp>
794 requires __detail::__can_iota_view<_Tp>
795 [[nodiscard]] constexpr auto
796 operator() (_Tp __e) const noexcept
797 { return iota(_Tp{}, __e); }
800 inline constexpr _Indices indices{};
801#endif // __cpp_lib_ranges_indices
807 template<typename _Val, typename _CharT, typename _Traits>
808 concept __stream_extractable
809 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
810 } // namespace __detail
812 template<movable _Val, typename _CharT,
813 typename _Traits = char_traits<_CharT>>
814 requires default_initializable<_Val>
815 && __detail::__stream_extractable<_Val, _CharT, _Traits>
816 class basic_istream_view
817 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
821 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
822 : _M_stream(std::__addressof(__stream))
828 *_M_stream >> _M_object;
829 return _Iterator{this};
832 constexpr default_sentinel_t
834 { return default_sentinel; }
837 basic_istream<_CharT, _Traits>* _M_stream;
838 _Val _M_object = _Val();
843 using iterator_concept = input_iterator_tag;
844 using difference_type = ptrdiff_t;
845 using value_type = _Val;
848 _Iterator(basic_istream_view* __parent) noexcept
849 : _M_parent(__parent)
852 _Iterator(const _Iterator&) = delete;
853 _Iterator(_Iterator&&) = default;
854 _Iterator& operator=(const _Iterator&) = delete;
855 _Iterator& operator=(_Iterator&&) = default;
860 *_M_parent->_M_stream >> _M_parent->_M_object;
870 { return _M_parent->_M_object; }
873 operator==(const _Iterator& __x, default_sentinel_t)
874 { return __x._M_at_end(); }
877 basic_istream_view* _M_parent;
881 { return !*_M_parent->_M_stream; }
887 template<typename _Val>
888 using istream_view = basic_istream_view<_Val, char>;
890 template<typename _Val>
891 using wistream_view = basic_istream_view<_Val, wchar_t>;
897 template<typename _Tp, typename _Up>
898 concept __can_istream_view = requires (_Up __e) {
899 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
901 } // namespace __detail
903 template<typename _Tp>
906 template<typename _CharT, typename _Traits>
908 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
909 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
910 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
913 template<typename _Tp>
914 inline constexpr _Istream<_Tp> istream;
918 // C++20 24.7 [range.adaptors] Range adaptors
922 template<typename _Tp, int _Disc>
925 // Alias for a type that is conditionally present
926 // (and is an empty type otherwise).
927 // Data members using this alias should use [[no_unique_address]] so that
928 // they take no space when not needed.
929 // The optional template parameter _Disc is for discriminating two otherwise
930 // equivalent absent types so that even they can overlap.
931 template<bool _Present, typename _Tp, int _Disc = 0>
932 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
934 // Alias for a type that is conditionally const.
935 template<bool _Const, typename _Tp>
936 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
938} // namespace __detail
940// Shorthand for __detail::__maybe_const_t.
941using __detail::__maybe_const_t;
943namespace views::__adaptor
945 // True if the range adaptor _Adaptor can be applied with _Args.
946 template<typename _Adaptor, typename... _Args>
947 concept __adaptor_invocable
948 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
950 // True if the range adaptor non-closure _Adaptor can be partially applied
952 template<typename _Adaptor, typename... _Args>
953 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
954 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
955 && (constructible_from<decay_t<_Args>, _Args> && ...);
957 template<typename _Adaptor, typename... _Args>
960 template<typename _Lhs, typename _Rhs>
963 // The base class of every range adaptor closure.
965 // The derived class should define the optional static data member
966 // _S_has_simple_call_op to true if the behavior of this adaptor is
967 // independent of the constness/value category of the adaptor object.
968 template<typename _Derived>
969 struct _RangeAdaptorClosure;
971 template<typename _Tp, typename _Up>
972 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
973 void __is_range_adaptor_closure_fn
974 (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined
976 template<typename _Tp>
977 concept __is_range_adaptor_closure
978 = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
980#pragma GCC diagnostic push
981#pragma GCC diagnostic ignored "-Wdangling-reference"
982 // range | adaptor is equivalent to adaptor(range).
983 template<typename _Self, typename _Range>
984 requires __is_range_adaptor_closure<_Self>
985 && __adaptor_invocable<_Self, _Range>
987 operator|(_Range&& __r, _Self&& __self)
988 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
990 // Compose the adaptors __lhs and __rhs into a pipeline, returning
991 // another range adaptor closure object.
992 template<typename _Lhs, typename _Rhs>
993 requires __is_range_adaptor_closure<_Lhs>
994 && __is_range_adaptor_closure<_Rhs>
996 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
998 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
999 std::forward<_Rhs>(__rhs)};
1001#pragma GCC diagnostic pop
1003 template<typename _Derived>
1004 struct _RangeAdaptorClosure
1006 // In non-modules compilation ADL finds these operators either way and
1007 // the friend declarations are redundant. But with the std module these
1008 // friend declarations enable ADL to find these operators without having
1010 template<typename _Self, typename _Range>
1011 requires __is_range_adaptor_closure<_Self>
1012 && __adaptor_invocable<_Self, _Range>
1013 friend constexpr auto
1014 operator|(_Range&& __r, _Self&& __self);
1016 template<typename _Lhs, typename _Rhs>
1017 requires __is_range_adaptor_closure<_Lhs>
1018 && __is_range_adaptor_closure<_Rhs>
1019 friend constexpr auto
1020 operator|(_Lhs&& __lhs, _Rhs&& __rhs);
1023 // The base class of every range adaptor non-closure.
1025 // The static data member _Derived::_S_arity must contain the total number of
1026 // arguments that the adaptor takes, and the class _Derived must introduce
1027 // _RangeAdaptor::operator() into the class scope via a using-declaration.
1029 // The optional static data member _Derived::_S_has_simple_extra_args should
1030 // be defined to true if the behavior of this adaptor is independent of the
1031 // constness/value category of the extra arguments. This data member could
1032 // also be defined as a variable template parameterized by the types of the
1034 template<typename _Derived>
1035 struct _RangeAdaptor
1037 // Partially apply the arguments __args to the range adaptor _Derived,
1038 // returning a range adaptor closure object.
1039 template<typename... _Args>
1040 requires __adaptor_partial_app_viable<_Derived, _Args...>
1042 operator()(_Args&&... __args) const
1044 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
1048 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
1049 // one that's not overloaded according to constness or value category of the
1051 template<typename _Adaptor>
1052 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1054 // True if the behavior of the range adaptor non-closure _Adaptor is
1055 // independent of the value category of its extra arguments _Args.
1056 template<typename _Adaptor, typename... _Args>
1057 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1058 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1060 // A range adaptor closure that represents partial application of
1061 // the range adaptor _Adaptor with arguments _Args.
1062 template<typename _Adaptor, typename... _Args>
1063 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1065 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1066 [[no_unique_address]] _Binder _M_binder;
1068 // First parameter is to ensure this constructor is never used
1069 // instead of the copy/move constructor.
1070 template<typename... _Ts>
1072 _Partial(int, _Ts&&... __args)
1073 : _M_binder(0, _Adaptor(), std::forward<_Ts>(__args)...)
1076 // Invoke _Adaptor with arguments __r, _M_args... according to the
1077 // value category of this _Partial object.
1078#if __cpp_explicit_this_parameter
1079 template<typename _Self, typename _Range>
1080 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1082 operator()(this _Self&& __self, _Range&& __r)
1084 return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
1085 std::forward<_Range>(__r));
1088 template<typename _Range>
1089 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1091 operator()(_Range&& __r) const &
1092 { return _Binder::_S_call(_M_binder, std::forward<_Range>(__r)); }
1094 template<typename _Range>
1095 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1097 operator()(_Range&& __r) &&
1098 { return _Binder::_S_call(std::move(_M_binder), std::forward<_Range>(__r)); }
1100 template<typename _Range>
1102 operator()(_Range&& __r) const && = delete;
1106 // Partial specialization of the primary template for the case where the extra
1107 // arguments of the adaptor can always be safely and efficiently forwarded by
1108 // const reference. This lets us get away with a single operator() overload,
1109 // which makes overload resolution failure diagnostics more concise.
1110 template<typename _Adaptor, typename... _Args>
1111 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1112 && (is_trivially_copy_constructible_v<_Args> && ...)
1113 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1115 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1116 [[no_unique_address]] _Binder _M_binder;
1118 template<typename... _Ts>
1120 _Partial(int, _Ts&&... __args)
1121 : _M_binder(0, _Adaptor(), std::forward<_Ts>(__args)...)
1124 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1125 // of the value category of this _Partial object.
1126 template<typename _Range>
1127 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1129 operator()(_Range&& __r) const
1130 { return _Binder::_S_call(_M_binder, std::forward<_Range>(__r)); }
1132 static constexpr bool _S_has_simple_call_op = true;
1135 template<typename _Lhs, typename _Rhs, typename _Range>
1136 concept __pipe_invocable
1137 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1139 // A range adaptor closure that represents composition of the range
1140 // adaptor closures _Lhs and _Rhs.
1141 template<typename _Lhs, typename _Rhs>
1142 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1144 [[no_unique_address]] _Lhs _M_lhs;
1145 [[no_unique_address]] _Rhs _M_rhs;
1147 template<typename _Tp, typename _Up>
1149 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1150 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1153 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1154 // range adaptor closure object.
1155#if __cpp_explicit_this_parameter
1156 template<typename _Self, typename _Range>
1157 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1159 operator()(this _Self&& __self, _Range&& __r)
1161 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1162 (__like_t<_Self, _Pipe>(__self)._M_lhs
1163 (std::forward<_Range>(__r))));
1166 template<typename _Range>
1167 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1169 operator()(_Range&& __r) const &
1170 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1172 template<typename _Range>
1173 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1175 operator()(_Range&& __r) &&
1176 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1178 template<typename _Range>
1180 operator()(_Range&& __r) const && = delete;
1184 // A partial specialization of the above primary template for the case where
1185 // both adaptor operands have a simple operator(). This in turn lets us
1186 // implement composition using a single simple operator(), which makes
1187 // overload resolution failure diagnostics more concise.
1188 template<typename _Lhs, typename _Rhs>
1189 requires __closure_has_simple_call_op<_Lhs>
1190 && __closure_has_simple_call_op<_Rhs>
1191 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1193 [[no_unique_address]] _Lhs _M_lhs;
1194 [[no_unique_address]] _Rhs _M_rhs;
1196 template<typename _Tp, typename _Up>
1198 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1199 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1202 template<typename _Range>
1203 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1205 operator()(_Range&& __r) const
1206 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1208 static constexpr bool _S_has_simple_call_op = true;
1210} // namespace views::__adaptor
1212#if __cpp_lib_ranges >= 202202L
1213 // P2387R3 Pipe support for user-defined range adaptors
1214 template<typename _Derived>
1215 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1216 class range_adaptor_closure
1217 : public views::__adaptor::_RangeAdaptorClosure<_Derived>
1221 template<range _Range> requires is_object_v<_Range>
1222 class ref_view : public view_interface<ref_view<_Range>>
1227 static void _S_fun(_Range&); // not defined
1228 static void _S_fun(_Range&&) = delete;
1231 template<__detail::__different_from<ref_view> _Tp>
1232 requires convertible_to<_Tp, _Range&>
1233 && requires { _S_fun(declval<_Tp>()); }
1236 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1237 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1244 constexpr iterator_t<_Range>
1246 { return ranges::begin(*_M_r); }
1248 constexpr sentinel_t<_Range>
1250 { return ranges::end(*_M_r); }
1253 empty() const requires requires { ranges::empty(*_M_r); }
1254 { return ranges::empty(*_M_r); }
1257 size() const requires sized_range<_Range>
1258 { return ranges::size(*_M_r); }
1261 data() const requires contiguous_range<_Range>
1262 { return ranges::data(*_M_r); }
1265 template<typename _Range>
1266 ref_view(_Range&) -> ref_view<_Range>;
1268 template<typename _Tp>
1269 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1271 template<range _Range>
1272 requires movable<_Range>
1273 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1274 class owning_view : public view_interface<owning_view<_Range>>
1277 _Range _M_r = _Range();
1280 owning_view() requires default_initializable<_Range> = default;
1283 owning_view(_Range&& __t)
1284 noexcept(is_nothrow_move_constructible_v<_Range>)
1285 : _M_r(std::move(__t))
1288 owning_view(owning_view&&) = default;
1289 owning_view& operator=(owning_view&&) = default;
1295 constexpr const _Range&
1296 base() const& noexcept
1301 { return std::move(_M_r); }
1303 constexpr const _Range&&
1304 base() const&& noexcept
1305 { return std::move(_M_r); }
1307 constexpr iterator_t<_Range>
1309 { return ranges::begin(_M_r); }
1311 constexpr sentinel_t<_Range>
1313 { return ranges::end(_M_r); }
1316 begin() const requires range<const _Range>
1317 { return ranges::begin(_M_r); }
1320 end() const requires range<const _Range>
1321 { return ranges::end(_M_r); }
1324 empty() requires requires { ranges::empty(_M_r); }
1325 { return ranges::empty(_M_r); }
1328 empty() const requires requires { ranges::empty(_M_r); }
1329 { return ranges::empty(_M_r); }
1332 size() requires sized_range<_Range>
1333 { return ranges::size(_M_r); }
1336 size() const requires sized_range<const _Range>
1337 { return ranges::size(_M_r); }
1340 data() requires contiguous_range<_Range>
1341 { return ranges::data(_M_r); }
1344 data() const requires contiguous_range<const _Range>
1345 { return ranges::data(_M_r); }
1348 template<typename _Tp>
1349 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1350 = enable_borrowed_range<_Tp>;
1356 template<typename _Range>
1357 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1359 template<typename _Range>
1360 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1361 } // namespace __detail
1363 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1365 template<typename _Range>
1366 static constexpr bool
1369 if constexpr (view<decay_t<_Range>>)
1370 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1371 else if constexpr (__detail::__can_ref_view<_Range>)
1374 return noexcept(owning_view{std::declval<_Range>()});
1377 template<viewable_range _Range>
1378 requires view<decay_t<_Range>>
1379 || __detail::__can_ref_view<_Range>
1380 || __detail::__can_owning_view<_Range>
1382 operator() [[nodiscard]] (_Range&& __r) const
1383 noexcept(_S_noexcept<_Range>())
1385 if constexpr (view<decay_t<_Range>>)
1386 return std::forward<_Range>(__r);
1387 else if constexpr (__detail::__can_ref_view<_Range>)
1388 return ref_view{std::forward<_Range>(__r)};
1390 return owning_view{std::forward<_Range>(__r)};
1393 static constexpr bool _S_has_simple_call_op = true;
1396 inline constexpr _All all;
1398 template<viewable_range _Range>
1399 using all_t = decltype(all(std::declval<_Range>()));
1400 } // namespace views
1404 template<typename _Tp>
1405 struct __non_propagating_cache
1407 // When _Tp is not an object type (e.g. is a reference type), we make
1408 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1409 // users can easily conditionally declare data members with this type
1410 // (such as join_view::_M_inner).
1413 template<typename _Tp>
1414 requires is_object_v<_Tp>
1415 struct __non_propagating_cache<_Tp>
1416 : protected _Optional_base<_Tp>
1418 __non_propagating_cache() = default;
1421 __non_propagating_cache(const __non_propagating_cache&) noexcept
1425 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1426 { __other._M_reset(); }
1428 constexpr __non_propagating_cache&
1429 operator=(const __non_propagating_cache& __other) noexcept
1431 if (std::__addressof(__other) != this)
1436 constexpr __non_propagating_cache&
1437 operator=(__non_propagating_cache&& __other) noexcept
1444 constexpr __non_propagating_cache&
1445 operator=(_Tp __val)
1448 this->_M_payload._M_construct(std::move(__val));
1453 operator bool() const noexcept
1454 { return this->_M_is_engaged(); }
1457 operator*() noexcept
1458 { return this->_M_get(); }
1460 constexpr const _Tp&
1461 operator*() const noexcept
1462 { return this->_M_get(); }
1464 template<typename _Iter>
1466 _M_emplace_deref(const _Iter& __i)
1469 auto __f = [] (auto& __x) { return *__x; };
1470 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1471 return this->_M_get();
1474 using _Optional_base<_Tp>::_M_reset;
1477 template<range _Range>
1478 struct _CachedPosition
1481 _M_has_value() const
1484 constexpr iterator_t<_Range>
1485 _M_get(const _Range&) const
1487 __glibcxx_assert(false);
1488 __builtin_unreachable();
1492 _M_set(const _Range&, const iterator_t<_Range>&) const
1496 template<forward_range _Range>
1497 struct _CachedPosition<_Range>
1498 : protected __non_propagating_cache<iterator_t<_Range>>
1501 _M_has_value() const
1502 { return this->_M_is_engaged(); }
1504 constexpr iterator_t<_Range>
1505 _M_get(const _Range&) const
1507 __glibcxx_assert(_M_has_value());
1512 _M_set(const _Range&, const iterator_t<_Range>& __it)
1514 __glibcxx_assert(!_M_has_value());
1515 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1517 this->_M_payload._M_engaged = true;
1521 template<random_access_range _Range>
1522 struct _CachedPosition<_Range>
1525 range_difference_t<_Range> _M_offset = -1;
1528 _CachedPosition() = default;
1531 _CachedPosition(const _CachedPosition&) = default;
1534 _CachedPosition(_CachedPosition&& __other) noexcept
1535 { *this = std::move(__other); }
1537 constexpr _CachedPosition&
1538 operator=(const _CachedPosition&) = default;
1540 constexpr _CachedPosition&
1541 operator=(_CachedPosition&& __other) noexcept
1543 // Propagate the cached offset, but invalidate the source.
1544 _M_offset = __other._M_offset;
1545 __other._M_offset = -1;
1550 _M_has_value() const
1551 { return _M_offset >= 0; }
1553 constexpr iterator_t<_Range>
1554 _M_get(_Range& __r) const
1556 __glibcxx_assert(_M_has_value());
1557 return ranges::begin(__r) + _M_offset;
1561 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1563 __glibcxx_assert(!_M_has_value());
1564 _M_offset = __it - ranges::begin(__r);
1567 } // namespace __detail
1571 template<typename _Base>
1572 struct __filter_view_iter_cat
1575 template<forward_range _Base>
1576 struct __filter_view_iter_cat<_Base>
1582 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1583 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1584 return bidirectional_iterator_tag{};
1585 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1586 return forward_iterator_tag{};
1591 using iterator_category = decltype(_S_iter_cat());
1593 } // namespace __detail
1595 template<input_range _Vp,
1596 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1597 requires view<_Vp> && is_object_v<_Pred>
1598 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1603 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1606 static constexpr auto
1609 if constexpr (bidirectional_range<_Vp>)
1610 return bidirectional_iterator_tag{};
1611 else if constexpr (forward_range<_Vp>)
1612 return forward_iterator_tag{};
1614 return input_iterator_tag{};
1619 using _Vp_iter = iterator_t<_Vp>;
1621 _Vp_iter _M_current = _Vp_iter();
1622 filter_view* _M_parent = nullptr;
1625 using iterator_concept = decltype(_S_iter_concept());
1626 // iterator_category defined in __filter_view_iter_cat
1627 using value_type = range_value_t<_Vp>;
1628 using difference_type = range_difference_t<_Vp>;
1630 _Iterator() requires default_initializable<_Vp_iter> = default;
1633 _Iterator(filter_view* __parent, _Vp_iter __current)
1634 : _M_current(std::move(__current)),
1638 constexpr const _Vp_iter&
1639 base() const & noexcept
1640 { return _M_current; }
1644 { return std::move(_M_current); }
1646 constexpr range_reference_t<_Vp>
1648 { return *_M_current; }
1652 requires __detail::__has_arrow<_Vp_iter>
1653 && copyable<_Vp_iter>
1654 { return _M_current; }
1656 constexpr _Iterator&
1659 _M_current = ranges::find_if(std::move(++_M_current),
1660 ranges::end(_M_parent->_M_base),
1661 std::ref(*_M_parent->_M_pred));
1670 operator++(int) requires forward_range<_Vp>
1677 constexpr _Iterator&
1678 operator--() requires bidirectional_range<_Vp>
1682 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1687 operator--(int) requires bidirectional_range<_Vp>
1694 friend constexpr bool
1695 operator==(const _Iterator& __x, const _Iterator& __y)
1696 requires equality_comparable<_Vp_iter>
1697 { return __x._M_current == __y._M_current; }
1699 friend constexpr range_rvalue_reference_t<_Vp>
1700 iter_move(const _Iterator& __i)
1701 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1702 { return ranges::iter_move(__i._M_current); }
1704 friend constexpr void
1705 iter_swap(const _Iterator& __x, const _Iterator& __y)
1706 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1707 requires indirectly_swappable<_Vp_iter>
1708 { ranges::iter_swap(__x._M_current, __y._M_current); }
1714 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1717 __equal(const _Iterator& __i) const
1718 { return __i._M_current == _M_end; }
1721 _Sentinel() = default;
1724 _Sentinel(filter_view* __parent)
1725 : _M_end(ranges::end(__parent->_M_base))
1728 constexpr sentinel_t<_Vp>
1732 friend constexpr bool
1733 operator==(const _Iterator& __x, const _Sentinel& __y)
1734 { return __y.__equal(__x); }
1737 _Vp _M_base = _Vp();
1738 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1739 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1742 filter_view() requires (default_initializable<_Vp>
1743 && default_initializable<_Pred>)
1747 filter_view(_Vp __base, _Pred __pred)
1748 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1752 base() const& requires copy_constructible<_Vp>
1757 { return std::move(_M_base); }
1759 constexpr const _Pred&
1761 { return *_M_pred; }
1766 if (_M_cached_begin._M_has_value())
1767 return {this, _M_cached_begin._M_get(_M_base)};
1769 __glibcxx_assert(_M_pred.has_value());
1770 auto __it = ranges::find_if(ranges::begin(_M_base),
1771 ranges::end(_M_base),
1772 std::ref(*_M_pred));
1773 _M_cached_begin._M_set(_M_base, __it);
1774 return {this, std::move(__it)};
1780 if constexpr (common_range<_Vp>)
1781 return _Iterator{this, ranges::end(_M_base)};
1783 return _Sentinel{this};
1787 template<typename _Range, typename _Pred>
1788 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1794 template<typename _Range, typename _Pred>
1795 concept __can_filter_view
1796 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1797 } // namespace __detail
1799 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1801 template<viewable_range _Range, typename _Pred>
1802 requires __detail::__can_filter_view<_Range, _Pred>
1804 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1806 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1809 using _RangeAdaptor<_Filter>::operator();
1810 static constexpr int _S_arity = 2;
1811 static constexpr bool _S_has_simple_extra_args = true;
1814 inline constexpr _Filter filter;
1815 } // namespace views
1817#if __cpp_lib_ranges >= 202207L // C++ >= 23
1818 template<input_range _Vp, move_constructible _Fp>
1820 template<input_range _Vp, copy_constructible _Fp>
1822 requires view<_Vp> && is_object_v<_Fp>
1823 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1824 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1825 range_reference_t<_Vp>>>
1826 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1829 template<bool _Const>
1830 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1832 template<bool _Const>
1836 template<bool _Const>
1837 requires forward_range<_Base<_Const>>
1838 struct __iter_cat<_Const>
1844 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1845 // 3564. transform_view::iterator<true>::value_type and
1846 // iterator_category should use const F&
1847 using _Base = transform_view::_Base<_Const>;
1848 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1849 range_reference_t<_Base>>;
1850 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1851 // 3798. Rvalue reference and iterator_category
1852 if constexpr (is_reference_v<_Res>)
1855 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1856 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1857 return random_access_iterator_tag{};
1862 return input_iterator_tag{};
1865 using iterator_category = decltype(_S_iter_cat());
1868 template<bool _Const>
1871 template<bool _Const>
1872 struct _Iterator : __iter_cat<_Const>
1875 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1876 using _Base = transform_view::_Base<_Const>;
1881 if constexpr (random_access_range<_Base>)
1882 return random_access_iterator_tag{};
1883 else if constexpr (bidirectional_range<_Base>)
1884 return bidirectional_iterator_tag{};
1885 else if constexpr (forward_range<_Base>)
1886 return forward_iterator_tag{};
1888 return input_iterator_tag{};
1891 using _Base_iter = iterator_t<_Base>;
1893 _Base_iter _M_current = _Base_iter();
1894 _Parent* _M_parent = nullptr;
1897 using iterator_concept = decltype(_S_iter_concept());
1898 // iterator_category defined in __transform_view_iter_cat
1900 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1901 range_reference_t<_Base>>>;
1902 using difference_type = range_difference_t<_Base>;
1904 _Iterator() requires default_initializable<_Base_iter> = default;
1907 _Iterator(_Parent* __parent, _Base_iter __current)
1908 : _M_current(std::move(__current)),
1913 _Iterator(_Iterator<!_Const> __i)
1915 && convertible_to<iterator_t<_Vp>, _Base_iter>
1916 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1919 constexpr const _Base_iter&
1920 base() const & noexcept
1921 { return _M_current; }
1923 constexpr _Base_iter
1925 { return std::move(_M_current); }
1927 constexpr decltype(auto)
1929 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1930 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1932 constexpr _Iterator&
1944 operator++(int) requires forward_range<_Base>
1951 constexpr _Iterator&
1952 operator--() requires bidirectional_range<_Base>
1959 operator--(int) requires bidirectional_range<_Base>
1966 constexpr _Iterator&
1967 operator+=(difference_type __n) requires random_access_range<_Base>
1973 constexpr _Iterator&
1974 operator-=(difference_type __n) requires random_access_range<_Base>
1980 constexpr decltype(auto)
1981 operator[](difference_type __n) const
1982 requires random_access_range<_Base>
1983 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1985 friend constexpr bool
1986 operator==(const _Iterator& __x, const _Iterator& __y)
1987 requires equality_comparable<_Base_iter>
1988 { return __x._M_current == __y._M_current; }
1990 friend constexpr bool
1991 operator<(const _Iterator& __x, const _Iterator& __y)
1992 requires random_access_range<_Base>
1993 { return __x._M_current < __y._M_current; }
1995 friend constexpr bool
1996 operator>(const _Iterator& __x, const _Iterator& __y)
1997 requires random_access_range<_Base>
1998 { return __y < __x; }
2000 friend constexpr bool
2001 operator<=(const _Iterator& __x, const _Iterator& __y)
2002 requires random_access_range<_Base>
2003 { return !(__y < __x); }
2005 friend constexpr bool
2006 operator>=(const _Iterator& __x, const _Iterator& __y)
2007 requires random_access_range<_Base>
2008 { return !(__x < __y); }
2010#ifdef __cpp_lib_three_way_comparison
2011 friend constexpr auto
2012 operator<=>(const _Iterator& __x, const _Iterator& __y)
2013 requires random_access_range<_Base>
2014 && three_way_comparable<_Base_iter>
2015 { return __x._M_current <=> __y._M_current; }
2018 friend constexpr _Iterator
2019 operator+(_Iterator __i, difference_type __n)
2020 requires random_access_range<_Base>
2021 { return {__i._M_parent, __i._M_current + __n}; }
2023 friend constexpr _Iterator
2024 operator+(difference_type __n, _Iterator __i)
2025 requires random_access_range<_Base>
2026 { return {__i._M_parent, __i._M_current + __n}; }
2028 friend constexpr _Iterator
2029 operator-(_Iterator __i, difference_type __n)
2030 requires random_access_range<_Base>
2031 { return {__i._M_parent, __i._M_current - __n}; }
2033 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2034 // 3483. transform_view::iterator's difference is overconstrained
2035 friend constexpr difference_type
2036 operator-(const _Iterator& __x, const _Iterator& __y)
2037 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2038 { return __x._M_current - __y._M_current; }
2040 friend constexpr decltype(auto)
2041 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
2043 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
2044 return std::move(*__i);
2049 friend _Iterator<!_Const>;
2050 template<bool> friend struct _Sentinel;
2053 template<bool _Const>
2057 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2058 using _Base = transform_view::_Base<_Const>;
2060 template<bool _Const2>
2062 __distance_from(const _Iterator<_Const2>& __i) const
2063 { return _M_end - __i._M_current; }
2065 template<bool _Const2>
2067 __equal(const _Iterator<_Const2>& __i) const
2068 { return __i._M_current == _M_end; }
2070 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2073 _Sentinel() = default;
2076 _Sentinel(sentinel_t<_Base> __end)
2081 _Sentinel(_Sentinel<!_Const> __i)
2083 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2084 : _M_end(std::move(__i._M_end))
2087 constexpr sentinel_t<_Base>
2091 template<bool _Const2>
2092 requires sentinel_for<sentinel_t<_Base>,
2093 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2094 friend constexpr bool
2095 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2096 { return __y.__equal(__x); }
2098 template<bool _Const2,
2099 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2100 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2101 friend constexpr range_difference_t<_Base2>
2102 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2103 { return -__y.__distance_from(__x); }
2105 template<bool _Const2,
2106 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2107 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2108 friend constexpr range_difference_t<_Base2>
2109 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2110 { return __y.__distance_from(__x); }
2112 friend _Sentinel<!_Const>;
2115 _Vp _M_base = _Vp();
2116 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2119 transform_view() requires (default_initializable<_Vp>
2120 && default_initializable<_Fp>)
2124 transform_view(_Vp __base, _Fp __fun)
2125 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2129 base() const& requires copy_constructible<_Vp>
2130 { return _M_base ; }
2134 { return std::move(_M_base); }
2136 constexpr _Iterator<false>
2138 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2140 constexpr _Iterator<true>
2142 requires range<const _Vp>
2143 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2144 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2146 constexpr _Sentinel<false>
2148 { return _Sentinel<false>{ranges::end(_M_base)}; }
2150 constexpr _Iterator<false>
2151 end() requires common_range<_Vp>
2152 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2154 constexpr _Sentinel<true>
2156 requires range<const _Vp>
2157 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2158 { return _Sentinel<true>{ranges::end(_M_base)}; }
2160 constexpr _Iterator<true>
2162 requires common_range<const _Vp>
2163 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2164 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2167 size() requires sized_range<_Vp>
2168 { return ranges::size(_M_base); }
2171 size() const requires sized_range<const _Vp>
2172 { return ranges::size(_M_base); }
2175 template<typename _Range, typename _Fp>
2176 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2182 template<typename _Range, typename _Fp>
2183 concept __can_transform_view
2184 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2185 } // namespace __detail
2187 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2189 template<viewable_range _Range, typename _Fp>
2190 requires __detail::__can_transform_view<_Range, _Fp>
2192 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2194 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2197 using _RangeAdaptor<_Transform>::operator();
2198 static constexpr int _S_arity = 2;
2199 static constexpr bool _S_has_simple_extra_args = true;
2202 inline constexpr _Transform transform;
2203 } // namespace views
2206 class take_view : public view_interface<take_view<_Vp>>
2209 template<bool _Const>
2210 using _CI = counted_iterator<
2211 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2213 template<bool _Const>
2217 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2218 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2221 _Sentinel() = default;
2224 _Sentinel(sentinel_t<_Base> __end)
2229 _Sentinel(_Sentinel<!_Const> __s)
2230 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2231 : _M_end(std::move(__s._M_end))
2234 constexpr sentinel_t<_Base>
2238 friend constexpr bool
2239 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2240 { return __y.count() == 0 || __y.base() == __x._M_end; }
2242 template<bool _OtherConst = !_Const,
2243 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2244 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2245 friend constexpr bool
2246 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2247 { return __y.count() == 0 || __y.base() == __x._M_end; }
2249 friend _Sentinel<!_Const>;
2252 _Vp _M_base = _Vp();
2253 range_difference_t<_Vp> _M_count = 0;
2256 take_view() requires default_initializable<_Vp> = default;
2259 take_view(_Vp __base, range_difference_t<_Vp> __count)
2260 : _M_base(std::move(__base)), _M_count(std::move(__count))
2264 base() const& requires copy_constructible<_Vp>
2269 { return std::move(_M_base); }
2272 begin() requires (!__detail::__simple_view<_Vp>)
2274 if constexpr (sized_range<_Vp>)
2276 if constexpr (random_access_range<_Vp>)
2277 return ranges::begin(_M_base);
2281 return counted_iterator(ranges::begin(_M_base), __sz);
2285 return counted_iterator(ranges::begin(_M_base), _M_count);
2289 begin() const requires range<const _Vp>
2291 if constexpr (sized_range<const _Vp>)
2293 if constexpr (random_access_range<const _Vp>)
2294 return ranges::begin(_M_base);
2298 return counted_iterator(ranges::begin(_M_base), __sz);
2302 return counted_iterator(ranges::begin(_M_base), _M_count);
2306 end() requires (!__detail::__simple_view<_Vp>)
2308 if constexpr (sized_range<_Vp>)
2310 if constexpr (random_access_range<_Vp>)
2311 return ranges::begin(_M_base) + size();
2313 return default_sentinel;
2316 return _Sentinel<false>{ranges::end(_M_base)};
2320 end() const requires range<const _Vp>
2322 if constexpr (sized_range<const _Vp>)
2324 if constexpr (random_access_range<const _Vp>)
2325 return ranges::begin(_M_base) + size();
2327 return default_sentinel;
2330 return _Sentinel<true>{ranges::end(_M_base)};
2334 size() requires sized_range<_Vp>
2336 auto __n = ranges::size(_M_base);
2337 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2341 size() const requires sized_range<const _Vp>
2343 auto __n = ranges::size(_M_base);
2344 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2348 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2349 // 3447. Deduction guides for take_view and drop_view have different
2351 template<typename _Range>
2352 take_view(_Range&&, range_difference_t<_Range>)
2353 -> take_view<views::all_t<_Range>>;
2355 template<typename _Tp>
2356 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2357 = enable_borrowed_range<_Tp>;
2363 template<typename _Range>
2364 inline constexpr bool __is_empty_view = false;
2366 template<typename _Tp>
2367 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2369 template<typename _Range>
2370 inline constexpr bool __is_basic_string_view = false;
2372 template<typename _CharT, typename _Traits>
2373 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2376 using ranges::__detail::__is_subrange;
2378 template<typename _Range>
2379 inline constexpr bool __is_iota_view = false;
2381 template<typename _Winc, typename _Bound>
2382 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2384 template<typename _Range>
2385 inline constexpr bool __is_repeat_view = false;
2387 template<typename _Range>
2389 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2391 template<typename _Range, typename _Dp>
2392 concept __can_take_view
2393 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2394 } // namespace __detail
2396 struct _Take : __adaptor::_RangeAdaptor<_Take>
2398 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2399 requires __detail::__can_take_view<_Range, _Dp>
2401 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2403 using _Tp = remove_cvref_t<_Range>;
2404 if constexpr (__detail::__is_empty_view<_Tp>)
2406 else if constexpr (random_access_range<_Tp>
2408 && (std::__detail::__is_span<_Tp>
2409 || __detail::__is_basic_string_view<_Tp>
2410 || __detail::__is_subrange<_Tp>
2411 || __detail::__is_iota_view<_Tp>))
2413 __n = std::min<_Dp>(ranges::distance(__r), __n);
2414 auto __begin = ranges::begin(__r);
2415 auto __end = __begin + __n;
2416 if constexpr (std::__detail::__is_span<_Tp>)
2417 return span<typename _Tp::element_type>(__begin, __end);
2418 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2419 return _Tp(__begin, __end);
2420 else if constexpr (__detail::__is_subrange<_Tp>)
2421 return subrange<iterator_t<_Tp>>(__begin, __end);
2423 return iota_view(*__begin, *__end);
2425 else if constexpr (__detail::__is_repeat_view<_Tp>)
2426 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2428 return take_view(std::forward<_Range>(__r), __n);
2431 using _RangeAdaptor<_Take>::operator();
2432 static constexpr int _S_arity = 2;
2433 // The count argument of views::take is not always simple -- it can be
2434 // e.g. a move-only class that's implicitly convertible to the difference
2435 // type. But an integer-like count argument is surely simple.
2436 template<typename _Tp>
2437 static constexpr bool _S_has_simple_extra_args
2438 = ranges::__detail::__is_integer_like<_Tp>;
2441 inline constexpr _Take take;
2442 } // namespace views
2444 template<view _Vp, typename _Pred>
2445 requires input_range<_Vp> && is_object_v<_Pred>
2446 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2447 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2449 template<bool _Const>
2453 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2455 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2456 const _Pred* _M_pred = nullptr;
2459 _Sentinel() = default;
2462 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2463 : _M_end(__end), _M_pred(__pred)
2467 _Sentinel(_Sentinel<!_Const> __s)
2468 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2469 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2472 constexpr sentinel_t<_Base>
2473 base() const { return _M_end; }
2475 friend constexpr bool
2476 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2477 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2479 template<bool _OtherConst = !_Const,
2480 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2481 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2482 friend constexpr bool
2483 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2484 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2486 friend _Sentinel<!_Const>;
2489 _Vp _M_base = _Vp();
2490 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2493 take_while_view() requires (default_initializable<_Vp>
2494 && default_initializable<_Pred>)
2498 take_while_view(_Vp __base, _Pred __pred)
2499 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2503 base() const& requires copy_constructible<_Vp>
2508 { return std::move(_M_base); }
2510 constexpr const _Pred&
2512 { return *_M_pred; }
2515 begin() requires (!__detail::__simple_view<_Vp>)
2516 { return ranges::begin(_M_base); }
2519 begin() const requires range<const _Vp>
2520 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2521 { return ranges::begin(_M_base); }
2524 end() requires (!__detail::__simple_view<_Vp>)
2525 { return _Sentinel<false>(ranges::end(_M_base),
2526 std::__addressof(*_M_pred)); }
2529 end() const requires range<const _Vp>
2530 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2531 { return _Sentinel<true>(ranges::end(_M_base),
2532 std::__addressof(*_M_pred)); }
2535 template<typename _Range, typename _Pred>
2536 take_while_view(_Range&&, _Pred)
2537 -> take_while_view<views::all_t<_Range>, _Pred>;
2543 template<typename _Range, typename _Pred>
2544 concept __can_take_while_view
2545 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2546 } // namespace __detail
2548 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2550 template<viewable_range _Range, typename _Pred>
2551 requires __detail::__can_take_while_view<_Range, _Pred>
2553 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2555 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2558 using _RangeAdaptor<_TakeWhile>::operator();
2559 static constexpr int _S_arity = 2;
2560 static constexpr bool _S_has_simple_extra_args = true;
2563 inline constexpr _TakeWhile take_while;
2564 } // namespace views
2567 class drop_view : public view_interface<drop_view<_Vp>>
2570 _Vp _M_base = _Vp();
2571 range_difference_t<_Vp> _M_count = 0;
2573 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2574 // both random_access_range and sized_range. Otherwise, cache its result.
2575 static constexpr bool _S_needs_cached_begin
2576 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2577 [[no_unique_address]]
2578 __detail::__maybe_present_t<_S_needs_cached_begin,
2579 __detail::_CachedPosition<_Vp>>
2583 drop_view() requires default_initializable<_Vp> = default;
2586 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2587 : _M_base(std::move(__base)), _M_count(__count)
2588 { __glibcxx_assert(__count >= 0); }
2591 base() const& requires copy_constructible<_Vp>
2596 { return std::move(_M_base); }
2598 // This overload is disabled for simple views with constant-time begin().
2601 requires (!(__detail::__simple_view<_Vp>
2602 && random_access_range<const _Vp>
2603 && sized_range<const _Vp>))
2605 if constexpr (_S_needs_cached_begin)
2606 if (_M_cached_begin._M_has_value())
2607 return _M_cached_begin._M_get(_M_base);
2609 auto __it = ranges::next(ranges::begin(_M_base),
2610 _M_count, ranges::end(_M_base));
2611 if constexpr (_S_needs_cached_begin)
2612 _M_cached_begin._M_set(_M_base, __it);
2616 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2617 // 3482. drop_view's const begin should additionally require sized_range
2620 requires random_access_range<const _Vp> && sized_range<const _Vp>
2622 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2627 end() requires (!__detail::__simple_view<_Vp>)
2628 { return ranges::end(_M_base); }
2631 end() const requires range<const _Vp>
2632 { return ranges::end(_M_base); }
2635 size() requires sized_range<_Vp>
2637 const auto __s = ranges::size(_M_base);
2638 const auto __c = static_cast<decltype(__s)>(_M_count);
2639 return __s < __c ? 0 : __s - __c;
2643 size() const requires sized_range<const _Vp>
2645 const auto __s = ranges::size(_M_base);
2646 const auto __c = static_cast<decltype(__s)>(_M_count);
2647 return __s < __c ? 0 : __s - __c;
2651 template<typename _Range>
2652 drop_view(_Range&&, range_difference_t<_Range>)
2653 -> drop_view<views::all_t<_Range>>;
2655 template<typename _Tp>
2656 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2657 = enable_borrowed_range<_Tp>;
2663 template<typename _Range>
2665 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2667 template<typename _Range, typename _Dp>
2668 concept __can_drop_view
2669 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2670 } // namespace __detail
2672 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2674 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2675 requires __detail::__can_drop_view<_Range, _Dp>
2677 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2679 using _Tp = remove_cvref_t<_Range>;
2680 if constexpr (__detail::__is_empty_view<_Tp>)
2682 else if constexpr (random_access_range<_Tp>
2684 && (std::__detail::__is_span<_Tp>
2685 || __detail::__is_basic_string_view<_Tp>
2686 || __detail::__is_iota_view<_Tp>
2687 || __detail::__is_subrange<_Tp>))
2689 __n = std::min<_Dp>(ranges::distance(__r), __n);
2690 auto __begin = ranges::begin(__r) + __n;
2691 auto __end = ranges::end(__r);
2692 if constexpr (std::__detail::__is_span<_Tp>)
2693 return span<typename _Tp::element_type>(__begin, __end);
2694 else if constexpr (__detail::__is_subrange<_Tp>)
2696 if constexpr (_Tp::_S_store_size)
2698 using ranges::__detail::__to_unsigned_like;
2699 auto __m = ranges::distance(__r) - __n;
2700 return _Tp(__begin, __end, __to_unsigned_like(__m));
2703 return _Tp(__begin, __end);
2706 return _Tp(__begin, __end);
2708 else if constexpr (__detail::__is_repeat_view<_Tp>)
2709 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2711 return drop_view(std::forward<_Range>(__r), __n);
2714 using _RangeAdaptor<_Drop>::operator();
2715 static constexpr int _S_arity = 2;
2716 template<typename _Tp>
2717 static constexpr bool _S_has_simple_extra_args
2718 = _Take::_S_has_simple_extra_args<_Tp>;
2721 inline constexpr _Drop drop;
2722 } // namespace views
2724 template<view _Vp, typename _Pred>
2725 requires input_range<_Vp> && is_object_v<_Pred>
2726 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2727 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2730 _Vp _M_base = _Vp();
2731 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2732 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2735 drop_while_view() requires (default_initializable<_Vp>
2736 && default_initializable<_Pred>)
2740 drop_while_view(_Vp __base, _Pred __pred)
2741 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2745 base() const& requires copy_constructible<_Vp>
2750 { return std::move(_M_base); }
2752 constexpr const _Pred&
2754 { return *_M_pred; }
2759 if (_M_cached_begin._M_has_value())
2760 return _M_cached_begin._M_get(_M_base);
2762 __glibcxx_assert(_M_pred.has_value());
2763 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2764 ranges::end(_M_base),
2765 std::cref(*_M_pred));
2766 _M_cached_begin._M_set(_M_base, __it);
2772 { return ranges::end(_M_base); }
2775 template<typename _Range, typename _Pred>
2776 drop_while_view(_Range&&, _Pred)
2777 -> drop_while_view<views::all_t<_Range>, _Pred>;
2779 template<typename _Tp, typename _Pred>
2780 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2781 = enable_borrowed_range<_Tp>;
2787 template<typename _Range, typename _Pred>
2788 concept __can_drop_while_view
2789 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2790 } // namespace __detail
2792 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2794 template<viewable_range _Range, typename _Pred>
2795 requires __detail::__can_drop_while_view<_Range, _Pred>
2797 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2799 return drop_while_view(std::forward<_Range>(__r),
2800 std::forward<_Pred>(__p));
2803 using _RangeAdaptor<_DropWhile>::operator();
2804 static constexpr int _S_arity = 2;
2805 static constexpr bool _S_has_simple_extra_args = true;
2808 inline constexpr _DropWhile drop_while;
2809 } // namespace views
2813 template<typename _Tp>
2815 __as_lvalue(_Tp&& __t)
2816 { return static_cast<_Tp&>(__t); }
2817 } // namespace __detail
2819 template<input_range _Vp>
2820 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2821 class join_view : public view_interface<join_view<_Vp>>
2824 using _InnerRange = range_reference_t<_Vp>;
2826 template<bool _Const>
2827 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2829 template<bool _Const>
2830 using _Outer_iter = iterator_t<_Base<_Const>>;
2832 template<bool _Const>
2833 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2835 template<bool _Const>
2836 static constexpr bool _S_ref_is_glvalue
2837 = is_reference_v<range_reference_t<_Base<_Const>>>;
2839 template<bool _Const>
2843 template<bool _Const>
2844 requires _S_ref_is_glvalue<_Const>
2845 && forward_range<_Base<_Const>>
2846 && forward_range<range_reference_t<_Base<_Const>>>
2847 struct __iter_cat<_Const>
2850 static constexpr auto
2853 using _Outer_iter = join_view::_Outer_iter<_Const>;
2854 using _Inner_iter = join_view::_Inner_iter<_Const>;
2855 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2856 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2857 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2858 && derived_from<_InnerCat, bidirectional_iterator_tag>
2859 && common_range<range_reference_t<_Base<_Const>>>)
2860 return bidirectional_iterator_tag{};
2861 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2862 && derived_from<_InnerCat, forward_iterator_tag>)
2863 return forward_iterator_tag{};
2865 return input_iterator_tag{};
2868 using iterator_category = decltype(_S_iter_cat());
2871 template<bool _Const>
2874 template<bool _Const>
2875 struct _Iterator : __iter_cat<_Const>
2878 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2879 using _Base = join_view::_Base<_Const>;
2883 static constexpr bool _S_ref_is_glvalue
2884 = join_view::_S_ref_is_glvalue<_Const>;
2889 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2890 if constexpr (_S_ref_is_glvalue)
2893 return _M_parent->_M_inner._M_emplace_deref(__x);
2896 _Outer_iter& __outer = _M_get_outer();
2897 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2899 auto&& __inner = __update_inner(__outer);
2900 _M_inner = ranges::begin(__inner);
2901 if (_M_inner != ranges::end(__inner))
2905 if constexpr (_S_ref_is_glvalue)
2907 if constexpr (forward_iterator<_Inner_iter>)
2908 _M_inner = _Inner_iter();
2914 static constexpr auto
2917 if constexpr (_S_ref_is_glvalue
2918 && bidirectional_range<_Base>
2919 && bidirectional_range<range_reference_t<_Base>>
2920 && common_range<range_reference_t<_Base>>)
2921 return bidirectional_iterator_tag{};
2922 else if constexpr (_S_ref_is_glvalue
2923 && forward_range<_Base>
2924 && forward_range<range_reference_t<_Base>>)
2925 return forward_iterator_tag{};
2927 return input_iterator_tag{};
2930 using _Outer_iter = join_view::_Outer_iter<_Const>;
2931 using _Inner_iter = join_view::_Inner_iter<_Const>;
2933 constexpr _Outer_iter&
2936 if constexpr (forward_range<_Base>)
2939 return *_M_parent->_M_outer;
2942 constexpr const _Outer_iter&
2943 _M_get_outer() const
2945 if constexpr (forward_range<_Base>)
2948 return *_M_parent->_M_outer;
2951 constexpr _Inner_iter&
2952 _M_get_inner() noexcept
2954 if constexpr (forward_iterator<_Inner_iter>)
2960 constexpr const _Inner_iter&
2961 _M_get_inner() const noexcept
2963 if constexpr (forward_iterator<_Inner_iter>)
2970 _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base>
2971 : _M_outer(std::move(__outer)), _M_parent(__parent)
2975 _Iterator(_Parent* __parent) requires (!forward_range<_Base>)
2976 : _M_parent(__parent)
2979 [[no_unique_address]]
2980 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer
2981 = decltype(_M_outer)();
2982 __conditional_t<forward_iterator<_Inner_iter>,
2983 _Inner_iter, optional<_Inner_iter>> _M_inner
2984 = decltype(_M_inner)();
2985 _Parent* _M_parent = nullptr;
2988 using iterator_concept = decltype(_S_iter_concept());
2989 // iterator_category defined in __join_view_iter_cat
2990 using value_type = range_value_t<range_reference_t<_Base>>;
2991 using difference_type
2992 = common_type_t<range_difference_t<_Base>,
2993 range_difference_t<range_reference_t<_Base>>>;
2995 _Iterator() = default;
2998 _Iterator(_Iterator<!_Const> __i)
3000 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3001 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3002 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
3003 _M_parent(__i._M_parent)
3006 constexpr decltype(auto)
3008 { return *_M_get_inner(); }
3010 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3011 // 3500. join_view::iterator::operator->() is bogus
3012 constexpr _Inner_iter
3014 requires __detail::__has_arrow<_Inner_iter>
3015 && copyable<_Inner_iter>
3016 { return _M_get_inner(); }
3018 constexpr _Iterator&
3021 auto&& __inner_range = [this] () -> auto&& {
3022 if constexpr (_S_ref_is_glvalue)
3023 return *_M_get_outer();
3025 return *_M_parent->_M_inner;
3027 if (++_M_get_inner() == ranges::end(__inner_range))
3041 requires _S_ref_is_glvalue && forward_range<_Base>
3042 && forward_range<range_reference_t<_Base>>
3049 constexpr _Iterator&
3051 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3052 && bidirectional_range<range_reference_t<_Base>>
3053 && common_range<range_reference_t<_Base>>
3055 if (_M_outer == ranges::end(_M_parent->_M_base))
3056 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3057 while (_M_get_inner() == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3058 _M_get_inner() = ranges::end(__detail::__as_lvalue(*--_M_outer));
3065 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3066 && bidirectional_range<range_reference_t<_Base>>
3067 && common_range<range_reference_t<_Base>>
3074 friend constexpr bool
3075 operator==(const _Iterator& __x, const _Iterator& __y)
3076 requires _S_ref_is_glvalue
3077 && forward_range<_Base>
3078 && equality_comparable<_Inner_iter>
3080 return (__x._M_outer == __y._M_outer
3081 && __x._M_inner == __y._M_inner);
3084 friend constexpr decltype(auto)
3085 iter_move(const _Iterator& __i)
3086 noexcept(noexcept(ranges::iter_move(__i._M_get_inner())))
3087 { return ranges::iter_move(__i._M_get_inner()); }
3089 friend constexpr void
3090 iter_swap(const _Iterator& __x, const _Iterator& __y)
3091 noexcept(noexcept(ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner())))
3092 requires indirectly_swappable<_Inner_iter>
3093 { return ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner()); }
3095 friend _Iterator<!_Const>;
3096 template<bool> friend struct _Sentinel;
3099 template<bool _Const>
3103 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3104 using _Base = join_view::_Base<_Const>;
3106 template<bool _Const2>
3108 __equal(const _Iterator<_Const2>& __i) const
3109 { return __i._M_get_outer() == _M_end; }
3111 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3114 _Sentinel() = default;
3117 _Sentinel(_Parent* __parent)
3118 : _M_end(ranges::end(__parent->_M_base))
3122 _Sentinel(_Sentinel<!_Const> __s)
3123 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3124 : _M_end(std::move(__s._M_end))
3127 template<bool _Const2>
3128 requires sentinel_for<sentinel_t<_Base>,
3129 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3130 friend constexpr bool
3131 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3132 { return __y.__equal(__x); }
3134 friend _Sentinel<!_Const>;
3137 _Vp _M_base = _Vp();
3138 [[no_unique_address]]
3139 __detail::__maybe_present_t<!forward_range<_Vp>,
3140 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3141 [[no_unique_address]]
3142 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3145 join_view() requires default_initializable<_Vp> = default;
3148 join_view(_Vp __base)
3149 : _M_base(std::move(__base))
3153 base() const& requires copy_constructible<_Vp>
3158 { return std::move(_M_base); }
3163 if constexpr (forward_range<_Vp>)
3165 constexpr bool __use_const
3166 = (__detail::__simple_view<_Vp>
3167 && is_reference_v<range_reference_t<_Vp>>);
3168 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3172 _M_outer = ranges::begin(_M_base);
3173 return _Iterator<false>{this};
3179 requires forward_range<const _Vp>
3180 && is_reference_v<range_reference_t<const _Vp>>
3181 && input_range<range_reference_t<const _Vp>>
3183 return _Iterator<true>{this, ranges::begin(_M_base)};
3189 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3190 && forward_range<_InnerRange>
3191 && common_range<_Vp> && common_range<_InnerRange>)
3192 return _Iterator<__detail::__simple_view<_Vp>>{this,
3193 ranges::end(_M_base)};
3195 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3200 requires forward_range<const _Vp>
3201 && is_reference_v<range_reference_t<const _Vp>>
3202 && input_range<range_reference_t<const _Vp>>
3204 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3205 && forward_range<range_reference_t<const _Vp>>
3206 && common_range<const _Vp>
3207 && common_range<range_reference_t<const _Vp>>)
3208 return _Iterator<true>{this, ranges::end(_M_base)};
3210 return _Sentinel<true>{this};
3214 template<typename _Range>
3215 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3221 template<typename _Range>
3222 concept __can_join_view
3223 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3224 } // namespace __detail
3226 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3228 template<viewable_range _Range>
3229 requires __detail::__can_join_view<_Range>
3231 operator() [[nodiscard]] (_Range&& __r) const
3233 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3234 // 3474. Nesting join_views is broken because of CTAD
3235 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3238 static constexpr bool _S_has_simple_call_op = true;
3241 inline constexpr _Join join;
3242 } // namespace views
3247 struct __require_constant;
3249 template<typename _Range>
3250 concept __tiny_range = sized_range<_Range>
3252 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3253 && (remove_reference_t<_Range>::size() <= 1);
3255 template<typename _Base>
3256 struct __lazy_split_view_outer_iter_cat
3259 template<forward_range _Base>
3260 struct __lazy_split_view_outer_iter_cat<_Base>
3261 { using iterator_category = input_iterator_tag; };
3263 template<typename _Base>
3264 struct __lazy_split_view_inner_iter_cat
3267 template<forward_range _Base>
3268 struct __lazy_split_view_inner_iter_cat<_Base>
3271 static constexpr auto
3274 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3275 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3276 return forward_iterator_tag{};
3281 using iterator_category = decltype(_S_iter_cat());
3285 template<input_range _Vp, forward_range _Pattern>
3286 requires view<_Vp> && view<_Pattern>
3287 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3289 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3290 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3293 template<bool _Const>
3294 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3296 template<bool _Const>
3299 template<bool _Const>
3301 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3304 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3305 using _Base = lazy_split_view::_Base<_Const>;
3309 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3311 // [range.lazy.split.outer] p1
3312 // Many of the following specifications refer to the notional member
3313 // current of outer-iterator. current is equivalent to current_ if
3314 // V models forward_range, and parent_->current_ otherwise.
3316 __current() noexcept
3318 if constexpr (forward_range<_Vp>)
3321 return *_M_parent->_M_current;
3325 __current() const noexcept
3327 if constexpr (forward_range<_Vp>)
3330 return *_M_parent->_M_current;
3333 _Parent* _M_parent = nullptr;
3335 [[no_unique_address]]
3336 __detail::__maybe_present_t<forward_range<_Vp>,
3337 iterator_t<_Base>> _M_current
3338 = decltype(_M_current)();
3339 bool _M_trailing_empty = false;
3342 using iterator_concept = __conditional_t<forward_range<_Base>,
3343 forward_iterator_tag,
3344 input_iterator_tag>;
3345 // iterator_category defined in __lazy_split_view_outer_iter_cat
3346 using difference_type = range_difference_t<_Base>;
3348 struct value_type : view_interface<value_type>
3351 _OuterIter _M_i = _OuterIter();
3353 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3354 // 4013. lazy_split_view::outer-iterator::value_type should not
3355 // provide default constructor
3357 value_type(_OuterIter __i)
3358 : _M_i(std::move(__i))
3364 constexpr _InnerIter<_Const>
3366 { return _InnerIter<_Const>{_M_i}; }
3368 constexpr default_sentinel_t
3369 end() const noexcept
3370 { return default_sentinel; }
3373 _OuterIter() = default;
3376 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3377 : _M_parent(__parent)
3381 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3382 requires forward_range<_Base>
3383 : _M_parent(__parent),
3384 _M_current(std::move(__current))
3388 _OuterIter(_OuterIter<!_Const> __i)
3390 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3391 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3392 _M_trailing_empty(__i._M_trailing_empty)
3395 constexpr value_type
3397 { return value_type{*this}; }
3399 constexpr _OuterIter&
3402 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3403 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3404 const auto __end = ranges::end(_M_parent->_M_base);
3405 if (__current() == __end)
3407 _M_trailing_empty = false;
3410 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3411 if (__pbegin == __pend)
3413 else if constexpr (__detail::__tiny_range<_Pattern>)
3415 __current() = ranges::find(std::move(__current()), __end,
3417 if (__current() != __end)
3420 if (__current() == __end)
3421 _M_trailing_empty = true;
3428 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3432 if (__current() == __end)
3433 _M_trailing_empty = true;
3436 } while (++__current() != __end);
3440 constexpr decltype(auto)
3443 if constexpr (forward_range<_Base>)
3453 friend constexpr bool
3454 operator==(const _OuterIter& __x, const _OuterIter& __y)
3455 requires forward_range<_Base>
3457 return __x._M_current == __y._M_current
3458 && __x._M_trailing_empty == __y._M_trailing_empty;
3461 friend constexpr bool
3462 operator==(const _OuterIter& __x, default_sentinel_t)
3463 { return __x.__at_end(); };
3465 friend _OuterIter<!_Const>;
3466 friend _InnerIter<_Const>;
3469 template<bool _Const>
3471 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3474 using _Base = lazy_split_view::_Base<_Const>;
3479 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3480 auto __end = ranges::end(_M_i._M_parent->_M_base);
3481 if constexpr (__detail::__tiny_range<_Pattern>)
3483 const auto& __cur = _M_i_current();
3486 if (__pcur == __pend)
3487 return _M_incremented;
3488 return *__cur == *__pcur;
3492 auto __cur = _M_i_current();
3495 if (__pcur == __pend)
3496 return _M_incremented;
3499 if (*__cur != *__pcur)
3501 if (++__pcur == __pend)
3503 } while (++__cur != __end);
3509 _M_i_current() noexcept
3510 { return _M_i.__current(); }
3513 _M_i_current() const noexcept
3514 { return _M_i.__current(); }
3516 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3517 bool _M_incremented = false;
3520 using iterator_concept
3521 = typename _OuterIter<_Const>::iterator_concept;
3522 // iterator_category defined in __lazy_split_view_inner_iter_cat
3523 using value_type = range_value_t<_Base>;
3524 using difference_type = range_difference_t<_Base>;
3526 _InnerIter() = default;
3529 _InnerIter(_OuterIter<_Const> __i)
3530 : _M_i(std::move(__i))
3533 constexpr const iterator_t<_Base>&
3534 base() const& noexcept
3535 { return _M_i_current(); }
3537 constexpr iterator_t<_Base>
3538 base() && requires forward_range<_Vp>
3539 { return std::move(_M_i_current()); }
3541 constexpr decltype(auto)
3543 { return *_M_i_current(); }
3545 constexpr _InnerIter&
3548 _M_incremented = true;
3549 if constexpr (!forward_range<_Base>)
3550 if constexpr (_Pattern::size() == 0)
3556 constexpr decltype(auto)
3559 if constexpr (forward_range<_Base>)
3569 friend constexpr bool
3570 operator==(const _InnerIter& __x, const _InnerIter& __y)
3571 requires forward_range<_Base>
3572 { return __x._M_i == __y._M_i; }
3574 friend constexpr bool
3575 operator==(const _InnerIter& __x, default_sentinel_t)
3576 { return __x.__at_end(); }
3578 friend constexpr decltype(auto)
3579 iter_move(const _InnerIter& __i)
3580 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3581 { return ranges::iter_move(__i._M_i_current()); }
3583 friend constexpr void
3584 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3585 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3586 __y._M_i_current())))
3587 requires indirectly_swappable<iterator_t<_Base>>
3588 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3591 _Vp _M_base = _Vp();
3592 _Pattern _M_pattern = _Pattern();
3593 [[no_unique_address]]
3594 __detail::__maybe_present_t<!forward_range<_Vp>,
3595 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3599 lazy_split_view() requires (default_initializable<_Vp>
3600 && default_initializable<_Pattern>)
3604 lazy_split_view(_Vp __base, _Pattern __pattern)
3605 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3608 template<input_range _Range>
3609 requires constructible_from<_Vp, views::all_t<_Range>>
3610 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3612 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3613 : _M_base(views::all(std::forward<_Range>(__r))),
3614 _M_pattern(views::single(std::move(__e)))
3618 base() const& requires copy_constructible<_Vp>
3623 { return std::move(_M_base); }
3628 if constexpr (forward_range<_Vp>)
3630 constexpr bool __simple
3631 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3632 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3636 _M_current = ranges::begin(_M_base);
3637 return _OuterIter<false>{this};
3642 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3644 return _OuterIter<true>{this, ranges::begin(_M_base)};
3648 end() requires forward_range<_Vp> && common_range<_Vp>
3650 constexpr bool __simple
3651 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3652 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3658 if constexpr (forward_range<_Vp>
3659 && forward_range<const _Vp>
3660 && common_range<const _Vp>)
3661 return _OuterIter<true>{this, ranges::end(_M_base)};
3663 return default_sentinel;
3667 template<typename _Range, typename _Pattern>
3668 lazy_split_view(_Range&&, _Pattern&&)
3669 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3671 template<input_range _Range>
3672 lazy_split_view(_Range&&, range_value_t<_Range>)
3673 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3679 template<typename _Range, typename _Pattern>
3680 concept __can_lazy_split_view
3681 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3682 } // namespace __detail
3684 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3686 template<viewable_range _Range, typename _Pattern>
3687 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3689 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3691 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3694 using _RangeAdaptor<_LazySplit>::operator();
3695 static constexpr int _S_arity = 2;
3696 // The pattern argument of views::lazy_split is not always simple -- it can be
3697 // a non-view range, the value category of which affects whether the call
3698 // is well-formed. But a scalar or a view pattern argument is surely
3700 template<typename _Pattern>
3701 static constexpr bool _S_has_simple_extra_args
3702 = is_scalar_v<_Pattern> || (view<_Pattern>
3703 && copy_constructible<_Pattern>);
3706 inline constexpr _LazySplit lazy_split;
3707 } // namespace views
3709 template<forward_range _Vp, forward_range _Pattern>
3710 requires view<_Vp> && view<_Pattern>
3711 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3713 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3716 _Vp _M_base = _Vp();
3717 _Pattern _M_pattern = _Pattern();
3718 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3724 split_view() requires (default_initializable<_Vp>
3725 && default_initializable<_Pattern>)
3729 split_view(_Vp __base, _Pattern __pattern)
3730 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3733 template<forward_range _Range>
3734 requires constructible_from<_Vp, views::all_t<_Range>>
3735 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3737 split_view(_Range&& __r, range_value_t<_Range> __e)
3738 : _M_base(views::all(std::forward<_Range>(__r))),
3739 _M_pattern(views::single(std::move(__e)))
3743 base() const& requires copy_constructible<_Vp>
3748 { return std::move(_M_base); }
3753 if (!_M_cached_begin)
3754 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3755 return {this, ranges::begin(_M_base), *_M_cached_begin};
3761 if constexpr (common_range<_Vp>)
3762 return _Iterator{this, ranges::end(_M_base), {}};
3764 return _Sentinel{this};
3767 constexpr subrange<iterator_t<_Vp>>
3768 _M_find_next(iterator_t<_Vp> __it)
3770 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3771 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3783 split_view* _M_parent = nullptr;
3784 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3785 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3786 bool _M_trailing_empty = false;
3788 friend struct _Sentinel;
3791 using iterator_concept = forward_iterator_tag;
3792 using iterator_category = input_iterator_tag;
3793 using value_type = subrange<iterator_t<_Vp>>;
3794 using difference_type = range_difference_t<_Vp>;
3796 _Iterator() = default;
3799 _Iterator(split_view* __parent,
3800 iterator_t<_Vp> __current,
3801 subrange<iterator_t<_Vp>> __next)
3802 : _M_parent(__parent),
3803 _M_cur(std::move(__current)),
3804 _M_next(std::move(__next))
3807 constexpr iterator_t<_Vp>
3811 constexpr value_type
3813 { return {_M_cur, _M_next.begin()}; }
3815 constexpr _Iterator&
3818 _M_cur = _M_next.begin();
3819 if (_M_cur != ranges::end(_M_parent->_M_base))
3821 _M_cur = _M_next.end();
3822 if (_M_cur == ranges::end(_M_parent->_M_base))
3824 _M_trailing_empty = true;
3825 _M_next = {_M_cur, _M_cur};
3828 _M_next = _M_parent->_M_find_next(_M_cur);
3831 _M_trailing_empty = false;
3843 friend constexpr bool
3844 operator==(const _Iterator& __x, const _Iterator& __y)
3846 return __x._M_cur == __y._M_cur
3847 && __x._M_trailing_empty == __y._M_trailing_empty;
3854 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3857 _M_equal(const _Iterator& __x) const
3858 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3861 _Sentinel() = default;
3864 _Sentinel(split_view* __parent)
3865 : _M_end(ranges::end(__parent->_M_base))
3868 friend constexpr bool
3869 operator==(const _Iterator& __x, const _Sentinel& __y)
3870 { return __y._M_equal(__x); }
3874 template<typename _Range, typename _Pattern>
3875 split_view(_Range&&, _Pattern&&)
3876 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3878 template<forward_range _Range>
3879 split_view(_Range&&, range_value_t<_Range>)
3880 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3886 template<typename _Range, typename _Pattern>
3887 concept __can_split_view
3888 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3889 } // namespace __detail
3891 struct _Split : __adaptor::_RangeAdaptor<_Split>
3893 template<viewable_range _Range, typename _Pattern>
3894 requires __detail::__can_split_view<_Range, _Pattern>
3896 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3898 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3901 using _RangeAdaptor<_Split>::operator();
3902 static constexpr int _S_arity = 2;
3903 template<typename _Pattern>
3904 static constexpr bool _S_has_simple_extra_args
3905 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3908 inline constexpr _Split split;
3909 } // namespace views
3915 template<input_or_output_iterator _Iter>
3917 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3919 if constexpr (contiguous_iterator<_Iter>)
3920 return span(std::to_address(__i), __n);
3921 else if constexpr (random_access_iterator<_Iter>)
3922 return subrange(__i, __i + __n);
3924 return subrange(counted_iterator(std::move(__i), __n),
3929 inline constexpr _Counted counted{};
3930 } // namespace views
3933 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3934 class common_view : public view_interface<common_view<_Vp>>
3937 _Vp _M_base = _Vp();
3940 common_view() requires default_initializable<_Vp> = default;
3943 common_view(_Vp __r)
3944 : _M_base(std::move(__r))
3948 base() const& requires copy_constructible<_Vp>
3953 { return std::move(_M_base); }
3955 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3956 // 4012. common_view::begin/end are missing the simple-view check
3958 begin() requires (!__detail::__simple_view<_Vp>)
3960 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3961 return ranges::begin(_M_base);
3963 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3964 (ranges::begin(_M_base));
3968 begin() const requires range<const _Vp>
3970 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3971 return ranges::begin(_M_base);
3973 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3974 (ranges::begin(_M_base));
3978 end() requires (!__detail::__simple_view<_Vp>)
3980 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3981 return ranges::begin(_M_base) + ranges::size(_M_base);
3983 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3984 (ranges::end(_M_base));
3988 end() const requires range<const _Vp>
3990 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3991 return ranges::begin(_M_base) + ranges::size(_M_base);
3993 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3994 (ranges::end(_M_base));
3998 size() requires sized_range<_Vp>
3999 { return ranges::size(_M_base); }
4002 size() const requires sized_range<const _Vp>
4003 { return ranges::size(_M_base); }
4006 template<typename _Range>
4007 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4009 template<typename _Tp>
4010 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4011 = enable_borrowed_range<_Tp>;
4017 template<typename _Range>
4018 concept __already_common = common_range<_Range>
4019 && requires { views::all(std::declval<_Range>()); };
4021 template<typename _Range>
4022 concept __can_common_view
4023 = requires { common_view{std::declval<_Range>()}; };
4024 } // namespace __detail
4026 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4028 template<viewable_range _Range>
4029 requires __detail::__already_common<_Range>
4030 || __detail::__can_common_view<_Range>
4032 operator() [[nodiscard]] (_Range&& __r) const
4034 if constexpr (__detail::__already_common<_Range>)
4035 return views::all(std::forward<_Range>(__r));
4037 return common_view{std::forward<_Range>(__r)};
4040 static constexpr bool _S_has_simple_call_op = true;
4043 inline constexpr _Common common;
4044 } // namespace views
4047 requires bidirectional_range<_Vp>
4048 class reverse_view : public view_interface<reverse_view<_Vp>>
4051 static constexpr bool _S_needs_cached_begin
4052 = !common_range<_Vp> && !(random_access_range<_Vp>
4053 && sized_sentinel_for<sentinel_t<_Vp>,
4056 _Vp _M_base = _Vp();
4057 [[no_unique_address]]
4058 __detail::__maybe_present_t<_S_needs_cached_begin,
4059 __detail::_CachedPosition<_Vp>>
4063 reverse_view() requires default_initializable<_Vp> = default;
4066 reverse_view(_Vp __r)
4067 : _M_base(std::move(__r))
4071 base() const& requires copy_constructible<_Vp>
4076 { return std::move(_M_base); }
4078 constexpr reverse_iterator<iterator_t<_Vp>>
4081 if constexpr (_S_needs_cached_begin)
4082 if (_M_cached_begin._M_has_value())
4083 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
4085 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4086 if constexpr (_S_needs_cached_begin)
4087 _M_cached_begin._M_set(_M_base, __it);
4088 return std::make_reverse_iterator(std::move(__it));
4092 begin() requires common_range<_Vp>
4093 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4096 begin() const requires common_range<const _Vp>
4097 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4099 constexpr reverse_iterator<iterator_t<_Vp>>
4101 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4104 end() const requires common_range<const _Vp>
4105 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4108 size() requires sized_range<_Vp>
4109 { return ranges::size(_M_base); }
4112 size() const requires sized_range<const _Vp>
4113 { return ranges::size(_M_base); }
4116 template<typename _Range>
4117 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4119 template<typename _Tp>
4120 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4121 = enable_borrowed_range<_Tp>;
4128 inline constexpr bool __is_reversible_subrange = false;
4130 template<typename _Iter, subrange_kind _Kind>
4131 inline constexpr bool
4132 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4133 reverse_iterator<_Iter>,
4137 inline constexpr bool __is_reverse_view = false;
4139 template<typename _Vp>
4140 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
4142 template<typename _Range>
4143 concept __can_reverse_view
4144 = requires { reverse_view{std::declval<_Range>()}; };
4145 } // namespace __detail
4147 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4149 template<viewable_range _Range>
4150 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4151 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4152 || __detail::__can_reverse_view<_Range>
4154 operator() [[nodiscard]] (_Range&& __r) const
4156 using _Tp = remove_cvref_t<_Range>;
4157 if constexpr (__detail::__is_reverse_view<_Tp>)
4158 return std::forward<_Range>(__r).base();
4159 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4161 using _Iter = decltype(ranges::begin(__r).base());
4162 if constexpr (sized_range<_Tp>)
4163 return subrange<_Iter, _Iter, subrange_kind::sized>
4164 {__r.end().base(), __r.begin().base(), __r.size()};
4166 return subrange<_Iter, _Iter, subrange_kind::unsized>
4167 {__r.end().base(), __r.begin().base()};
4170 return reverse_view{std::forward<_Range>(__r)};
4173 static constexpr bool _S_has_simple_call_op = true;
4176 inline constexpr _Reverse reverse;
4177 } // namespace views
4181#if __cpp_lib_tuple_like // >= C++23
4182 template<typename _Tp, size_t _Nm>
4183 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4185 template<typename _Tp, size_t _Nm>
4186 concept __has_tuple_element = requires(_Tp __t)
4188 typename tuple_size<_Tp>::type;
4189 requires _Nm < tuple_size_v<_Tp>;
4190 typename tuple_element_t<_Nm, _Tp>;
4191 { std::get<_Nm>(__t) }
4192 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4196 template<typename _Tp, size_t _Nm>
4197 concept __returnable_element
4198 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4201 template<input_range _Vp, size_t _Nm>
4203 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4204 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4206 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4207 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4210 elements_view() requires default_initializable<_Vp> = default;
4213 elements_view(_Vp __base)
4214 : _M_base(std::move(__base))
4218 base() const& requires copy_constructible<_Vp>
4223 { return std::move(_M_base); }
4226 begin() requires (!__detail::__simple_view<_Vp>)
4227 { return _Iterator<false>(ranges::begin(_M_base)); }
4230 begin() const requires range<const _Vp>
4231 { return _Iterator<true>(ranges::begin(_M_base)); }
4234 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4235 { return _Sentinel<false>{ranges::end(_M_base)}; }
4238 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4239 { return _Iterator<false>{ranges::end(_M_base)}; }
4242 end() const requires range<const _Vp>
4243 { return _Sentinel<true>{ranges::end(_M_base)}; }
4246 end() const requires common_range<const _Vp>
4247 { return _Iterator<true>{ranges::end(_M_base)}; }
4250 size() requires sized_range<_Vp>
4251 { return ranges::size(_M_base); }
4254 size() const requires sized_range<const _Vp>
4255 { return ranges::size(_M_base); }
4258 template<bool _Const>
4259 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4261 template<bool _Const>
4265 template<bool _Const>
4266 requires forward_range<_Base<_Const>>
4267 struct __iter_cat<_Const>
4270 static auto _S_iter_cat()
4272 using _Base = elements_view::_Base<_Const>;
4273 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4274 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4275 if constexpr (!is_lvalue_reference_v<_Res>)
4276 return input_iterator_tag{};
4277 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4278 return random_access_iterator_tag{};
4283 using iterator_category = decltype(_S_iter_cat());
4286 template<bool _Const>
4289 template<bool _Const>
4290 struct _Iterator : __iter_cat<_Const>
4293 using _Base = elements_view::_Base<_Const>;
4295 iterator_t<_Base> _M_current = iterator_t<_Base>();
4297 static constexpr decltype(auto)
4298 _S_get_element(const iterator_t<_Base>& __i)
4300 if constexpr (is_reference_v<range_reference_t<_Base>>)
4301 return std::get<_Nm>(*__i);
4304 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4305 return static_cast<_Et>(std::get<_Nm>(*__i));
4312 if constexpr (random_access_range<_Base>)
4313 return random_access_iterator_tag{};
4314 else if constexpr (bidirectional_range<_Base>)
4315 return bidirectional_iterator_tag{};
4316 else if constexpr (forward_range<_Base>)
4317 return forward_iterator_tag{};
4319 return input_iterator_tag{};
4322 friend _Iterator<!_Const>;
4325 using iterator_concept = decltype(_S_iter_concept());
4326 // iterator_category defined in elements_view::__iter_cat
4328 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4329 using difference_type = range_difference_t<_Base>;
4331 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4334 _Iterator(iterator_t<_Base> __current)
4335 : _M_current(std::move(__current))
4339 _Iterator(_Iterator<!_Const> __i)
4340 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4341 : _M_current(std::move(__i._M_current))
4344 constexpr const iterator_t<_Base>&
4345 base() const& noexcept
4346 { return _M_current; }
4348 constexpr iterator_t<_Base>
4350 { return std::move(_M_current); }
4352 constexpr decltype(auto)
4354 { return _S_get_element(_M_current); }
4356 constexpr _Iterator&
4368 operator++(int) requires forward_range<_Base>
4375 constexpr _Iterator&
4376 operator--() requires bidirectional_range<_Base>
4383 operator--(int) requires bidirectional_range<_Base>
4390 constexpr _Iterator&
4391 operator+=(difference_type __n)
4392 requires random_access_range<_Base>
4398 constexpr _Iterator&
4399 operator-=(difference_type __n)
4400 requires random_access_range<_Base>
4406 constexpr decltype(auto)
4407 operator[](difference_type __n) const
4408 requires random_access_range<_Base>
4409 { return _S_get_element(_M_current + __n); }
4411 friend constexpr bool
4412 operator==(const _Iterator& __x, const _Iterator& __y)
4413 requires equality_comparable<iterator_t<_Base>>
4414 { return __x._M_current == __y._M_current; }
4416 friend constexpr bool
4417 operator<(const _Iterator& __x, const _Iterator& __y)
4418 requires random_access_range<_Base>
4419 { return __x._M_current < __y._M_current; }
4421 friend constexpr bool
4422 operator>(const _Iterator& __x, const _Iterator& __y)
4423 requires random_access_range<_Base>
4424 { return __y._M_current < __x._M_current; }
4426 friend constexpr bool
4427 operator<=(const _Iterator& __x, const _Iterator& __y)
4428 requires random_access_range<_Base>
4429 { return !(__y._M_current > __x._M_current); }
4431 friend constexpr bool
4432 operator>=(const _Iterator& __x, const _Iterator& __y)
4433 requires random_access_range<_Base>
4434 { return !(__x._M_current > __y._M_current); }
4436#ifdef __cpp_lib_three_way_comparison
4437 friend constexpr auto
4438 operator<=>(const _Iterator& __x, const _Iterator& __y)
4439 requires random_access_range<_Base>
4440 && three_way_comparable<iterator_t<_Base>>
4441 { return __x._M_current <=> __y._M_current; }
4444 friend constexpr _Iterator
4445 operator+(const _Iterator& __x, difference_type __y)
4446 requires random_access_range<_Base>
4447 { return _Iterator{__x} += __y; }
4449 friend constexpr _Iterator
4450 operator+(difference_type __x, const _Iterator& __y)
4451 requires random_access_range<_Base>
4452 { return __y + __x; }
4454 friend constexpr _Iterator
4455 operator-(const _Iterator& __x, difference_type __y)
4456 requires random_access_range<_Base>
4457 { return _Iterator{__x} -= __y; }
4459 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4460 // 3483. transform_view::iterator's difference is overconstrained
4461 friend constexpr difference_type
4462 operator-(const _Iterator& __x, const _Iterator& __y)
4463 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4464 { return __x._M_current - __y._M_current; }
4466 template <bool> friend struct _Sentinel;
4469 template<bool _Const>
4473 template<bool _Const2>
4475 _M_equal(const _Iterator<_Const2>& __x) const
4476 { return __x._M_current == _M_end; }
4478 template<bool _Const2>
4480 _M_distance_from(const _Iterator<_Const2>& __i) const
4481 { return _M_end - __i._M_current; }
4483 using _Base = elements_view::_Base<_Const>;
4484 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4487 _Sentinel() = default;
4490 _Sentinel(sentinel_t<_Base> __end)
4491 : _M_end(std::move(__end))
4495 _Sentinel(_Sentinel<!_Const> __other)
4497 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4498 : _M_end(std::move(__other._M_end))
4501 constexpr sentinel_t<_Base>
4505 template<bool _Const2>
4506 requires sentinel_for<sentinel_t<_Base>,
4507 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4508 friend constexpr bool
4509 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4510 { return __y._M_equal(__x); }
4512 template<bool _Const2,
4513 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4514 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4515 friend constexpr range_difference_t<_Base2>
4516 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4517 { return -__y._M_distance_from(__x); }
4519 template<bool _Const2,
4520 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4521 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4522 friend constexpr range_difference_t<_Base2>
4523 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4524 { return __x._M_distance_from(__y); }
4526 friend _Sentinel<!_Const>;
4529 _Vp _M_base = _Vp();
4532 template<typename _Tp, size_t _Nm>
4533 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4534 = enable_borrowed_range<_Tp>;
4536 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4537 // 3563. keys_view example is broken
4538 template<typename _Range>
4539 using keys_view = elements_view<_Range, 0>;
4541 template<typename _Range>
4542 using values_view = elements_view<_Range, 1>;
4548 template<size_t _Nm, typename _Range>
4549 concept __can_elements_view
4550 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4551 } // namespace __detail
4553 template<size_t _Nm>
4554 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4556 template<viewable_range _Range>
4557 requires __detail::__can_elements_view<_Nm, _Range>
4559 operator() [[nodiscard]] (_Range&& __r) const
4561 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4564 static constexpr bool _S_has_simple_call_op = true;
4567 template<size_t _Nm>
4568 inline constexpr _Elements<_Nm> elements;
4569 inline constexpr auto keys = elements<0>;
4570 inline constexpr auto values = elements<1>;
4571 } // namespace views
4573#ifdef __cpp_lib_ranges_zip // C++ >= 23
4576 template<typename... _Rs>
4577 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4578 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4579 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4581 template<typename _Fp, typename _Tuple>
4583 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4585 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4586 return tuple<invoke_result_t<_Fp&, _Ts>...>
4587 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4588 }, std::forward<_Tuple>(__tuple));
4591 template<typename _Fp, typename _Tuple>
4593 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4595 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4596 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4597 }, std::forward<_Tuple>(__tuple));
4599 } // namespace __detail
4601 template<input_range... _Vs>
4602 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4603 class zip_view : public view_interface<zip_view<_Vs...>>
4605 tuple<_Vs...> _M_views;
4607 template<bool> class _Iterator;
4608 template<bool> class _Sentinel;
4611 zip_view() = default;
4614 zip_view(_Vs... __views)
4615 : _M_views(std::move(__views)...)
4619 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4620 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4623 begin() const requires (range<const _Vs> && ...)
4624 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4627 end() requires (!(__detail::__simple_view<_Vs> && ...))
4629 if constexpr (!__detail::__zip_is_common<_Vs...>)
4630 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4631 else if constexpr ((random_access_range<_Vs> && ...))
4632 return begin() + iter_difference_t<_Iterator<false>>(size());
4634 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4638 end() const requires (range<const _Vs> && ...)
4640 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4641 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4642 else if constexpr ((random_access_range<const _Vs> && ...))
4643 return begin() + iter_difference_t<_Iterator<true>>(size());
4645 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4649 size() requires (sized_range<_Vs> && ...)
4651 return std::apply([](auto... sizes) {
4652 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4653 return ranges::min({_CT(sizes)...});
4654 }, __detail::__tuple_transform(ranges::size, _M_views));
4658 size() const requires (sized_range<const _Vs> && ...)
4660 return std::apply([](auto... sizes) {
4661 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4662 return ranges::min({_CT(sizes)...});
4663 }, __detail::__tuple_transform(ranges::size, _M_views));
4667 template<typename... _Rs>
4668 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4670 template<typename... _Views>
4671 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4672 = (enable_borrowed_range<_Views> && ...);
4676 template<bool _Const, typename... _Vs>
4677 concept __all_random_access
4678 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4680 template<bool _Const, typename... _Vs>
4681 concept __all_bidirectional
4682 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4684 template<bool _Const, typename... _Vs>
4685 concept __all_forward
4686 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4688 template<bool _Const, typename... _Views>
4689 struct __zip_view_iter_cat
4692 template<bool _Const, typename... _Views>
4693 requires __all_forward<_Const, _Views...>
4694 struct __zip_view_iter_cat<_Const, _Views...>
4695 { using iterator_category = input_iterator_tag; };
4696 } // namespace __detail
4698 template<input_range... _Vs>
4699 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4700 template<bool _Const>
4701 class zip_view<_Vs...>::_Iterator
4702 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4704#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
4707 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4710 _Iterator(decltype(_M_current) __current)
4711 : _M_current(std::move(__current))
4717 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4718 return random_access_iterator_tag{};
4719 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4720 return bidirectional_iterator_tag{};
4721 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4722 return forward_iterator_tag{};
4724 return input_iterator_tag{};
4727#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
4728 template<move_constructible _Fp, input_range... _Ws>
4729 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4730 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4731 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4732 friend class zip_transform_view;
4736 // iterator_category defined in __zip_view_iter_cat
4737 using iterator_concept = decltype(_S_iter_concept());
4739 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4740 using difference_type
4741 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4743 _Iterator() = default;
4746 _Iterator(_Iterator<!_Const> __i)
4748 && (convertible_to<iterator_t<_Vs>,
4749 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4750 : _M_current(std::move(__i._M_current))
4756 auto __f = [](auto& __i) -> decltype(auto) {
4759 return __detail::__tuple_transform(__f, _M_current);
4762 constexpr _Iterator&
4765 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4775 requires __detail::__all_forward<_Const, _Vs...>
4782 constexpr _Iterator&
4784 requires __detail::__all_bidirectional<_Const, _Vs...>
4786 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4792 requires __detail::__all_bidirectional<_Const, _Vs...>
4799 constexpr _Iterator&
4800 operator+=(difference_type __x)
4801 requires __detail::__all_random_access<_Const, _Vs...>
4803 auto __f = [&]<typename _It>(_It& __i) {
4804 __i += iter_difference_t<_It>(__x);
4806 __detail::__tuple_for_each(__f, _M_current);
4810 constexpr _Iterator&
4811 operator-=(difference_type __x)
4812 requires __detail::__all_random_access<_Const, _Vs...>
4814 auto __f = [&]<typename _It>(_It& __i) {
4815 __i -= iter_difference_t<_It>(__x);
4817 __detail::__tuple_for_each(__f, _M_current);
4822 operator[](difference_type __n) const
4823 requires __detail::__all_random_access<_Const, _Vs...>
4825 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4826 return __i[iter_difference_t<_It>(__n)];
4828 return __detail::__tuple_transform(__f, _M_current);
4831 friend constexpr bool
4832 operator==(const _Iterator& __x, const _Iterator& __y)
4833 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4835 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4836 return __x._M_current == __y._M_current;
4838 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4839 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4840 }(make_index_sequence<sizeof...(_Vs)>{});
4843 friend constexpr auto
4844 operator<=>(const _Iterator& __x, const _Iterator& __y)
4845 requires __detail::__all_random_access<_Const, _Vs...>
4846 { return __x._M_current <=> __y._M_current; }
4848 friend constexpr _Iterator
4849 operator+(const _Iterator& __i, difference_type __n)
4850 requires __detail::__all_random_access<_Const, _Vs...>
4857 friend constexpr _Iterator
4858 operator+(difference_type __n, const _Iterator& __i)
4859 requires __detail::__all_random_access<_Const, _Vs...>
4866 friend constexpr _Iterator
4867 operator-(const _Iterator& __i, difference_type __n)
4868 requires __detail::__all_random_access<_Const, _Vs...>
4875 friend constexpr difference_type
4876 operator-(const _Iterator& __x, const _Iterator& __y)
4877 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4878 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4880 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4881 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4882 - std::get<_Is>(__y._M_current))...},
4884 [](difference_type __i) {
4885 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4887 }(make_index_sequence<sizeof...(_Vs)>{});
4890 friend constexpr auto
4891 iter_move(const _Iterator& __i)
4892 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4894 friend constexpr void
4895 iter_swap(const _Iterator& __l, const _Iterator& __r)
4896 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4898 [&]<size_t... _Is>(index_sequence<_Is...>) {
4899 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4900 }(make_index_sequence<sizeof...(_Vs)>{});
4903 friend class zip_view;
4906 template<input_range... _Vs>
4907 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4908 template<bool _Const>
4909 class zip_view<_Vs...>::_Sentinel
4911 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4914 _Sentinel(decltype(_M_end) __end)
4918 friend class zip_view;
4921 _Sentinel() = default;
4924 _Sentinel(_Sentinel<!_Const> __i)
4926 && (convertible_to<sentinel_t<_Vs>,
4927 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4928 : _M_end(std::move(__i._M_end))
4931 template<bool _OtherConst>
4932 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4933 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4934 friend constexpr bool
4935 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4937 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4938 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4939 }(make_index_sequence<sizeof...(_Vs)>{});
4942 template<bool _OtherConst>
4943 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4944 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4945 friend constexpr auto
4946 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4949 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4950 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4951 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4954 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4956 }(make_index_sequence<sizeof...(_Vs)>{});
4959 template<bool _OtherConst>
4960 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4961 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4962 friend constexpr auto
4963 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4964 { return -(__x - __y); }
4971 template<typename... _Ts>
4972 concept __can_zip_view
4973 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4978 template<typename... _Ts>
4979 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4981 operator() [[nodiscard]] (_Ts&&... __ts) const
4983 if constexpr (sizeof...(_Ts) == 0)
4984 return views::empty<tuple<>>;
4986 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4990 inline constexpr _Zip zip;
4995 template<typename _Range, bool _Const>
4996 using __range_iter_cat
4997 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5000 template<move_constructible _Fp, input_range... _Vs>
5001 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5002 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5003 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5004 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
5006 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5007 zip_view<_Vs...> _M_zip;
5009 using _InnerView = zip_view<_Vs...>;
5011 template<bool _Const>
5012 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5014 template<bool _Const>
5015 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5017 template<bool _Const>
5018 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5020 template<bool _Const>
5024 template<bool _Const>
5025 requires forward_range<_Base<_Const>>
5026 struct __iter_cat<_Const>
5032 using __detail::__maybe_const_t;
5033 using __detail::__range_iter_cat;
5034 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5035 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5036 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5037 // 3798. Rvalue reference and iterator_category
5038 if constexpr (!is_reference_v<_Res>)
5039 return input_iterator_tag{};
5040 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5041 random_access_iterator_tag> && ...))
5042 return random_access_iterator_tag{};
5043 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5044 bidirectional_iterator_tag> && ...))
5045 return bidirectional_iterator_tag{};
5046 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5047 forward_iterator_tag> && ...))
5048 return forward_iterator_tag{};
5050 return input_iterator_tag{};
5053 using iterator_category = decltype(_S_iter_cat());
5056 template<bool> class _Iterator;
5057 template<bool> class _Sentinel;
5060 zip_transform_view() = default;
5063 zip_transform_view(_Fp __fun, _Vs... __views)
5064 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5069 { return _Iterator<false>(*this, _M_zip.begin()); }
5073 requires range<const _InnerView>
5074 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5075 { return _Iterator<true>(*this, _M_zip.begin()); }
5080 if constexpr (common_range<_InnerView>)
5081 return _Iterator<false>(*this, _M_zip.end());
5083 return _Sentinel<false>(_M_zip.end());
5088 requires range<const _InnerView>
5089 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5091 if constexpr (common_range<const _InnerView>)
5092 return _Iterator<true>(*this, _M_zip.end());
5094 return _Sentinel<true>(_M_zip.end());
5098 size() requires sized_range<_InnerView>
5099 { return _M_zip.size(); }
5102 size() const requires sized_range<const _InnerView>
5103 { return _M_zip.size(); }
5106 template<class _Fp, class... Rs>
5107 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5109 template<move_constructible _Fp, input_range... _Vs>
5110 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5111 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5112 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5113 template<bool _Const>
5114 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5116 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5118 _Parent* _M_parent = nullptr;
5119 __ziperator<_Const> _M_inner;
5122 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5123 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5126 friend class zip_transform_view;
5129 // iterator_category defined in zip_transform_view::__iter_cat
5130 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
5132 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5133 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5134 using difference_type = range_difference_t<_Base<_Const>>;
5136 _Iterator() = default;
5139 _Iterator(_Iterator<!_Const> __i)
5140 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5141 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5144 constexpr decltype(auto)
5147 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5148 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5149 }, _M_inner._M_current);
5152 constexpr _Iterator&
5164 operator++(int) requires forward_range<_Base<_Const>>
5171 constexpr _Iterator&
5172 operator--() requires bidirectional_range<_Base<_Const>>
5179 operator--(int) requires bidirectional_range<_Base<_Const>>
5186 constexpr _Iterator&
5187 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5193 constexpr _Iterator&
5194 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5200 constexpr decltype(auto)
5201 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5203 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5204 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5205 }, _M_inner._M_current);
5208 friend constexpr bool
5209 operator==(const _Iterator& __x, const _Iterator& __y)
5210 requires equality_comparable<__ziperator<_Const>>
5211 { return __x._M_inner == __y._M_inner; }
5213 friend constexpr auto
5214 operator<=>(const _Iterator& __x, const _Iterator& __y)
5215 requires random_access_range<_Base<_Const>>
5216 { return __x._M_inner <=> __y._M_inner; }
5218 friend constexpr _Iterator
5219 operator+(const _Iterator& __i, difference_type __n)
5220 requires random_access_range<_Base<_Const>>
5221 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5223 friend constexpr _Iterator
5224 operator+(difference_type __n, const _Iterator& __i)
5225 requires random_access_range<_Base<_Const>>
5226 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5228 friend constexpr _Iterator
5229 operator-(const _Iterator& __i, difference_type __n)
5230 requires random_access_range<_Base<_Const>>
5231 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5233 friend constexpr difference_type
5234 operator-(const _Iterator& __x, const _Iterator& __y)
5235 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5236 { return __x._M_inner - __y._M_inner; }
5239 template<move_constructible _Fp, input_range... _Vs>
5240 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5241 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5242 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5243 template<bool _Const>
5244 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5246 __zentinel<_Const> _M_inner;
5249 _Sentinel(__zentinel<_Const> __inner)
5253 friend class zip_transform_view;
5256 _Sentinel() = default;
5259 _Sentinel(_Sentinel<!_Const> __i)
5260 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5261 : _M_inner(std::move(__i._M_inner))
5264 template<bool _OtherConst>
5265 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5266 friend constexpr bool
5267 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5268 { return __x._M_inner == __y._M_inner; }
5270 template<bool _OtherConst>
5271 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5272 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5273 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5274 { return __x._M_inner - __y._M_inner; }
5276 template<bool _OtherConst>
5277 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5278 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5279 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5280 { return __x._M_inner - __y._M_inner; }
5287 template<typename _Fp, typename... _Ts>
5288 concept __can_zip_transform_view
5289 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5292 struct _ZipTransform
5294 template<typename _Fp>
5295 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
5296 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
5298 operator() [[nodiscard]] (_Fp&&) const
5300 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5303 template<typename _Fp, typename... _Ts>
5304 requires (sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
5306 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5308 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5312 inline constexpr _ZipTransform zip_transform;
5315 template<forward_range _Vp, size_t _Nm>
5316 requires view<_Vp> && (_Nm > 0)
5317 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5319 _Vp _M_base = _Vp();
5321 template<bool> class _Iterator;
5322 template<bool> class _Sentinel;
5324 struct __as_sentinel
5328 adjacent_view() requires default_initializable<_Vp> = default;
5331 adjacent_view(_Vp __base)
5332 : _M_base(std::move(__base))
5335 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5336 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5338 base() const & requires copy_constructible<_Vp>
5343 { return std::move(_M_base); }
5346 begin() requires (!__detail::__simple_view<_Vp>)
5347 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5350 begin() const requires range<const _Vp>
5351 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5354 end() requires (!__detail::__simple_view<_Vp>)
5356 if constexpr (common_range<_Vp>)
5357 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5359 return _Sentinel<false>(ranges::end(_M_base));
5363 end() const requires range<const _Vp>
5365 if constexpr (common_range<const _Vp>)
5366 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5368 return _Sentinel<true>(ranges::end(_M_base));
5372 size() requires sized_range<_Vp>
5374 using _ST = decltype(ranges::size(_M_base));
5375 using _CT = common_type_t<_ST, size_t>;
5376 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5377 __sz -= std::min<_CT>(__sz, _Nm - 1);
5378 return static_cast<_ST>(__sz);
5382 size() const requires sized_range<const _Vp>
5384 using _ST = decltype(ranges::size(_M_base));
5385 using _CT = common_type_t<_ST, size_t>;
5386 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5387 __sz -= std::min<_CT>(__sz, _Nm - 1);
5388 return static_cast<_ST>(__sz);
5392 template<typename _Vp, size_t _Nm>
5393 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5394 = enable_borrowed_range<_Vp>;
5398 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5399 template<typename _Tp, size_t _Nm>
5400 using __repeated_tuple = typename __make_tuple<array<_Tp, _Nm>>::__type;
5402 // For a functor F that is callable with N arguments, the expression
5403 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5404 template<typename _Fp, size_t _Nm>
5407 template<typename... _Ts>
5408 static invoke_result_t<_Fp, _Ts...>
5409 __tuple_apply(const tuple<_Ts...>&); // not defined
5411 template<typename _Tp>
5412 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5413 operator()(_Tp&&); // not defined
5417 template<forward_range _Vp, size_t _Nm>
5418 requires view<_Vp> && (_Nm > 0)
5419 template<bool _Const>
5420 class adjacent_view<_Vp, _Nm>::_Iterator
5422#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
5425 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5426 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5429 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5431 for (auto& __i : _M_current)
5434 ranges::advance(__first, 1, __last);
5439 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5441 if constexpr (!bidirectional_range<_Base>)
5442 for (auto& __it : _M_current)
5445 for (size_t __i = 0; __i < _Nm; ++__i)
5447 _M_current[_Nm - 1 - __i] = __last;
5448 ranges::advance(__last, -1, __first);
5455 if constexpr (random_access_range<_Base>)
5456 return random_access_iterator_tag{};
5457 else if constexpr (bidirectional_range<_Base>)
5458 return bidirectional_iterator_tag{};
5460 return forward_iterator_tag{};
5463 friend class adjacent_view;
5465#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
5466 template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
5467 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5468 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5469 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5470 range_reference_t<_Wp>>>
5471 friend class adjacent_transform_view;
5475 using iterator_category = input_iterator_tag;
5476 using iterator_concept = decltype(_S_iter_concept());
5477 using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
5478 using difference_type = range_difference_t<_Base>;
5480 _Iterator() = default;
5483 _Iterator(_Iterator<!_Const> __i)
5484 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5486 for (size_t __j = 0; __j < _Nm; ++__j)
5487 _M_current[__j] = std::move(__i._M_current[__j]);
5493 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5494 return __detail::__tuple_transform(__f, _M_current);
5497 constexpr _Iterator&
5500 for (auto& __i : _M_current)
5513 constexpr _Iterator&
5514 operator--() requires bidirectional_range<_Base>
5516 for (auto& __i : _M_current)
5522 operator--(int) requires bidirectional_range<_Base>
5529 constexpr _Iterator&
5530 operator+=(difference_type __x)
5531 requires random_access_range<_Base>
5533 for (auto& __i : _M_current)
5538 constexpr _Iterator&
5539 operator-=(difference_type __x)
5540 requires random_access_range<_Base>
5542 for (auto& __i : _M_current)
5548 operator[](difference_type __n) const
5549 requires random_access_range<_Base>
5551 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5552 return __detail::__tuple_transform(__f, _M_current);
5555 friend constexpr bool
5556 operator==(const _Iterator& __x, const _Iterator& __y)
5557 { return __x._M_current.back() == __y._M_current.back(); }
5559 friend constexpr bool
5560 operator<(const _Iterator& __x, const _Iterator& __y)
5561 requires random_access_range<_Base>
5562 { return __x._M_current.back() < __y._M_current.back(); }
5564 friend constexpr bool
5565 operator>(const _Iterator& __x, const _Iterator& __y)
5566 requires random_access_range<_Base>
5567 { return __y < __x; }
5569 friend constexpr bool
5570 operator<=(const _Iterator& __x, const _Iterator& __y)
5571 requires random_access_range<_Base>
5572 { return !(__y < __x); }
5574 friend constexpr bool
5575 operator>=(const _Iterator& __x, const _Iterator& __y)
5576 requires random_access_range<_Base>
5577 { return !(__x < __y); }
5579 friend constexpr auto
5580 operator<=>(const _Iterator& __x, const _Iterator& __y)
5581 requires random_access_range<_Base>
5582 && three_way_comparable<iterator_t<_Base>>
5583 { return __x._M_current.back() <=> __y._M_current.back(); }
5585 friend constexpr _Iterator
5586 operator+(const _Iterator& __i, difference_type __n)
5587 requires random_access_range<_Base>
5594 friend constexpr _Iterator
5595 operator+(difference_type __n, const _Iterator& __i)
5596 requires random_access_range<_Base>
5603 friend constexpr _Iterator
5604 operator-(const _Iterator& __i, difference_type __n)
5605 requires random_access_range<_Base>
5612 friend constexpr difference_type
5613 operator-(const _Iterator& __x, const _Iterator& __y)
5614 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5615 { return __x._M_current.back() - __y._M_current.back(); }
5617 friend constexpr auto
5618 iter_move(const _Iterator& __i)
5619 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5621 friend constexpr void
5622 iter_swap(const _Iterator& __l, const _Iterator& __r)
5623 requires indirectly_swappable<iterator_t<_Base>>
5625 for (size_t __i = 0; __i < _Nm; __i++)
5626 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5630 template<forward_range _Vp, size_t _Nm>
5631 requires view<_Vp> && (_Nm > 0)
5632 template<bool _Const>
5633 class adjacent_view<_Vp, _Nm>::_Sentinel
5635 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5637 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5640 _Sentinel(sentinel_t<_Base> __end)
5644 friend class adjacent_view;
5647 _Sentinel() = default;
5650 _Sentinel(_Sentinel<!_Const> __i)
5651 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5652 : _M_end(std::move(__i._M_end))
5655 template<bool _OtherConst>
5656 requires sentinel_for<sentinel_t<_Base>,
5657 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5658 friend constexpr bool
5659 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5660 { return __x._M_current.back() == __y._M_end; }
5662 template<bool _OtherConst>
5663 requires sized_sentinel_for<sentinel_t<_Base>,
5664 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5665 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5666 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5667 { return __x._M_current.back() - __y._M_end; }
5669 template<bool _OtherConst>
5670 requires sized_sentinel_for<sentinel_t<_Base>,
5671 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5672 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5673 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5674 { return __y._M_end - __x._M_current.back(); }
5681 template<size_t _Nm, typename _Range>
5682 concept __can_adjacent_view
5683 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5686 template<size_t _Nm>
5687 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5689 template<viewable_range _Range>
5690 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5692 operator() [[nodiscard]] (_Range&& __r) const
5694 if constexpr (_Nm == 0)
5695 return views::empty<tuple<>>;
5697 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5701 template<size_t _Nm>
5702 inline constexpr _Adjacent<_Nm> adjacent;
5704 inline constexpr auto pairwise = adjacent<2>;
5707 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5708 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5709 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5710 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5711 range_reference_t<_Vp>>>
5712 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5714 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5715 adjacent_view<_Vp, _Nm> _M_inner;
5717 using _InnerView = adjacent_view<_Vp, _Nm>;
5719 template<bool _Const>
5720 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5722 template<bool _Const>
5723 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5725 template<bool> class _Iterator;
5726 template<bool> class _Sentinel;
5729 adjacent_transform_view() = default;
5732 adjacent_transform_view(_Vp __base, _Fp __fun)
5733 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5736 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5737 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5738 // 3947. Unexpected constraints on adjacent_transform_view::base()
5740 base() const & requires copy_constructible<_Vp>
5741 { return _M_inner.base(); }
5745 { return std::move(_M_inner.base()); }
5749 { return _Iterator<false>(*this, _M_inner.begin()); }
5753 requires range<const _InnerView>
5754 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5755 range_reference_t<const _Vp>>
5756 { return _Iterator<true>(*this, _M_inner.begin()); }
5761 if constexpr (common_range<_InnerView>)
5762 return _Iterator<false>(*this, _M_inner.end());
5764 return _Sentinel<false>(_M_inner.end());
5769 requires range<const _InnerView>
5770 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5771 range_reference_t<const _Vp>>
5773 if constexpr (common_range<const _InnerView>)
5774 return _Iterator<true>(*this, _M_inner.end());
5776 return _Sentinel<true>(_M_inner.end());
5780 size() requires sized_range<_InnerView>
5781 { return _M_inner.size(); }
5784 size() const requires sized_range<const _InnerView>
5785 { return _M_inner.size(); }
5788 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5789 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5790 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5791 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5792 range_reference_t<_Vp>>>
5793 template<bool _Const>
5794 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5796 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5797 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5799 _Parent* _M_parent = nullptr;
5800 _InnerIter<_Const> _M_inner;
5803 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5804 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5810 using __detail::__maybe_const_t;
5811 using __detail::__unarize;
5812 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5813 range_reference_t<_Base>>;
5814 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5815 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5816 // 3798. Rvalue reference and iterator_category
5817 if constexpr (!is_reference_v<_Res>)
5818 return input_iterator_tag{};
5819 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5820 return random_access_iterator_tag{};
5821 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5822 return bidirectional_iterator_tag{};
5823 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5824 return forward_iterator_tag{};
5826 return input_iterator_tag{};
5829 friend class adjacent_transform_view;
5832 using iterator_category = decltype(_S_iter_cat());
5833 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5835 = remove_cvref_t<invoke_result_t
5836 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5837 range_reference_t<_Base>>>;
5838 using difference_type = range_difference_t<_Base>;
5840 _Iterator() = default;
5843 _Iterator(_Iterator<!_Const> __i)
5844 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5845 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5848 constexpr decltype(auto)
5851 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5852 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5853 }, _M_inner._M_current);
5856 constexpr _Iterator&
5871 constexpr _Iterator&
5872 operator--() requires bidirectional_range<_Base>
5879 operator--(int) requires bidirectional_range<_Base>
5886 constexpr _Iterator&
5887 operator+=(difference_type __x) requires random_access_range<_Base>
5893 constexpr _Iterator&
5894 operator-=(difference_type __x) requires random_access_range<_Base>
5900 constexpr decltype(auto)
5901 operator[](difference_type __n) const requires random_access_range<_Base>
5903 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5904 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5905 }, _M_inner._M_current);
5908 friend constexpr bool
5909 operator==(const _Iterator& __x, const _Iterator& __y)
5910 { return __x._M_inner == __y._M_inner; }
5912 friend constexpr bool
5913 operator<(const _Iterator& __x, const _Iterator& __y)
5914 requires random_access_range<_Base>
5915 { return __x._M_inner < __y._M_inner; }
5917 friend constexpr bool
5918 operator>(const _Iterator& __x, const _Iterator& __y)
5919 requires random_access_range<_Base>
5920 { return __x._M_inner > __y._M_inner; }
5922 friend constexpr bool
5923 operator<=(const _Iterator& __x, const _Iterator& __y)
5924 requires random_access_range<_Base>
5925 { return __x._M_inner <= __y._M_inner; }
5927 friend constexpr bool
5928 operator>=(const _Iterator& __x, const _Iterator& __y)
5929 requires random_access_range<_Base>
5930 { return __x._M_inner >= __y._M_inner; }
5932 friend constexpr auto
5933 operator<=>(const _Iterator& __x, const _Iterator& __y)
5934 requires random_access_range<_Base> &&
5935 three_way_comparable<_InnerIter<_Const>>
5936 { return __x._M_inner <=> __y._M_inner; }
5938 friend constexpr _Iterator
5939 operator+(const _Iterator& __i, difference_type __n)
5940 requires random_access_range<_Base>
5941 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5943 friend constexpr _Iterator
5944 operator+(difference_type __n, const _Iterator& __i)
5945 requires random_access_range<_Base>
5946 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5948 friend constexpr _Iterator
5949 operator-(const _Iterator& __i, difference_type __n)
5950 requires random_access_range<_Base>
5951 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5953 friend constexpr difference_type
5954 operator-(const _Iterator& __x, const _Iterator& __y)
5955 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5956 { return __x._M_inner - __y._M_inner; }
5959 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5960 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5961 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5962 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5963 range_reference_t<_Vp>>>
5964 template<bool _Const>
5965 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5967 _InnerSent<_Const> _M_inner;
5970 _Sentinel(_InnerSent<_Const> __inner)
5974 friend class adjacent_transform_view;
5977 _Sentinel() = default;
5980 _Sentinel(_Sentinel<!_Const> __i)
5981 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5982 : _M_inner(std::move(__i._M_inner))
5985 template<bool _OtherConst>
5986 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5987 friend constexpr bool
5988 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5989 { return __x._M_inner == __y._M_inner; }
5991 template<bool _OtherConst>
5992 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5993 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5994 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5995 { return __x._M_inner - __y._M_inner; }
5997 template<bool _OtherConst>
5998 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5999 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6000 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
6001 { return __x._M_inner - __y._M_inner; }
6008 template<size_t _Nm, typename _Range, typename _Fp>
6009 concept __can_adjacent_transform_view
6010 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6011 (std::declval<_Range>(), std::declval<_Fp>()); };
6014 template<size_t _Nm>
6015 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6017 template<viewable_range _Range, typename _Fp>
6018 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6020 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
6022 if constexpr (_Nm == 0)
6023 return zip_transform(std::forward<_Fp>(__f));
6025 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6026 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6029 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6030 static constexpr int _S_arity = 2;
6031 static constexpr bool _S_has_simple_extra_args = true;
6034 template<size_t _Nm>
6035 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6037 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6039#endif // __cpp_lib_ranges_zip
6041#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6044 template<typename _Tp>
6045 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6047 _Tp __r = __num / __denom;
6048 if (__num % __denom)
6055 requires input_range<_Vp>
6056 class chunk_view : public view_interface<chunk_view<_Vp>>
6059 range_difference_t<_Vp> _M_n;
6060 range_difference_t<_Vp> _M_remainder = 0;
6061 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6068 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6069 : _M_base(std::move(__base)), _M_n(__n)
6070 { __glibcxx_assert(__n >= 0); }
6073 base() const & requires copy_constructible<_Vp>
6078 { return std::move(_M_base); }
6080 constexpr _OuterIter
6083 _M_current = ranges::begin(_M_base);
6084 _M_remainder = _M_n;
6085 return _OuterIter(*this);
6088 constexpr default_sentinel_t
6089 end() const noexcept
6090 { return default_sentinel; }
6093 size() requires sized_range<_Vp>
6095 return __detail::__to_unsigned_like(__detail::__div_ceil
6096 (ranges::distance(_M_base), _M_n));
6100 size() const requires sized_range<const _Vp>
6102 return __detail::__to_unsigned_like(__detail::__div_ceil
6103 (ranges::distance(_M_base), _M_n));
6107 template<typename _Range>
6108 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6111 requires input_range<_Vp>
6112 class chunk_view<_Vp>::_OuterIter
6114 chunk_view* _M_parent;
6117 _OuterIter(chunk_view& __parent) noexcept
6118 : _M_parent(std::__addressof(__parent))
6124 using iterator_concept = input_iterator_tag;
6125 using difference_type = range_difference_t<_Vp>;
6129 _OuterIter(_OuterIter&&) = default;
6130 _OuterIter& operator=(_OuterIter&&) = default;
6132 constexpr value_type
6135 __glibcxx_assert(*this != default_sentinel);
6136 return value_type(*_M_parent);
6139 constexpr _OuterIter&
6142 __glibcxx_assert(*this != default_sentinel);
6143 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6144 ranges::end(_M_parent->_M_base));
6145 _M_parent->_M_remainder = _M_parent->_M_n;
6153 friend constexpr bool
6154 operator==(const _OuterIter& __x, default_sentinel_t)
6156 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6157 && __x._M_parent->_M_remainder != 0;
6160 friend constexpr difference_type
6161 operator-(default_sentinel_t, const _OuterIter& __x)
6162 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6164 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6166 if (__dist < __x._M_parent->_M_remainder)
6167 return __dist == 0 ? 0 : 1;
6169 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6170 __x._M_parent->_M_n);
6173 friend constexpr difference_type
6174 operator-(const _OuterIter& __x, default_sentinel_t __y)
6175 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6176 { return -(__y - __x); }
6180 requires input_range<_Vp>
6181 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6184 chunk_view* _M_parent;
6187 value_type(chunk_view& __parent) noexcept
6188 : _M_parent(std::__addressof(__parent))
6194 constexpr _InnerIter
6195 begin() const noexcept
6196 { return _InnerIter(*_M_parent); }
6198 constexpr default_sentinel_t
6199 end() const noexcept
6200 { return default_sentinel; }
6204 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6206 return __detail::__to_unsigned_like
6207 (ranges::min(_M_parent->_M_remainder,
6208 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6213 requires input_range<_Vp>
6214 class chunk_view<_Vp>::_InnerIter
6216 chunk_view* _M_parent;
6219 _InnerIter(chunk_view& __parent) noexcept
6220 : _M_parent(std::__addressof(__parent))
6223 friend _OuterIter::value_type;
6226 using iterator_concept = input_iterator_tag;
6227 using difference_type = range_difference_t<_Vp>;
6228 using value_type = range_value_t<_Vp>;
6230 _InnerIter(_InnerIter&&) = default;
6231 _InnerIter& operator=(_InnerIter&&) = default;
6233 constexpr const iterator_t<_Vp>&
6235 { return *_M_parent->_M_current; }
6237 constexpr range_reference_t<_Vp>
6240 __glibcxx_assert(*this != default_sentinel);
6241 return **_M_parent->_M_current;
6244 constexpr _InnerIter&
6247 __glibcxx_assert(*this != default_sentinel);
6248 ++*_M_parent->_M_current;
6249 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6250 _M_parent->_M_remainder = 0;
6252 --_M_parent->_M_remainder;
6260 friend constexpr bool
6261 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6262 { return __x._M_parent->_M_remainder == 0; }
6264 friend constexpr difference_type
6265 operator-(default_sentinel_t, const _InnerIter& __x)
6266 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6268 return ranges::min(__x._M_parent->_M_remainder,
6269 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6272 friend constexpr difference_type
6273 operator-(const _InnerIter& __x, default_sentinel_t __y)
6274 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6275 { return -(__y - __x); }
6277 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6278 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
6279 friend constexpr range_rvalue_reference_t<_Vp>
6280 iter_move(const _InnerIter& __i)
6281 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6282 { return ranges::iter_move(*__i._M_parent->_M_current); }
6284 friend constexpr void
6285 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
6286 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6287 *__x._M_parent->_M_current)))
6288 requires indirectly_swappable<iterator_t<_Vp>>
6289 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6293 requires forward_range<_Vp>
6294 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6297 range_difference_t<_Vp> _M_n;
6298 template<bool> class _Iterator;
6302 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6303 : _M_base(std::move(__base)), _M_n(__n)
6304 { __glibcxx_assert(__n > 0); }
6307 base() const & requires copy_constructible<_Vp>
6312 { return std::move(_M_base); }
6315 begin() requires (!__detail::__simple_view<_Vp>)
6316 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6319 begin() const requires forward_range<const _Vp>
6320 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6323 end() requires (!__detail::__simple_view<_Vp>)
6325 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6327 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6328 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6330 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6331 return _Iterator<false>(this, ranges::end(_M_base));
6333 return default_sentinel;
6337 end() const requires forward_range<const _Vp>
6339 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6341 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6342 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6344 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6345 return _Iterator<true>(this, ranges::end(_M_base));
6347 return default_sentinel;
6351 size() requires sized_range<_Vp>
6353 return __detail::__to_unsigned_like(__detail::__div_ceil
6354 (ranges::distance(_M_base), _M_n));
6358 size() const requires sized_range<const _Vp>
6360 return __detail::__to_unsigned_like(__detail::__div_ceil
6361 (ranges::distance(_M_base), _M_n));
6365 template<typename _Vp>
6366 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6367 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6370 requires forward_range<_Vp>
6371 template<bool _Const>
6372 class chunk_view<_Vp>::_Iterator
6374 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6375 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6377 iterator_t<_Base> _M_current = iterator_t<_Base>();
6378 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6379 range_difference_t<_Base> _M_n = 0;
6380 range_difference_t<_Base> _M_missing = 0;
6383 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6384 range_difference_t<_Base> __missing = 0)
6385 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6386 _M_n(__parent->_M_n), _M_missing(__missing)
6392 if constexpr (random_access_range<_Base>)
6393 return random_access_iterator_tag{};
6394 else if constexpr (bidirectional_range<_Base>)
6395 return bidirectional_iterator_tag{};
6397 return forward_iterator_tag{};
6403 using iterator_category = input_iterator_tag;
6404 using iterator_concept = decltype(_S_iter_cat());
6405 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6406 using difference_type = range_difference_t<_Base>;
6408 _Iterator() = default;
6410 constexpr _Iterator(_Iterator<!_Const> __i)
6412 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6413 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6414 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6415 _M_n(__i._M_n), _M_missing(__i._M_missing)
6418 constexpr iterator_t<_Base>
6420 { return _M_current; }
6422 constexpr value_type
6425 __glibcxx_assert(_M_current != _M_end);
6426 return views::take(subrange(_M_current, _M_end), _M_n);
6429 constexpr _Iterator&
6432 __glibcxx_assert(_M_current != _M_end);
6433 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6445 constexpr _Iterator&
6446 operator--() requires bidirectional_range<_Base>
6448 ranges::advance(_M_current, _M_missing - _M_n);
6454 operator--(int) requires bidirectional_range<_Base>
6461 constexpr _Iterator&
6462 operator+=(difference_type __x)
6463 requires random_access_range<_Base>
6467 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6468 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6472 ranges::advance(_M_current, _M_n * __x + _M_missing);
6478 constexpr _Iterator&
6479 operator-=(difference_type __x)
6480 requires random_access_range<_Base>
6481 { return *this += -__x; }
6483 constexpr value_type
6484 operator[](difference_type __n) const
6485 requires random_access_range<_Base>
6486 { return *(*this + __n); }
6488 friend constexpr bool
6489 operator==(const _Iterator& __x, const _Iterator& __y)
6490 { return __x._M_current == __y._M_current; }
6492 friend constexpr bool
6493 operator==(const _Iterator& __x, default_sentinel_t)
6494 { return __x._M_current == __x._M_end; }
6496 friend constexpr bool
6497 operator<(const _Iterator& __x, const _Iterator& __y)
6498 requires random_access_range<_Base>
6499 { return __x._M_current > __y._M_current; }
6501 friend constexpr bool
6502 operator>(const _Iterator& __x, const _Iterator& __y)
6503 requires random_access_range<_Base>
6504 { return __y < __x; }
6506 friend constexpr bool
6507 operator<=(const _Iterator& __x, const _Iterator& __y)
6508 requires random_access_range<_Base>
6509 { return !(__y < __x); }
6511 friend constexpr bool
6512 operator>=(const _Iterator& __x, const _Iterator& __y)
6513 requires random_access_range<_Base>
6514 { return !(__x < __y); }
6516 friend constexpr auto
6517 operator<=>(const _Iterator& __x, const _Iterator& __y)
6518 requires random_access_range<_Base>
6519 && three_way_comparable<iterator_t<_Base>>
6520 { return __x._M_current <=> __y._M_current; }
6522 friend constexpr _Iterator
6523 operator+(const _Iterator& __i, difference_type __n)
6524 requires random_access_range<_Base>
6531 friend constexpr _Iterator
6532 operator+(difference_type __n, const _Iterator& __i)
6533 requires random_access_range<_Base>
6540 friend constexpr _Iterator
6541 operator-(const _Iterator& __i, difference_type __n)
6542 requires random_access_range<_Base>
6549 friend constexpr difference_type
6550 operator-(const _Iterator& __x, const _Iterator& __y)
6551 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6553 return (__x._M_current - __y._M_current
6554 + __x._M_missing - __y._M_missing) / __x._M_n;
6557 friend constexpr difference_type
6558 operator-(default_sentinel_t, const _Iterator& __x)
6559 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6560 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6562 friend constexpr difference_type
6563 operator-(const _Iterator& __x, default_sentinel_t __y)
6564 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6565 { return -(__y - __x); }
6572 template<typename _Range, typename _Dp>
6573 concept __can_chunk_view
6574 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6577 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6579 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6580 requires __detail::__can_chunk_view<_Range, _Dp>
6582 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6583 { return chunk_view(std::forward<_Range>(__r), __n); }
6585 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6586 static constexpr int _S_arity = 2;
6587 static constexpr bool _S_has_simple_extra_args = true;
6590 inline constexpr _Chunk chunk;
6592#endif // __cpp_lib_ranges_chunk
6594#ifdef __cpp_lib_ranges_slide // C++ >= 23
6597 template<typename _Vp>
6598 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6600 template<typename _Vp>
6601 concept __slide_caches_last
6602 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6604 template<typename _Vp>
6605 concept __slide_caches_first
6606 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6609 template<forward_range _Vp>
6611 class slide_view : public view_interface<slide_view<_Vp>>
6614 range_difference_t<_Vp> _M_n;
6615 [[no_unique_address]]
6616 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6617 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6618 [[no_unique_address]]
6619 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6620 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6622 template<bool> class _Iterator;
6627 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6628 : _M_base(std::move(__base)), _M_n(__n)
6629 { __glibcxx_assert(__n > 0); }
6631 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6632 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
6634 base() const & requires copy_constructible<_Vp>
6639 { return std::move(_M_base); }
6642 begin() requires (!(__detail::__simple_view<_Vp>
6643 && __detail::__slide_caches_nothing<const _Vp>))
6645 if constexpr (__detail::__slide_caches_first<_Vp>)
6647 iterator_t<_Vp> __it;
6648 if (_M_cached_begin._M_has_value())
6649 __it = _M_cached_begin._M_get(_M_base);
6652 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6653 _M_cached_begin._M_set(_M_base, __it);
6655 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6658 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6662 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6663 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6666 end() requires (!(__detail::__simple_view<_Vp>
6667 && __detail::__slide_caches_nothing<const _Vp>))
6669 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6670 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6672 else if constexpr (__detail::__slide_caches_last<_Vp>)
6674 iterator_t<_Vp> __it;
6675 if (_M_cached_end._M_has_value())
6676 __it = _M_cached_end._M_get(_M_base);
6679 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6680 _M_cached_end._M_set(_M_base, __it);
6682 return _Iterator<false>(std::move(__it), _M_n);
6684 else if constexpr (common_range<_Vp>)
6685 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6687 return _Sentinel(ranges::end(_M_base));
6691 end() const requires __detail::__slide_caches_nothing<const _Vp>
6692 { return begin() + range_difference_t<const _Vp>(size()); }
6695 size() requires sized_range<_Vp>
6697 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6700 return __detail::__to_unsigned_like(__sz);
6704 size() const requires sized_range<const _Vp>
6706 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6709 return __detail::__to_unsigned_like(__sz);
6713 template<typename _Range>
6714 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6716 template<typename _Vp>
6717 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6718 = enable_borrowed_range<_Vp>;
6720 template<forward_range _Vp>
6722 template<bool _Const>
6723 class slide_view<_Vp>::_Iterator
6725 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6726 static constexpr bool _S_last_elt_present
6727 = __detail::__slide_caches_first<_Base>;
6729 iterator_t<_Base> _M_current = iterator_t<_Base>();
6730 [[no_unique_address]]
6731 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6732 _M_last_elt = decltype(_M_last_elt)();
6733 range_difference_t<_Base> _M_n = 0;
6736 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6737 requires (!_S_last_elt_present)
6738 : _M_current(__current), _M_n(__n)
6742 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6743 range_difference_t<_Base> __n)
6744 requires _S_last_elt_present
6745 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6751 if constexpr (random_access_range<_Base>)
6752 return random_access_iterator_tag{};
6753 else if constexpr (bidirectional_range<_Base>)
6754 return bidirectional_iterator_tag{};
6756 return forward_iterator_tag{};
6760 friend slide_view::_Sentinel;
6763 using iterator_category = input_iterator_tag;
6764 using iterator_concept = decltype(_S_iter_concept());
6765 using value_type = decltype(views::counted(_M_current, _M_n));
6766 using difference_type = range_difference_t<_Base>;
6768 _Iterator() = default;
6771 _Iterator(_Iterator<!_Const> __i)
6772 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6773 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6778 { return views::counted(_M_current, _M_n); }
6780 constexpr _Iterator&
6784 if constexpr (_S_last_elt_present)
6797 constexpr _Iterator&
6798 operator--() requires bidirectional_range<_Base>
6801 if constexpr (_S_last_elt_present)
6807 operator--(int) requires bidirectional_range<_Base>
6814 constexpr _Iterator&
6815 operator+=(difference_type __x)
6816 requires random_access_range<_Base>
6819 if constexpr (_S_last_elt_present)
6824 constexpr _Iterator&
6825 operator-=(difference_type __x)
6826 requires random_access_range<_Base>
6829 if constexpr (_S_last_elt_present)
6835 operator[](difference_type __n) const
6836 requires random_access_range<_Base>
6837 { return views::counted(_M_current + __n, _M_n); }
6839 friend constexpr bool
6840 operator==(const _Iterator& __x, const _Iterator& __y)
6842 if constexpr (_S_last_elt_present)
6843 return __x._M_last_elt == __y._M_last_elt;
6845 return __x._M_current == __y._M_current;
6848 friend constexpr bool
6849 operator<(const _Iterator& __x, const _Iterator& __y)
6850 requires random_access_range<_Base>
6851 { return __x._M_current < __y._M_current; }
6853 friend constexpr bool
6854 operator>(const _Iterator& __x, const _Iterator& __y)
6855 requires random_access_range<_Base>
6856 { return __y < __x; }
6858 friend constexpr bool
6859 operator<=(const _Iterator& __x, const _Iterator& __y)
6860 requires random_access_range<_Base>
6861 { return !(__y < __x); }
6863 friend constexpr bool
6864 operator>=(const _Iterator& __x, const _Iterator& __y)
6865 requires random_access_range<_Base>
6866 { return !(__x < __y); }
6868 friend constexpr auto
6869 operator<=>(const _Iterator& __x, const _Iterator& __y)
6870 requires random_access_range<_Base>
6871 && three_way_comparable<iterator_t<_Base>>
6872 { return __x._M_current <=> __y._M_current; }
6874 friend constexpr _Iterator
6875 operator+(const _Iterator& __i, difference_type __n)
6876 requires random_access_range<_Base>
6883 friend constexpr _Iterator
6884 operator+(difference_type __n, const _Iterator& __i)
6885 requires random_access_range<_Base>
6892 friend constexpr _Iterator
6893 operator-(const _Iterator& __i, difference_type __n)
6894 requires random_access_range<_Base>
6901 friend constexpr difference_type
6902 operator-(const _Iterator& __x, const _Iterator& __y)
6903 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6905 if constexpr (_S_last_elt_present)
6906 return __x._M_last_elt - __y._M_last_elt;
6908 return __x._M_current - __y._M_current;
6912 template<forward_range _Vp>
6914 class slide_view<_Vp>::_Sentinel
6916 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6919 _Sentinel(sentinel_t<_Vp> __end)
6926 _Sentinel() = default;
6928 friend constexpr bool
6929 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6930 { return __x._M_last_elt == __y._M_end; }
6932 friend constexpr range_difference_t<_Vp>
6933 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6934 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6935 { return __x._M_last_elt - __y._M_end; }
6937 friend constexpr range_difference_t<_Vp>
6938 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6939 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6940 { return __y._M_end -__x._M_last_elt; }
6947 template<typename _Range, typename _Dp>
6948 concept __can_slide_view
6949 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6952 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6954 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6955 requires __detail::__can_slide_view<_Range, _Dp>
6957 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6958 { return slide_view(std::forward<_Range>(__r), __n); }
6960 using __adaptor::_RangeAdaptor<_Slide>::operator();
6961 static constexpr int _S_arity = 2;
6962 static constexpr bool _S_has_simple_extra_args = true;
6965 inline constexpr _Slide slide;
6967#endif // __cpp_lib_ranges_slide
6969#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
6970 template<forward_range _Vp,
6971 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6972 requires view<_Vp> && is_object_v<_Pred>
6973 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6975 _Vp _M_base = _Vp();
6976 __detail::__box<_Pred> _M_pred;
6977 __detail::_CachedPosition<_Vp> _M_cached_begin;
6979 constexpr iterator_t<_Vp>
6980 _M_find_next(iterator_t<_Vp> __current)
6982 __glibcxx_assert(_M_pred.has_value());
6983 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6984 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6986 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6987 return ranges::next(__it, 1, ranges::end(_M_base));
6990 constexpr iterator_t<_Vp>
6991 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
6993 __glibcxx_assert(_M_pred.has_value());
6994 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6995 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
6997 auto __rbegin = std::make_reverse_iterator(__current);
6998 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
6999 __glibcxx_assert(__rbegin != __rend);
7000 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7001 return ranges::prev(__it, 1, ranges::begin(_M_base));
7007 chunk_by_view() requires (default_initializable<_Vp>
7008 && default_initializable<_Pred>)
7012 chunk_by_view(_Vp __base, _Pred __pred)
7013 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
7017 base() const & requires copy_constructible<_Vp>
7022 { return std::move(_M_base); }
7024 constexpr const _Pred&
7026 { return *_M_pred; }
7031 __glibcxx_assert(_M_pred.has_value());
7032 iterator_t<_Vp> __it;
7033 if (_M_cached_begin._M_has_value())
7034 __it = _M_cached_begin._M_get(_M_base);
7037 __it = _M_find_next(ranges::begin(_M_base));
7038 _M_cached_begin._M_set(_M_base, __it);
7040 return _Iterator(*this, ranges::begin(_M_base), __it);
7046 if constexpr (common_range<_Vp>)
7047 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
7049 return default_sentinel;
7053 template<typename _Range, typename _Pred>
7054 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7056 template<forward_range _Vp,
7057 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7058 requires view<_Vp> && is_object_v<_Pred>
7059 class chunk_by_view<_Vp, _Pred>::_Iterator
7061 chunk_by_view* _M_parent = nullptr;
7062 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7063 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7066 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7067 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7073 if constexpr (bidirectional_range<_Vp>)
7074 return bidirectional_iterator_tag{};
7076 return forward_iterator_tag{};
7079 friend chunk_by_view;
7082 using value_type = subrange<iterator_t<_Vp>>;
7083 using difference_type = range_difference_t<_Vp>;
7084 using iterator_category = input_iterator_tag;
7085 using iterator_concept = decltype(_S_iter_concept());
7087 _Iterator() = default;
7089 constexpr value_type
7092 __glibcxx_assert(_M_current != _M_next);
7093 return ranges::subrange(_M_current, _M_next);
7096 constexpr _Iterator&
7099 __glibcxx_assert(_M_current != _M_next);
7100 _M_current = _M_next;
7101 _M_next = _M_parent->_M_find_next(_M_current);
7113 constexpr _Iterator&
7114 operator--() requires bidirectional_range<_Vp>
7116 _M_next = _M_current;
7117 _M_current = _M_parent->_M_find_prev(_M_next);
7122 operator--(int) requires bidirectional_range<_Vp>
7129 friend constexpr bool
7130 operator==(const _Iterator& __x, const _Iterator& __y)
7131 { return __x._M_current == __y._M_current; }
7133 friend constexpr bool
7134 operator==(const _Iterator& __x, default_sentinel_t)
7135 { return __x._M_current == __x._M_next; }
7142 template<typename _Range, typename _Pred>
7143 concept __can_chunk_by_view
7144 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7147 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7149 template<viewable_range _Range, typename _Pred>
7150 requires __detail::__can_chunk_by_view<_Range, _Pred>
7152 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7153 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7155 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7156 static constexpr int _S_arity = 2;
7157 static constexpr bool _S_has_simple_extra_args = true;
7160 inline constexpr _ChunkBy chunk_by;
7162#endif // __cpp_lib_ranges_chunk_by
7164#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7167 template<typename _Range, typename _Pattern>
7168 concept __compatible_joinable_ranges
7169 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7170 && common_reference_with<range_reference_t<_Range>,
7171 range_reference_t<_Pattern>>
7172 && common_reference_with<range_rvalue_reference_t<_Range>,
7173 range_rvalue_reference_t<_Pattern>>;
7175 template<typename _Range>
7176 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7179 template<input_range _Vp, forward_range _Pattern>
7180 requires view<_Vp> && view<_Pattern>
7181 && input_range<range_reference_t<_Vp>>
7182 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7183 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7185 using _InnerRange = range_reference_t<_Vp>;
7187 _Vp _M_base = _Vp();
7188 [[no_unique_address]]
7189 __detail::__maybe_present_t<!forward_range<_Vp>,
7190 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7191 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7192 _Pattern _M_pattern = _Pattern();
7194 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7195 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7196 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7198 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7199 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7200 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7202 template<bool _Const>
7203 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7205 template<bool _Const>
7209 template<bool _Const>
7210 requires _S_ref_is_glvalue<_Const>
7211 && forward_range<_Base<_Const>>
7212 && forward_range<_InnerBase<_Const>>
7213 struct __iter_cat<_Const>
7219 using _OuterIter = join_with_view::_OuterIter<_Const>;
7220 using _InnerIter = join_with_view::_InnerIter<_Const>;
7221 using _PatternIter = join_with_view::_PatternIter<_Const>;
7222 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7223 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7224 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7225 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7226 // 3798. Rvalue reference and iterator_category
7227 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7228 iter_reference_t<_PatternIter>>>)
7229 return input_iterator_tag{};
7230 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7231 && derived_from<_InnerCat, bidirectional_iterator_tag>
7232 && derived_from<_PatternCat, bidirectional_iterator_tag>
7233 && common_range<_InnerBase<_Const>>
7234 && common_range<_PatternBase<_Const>>)
7235 return bidirectional_iterator_tag{};
7236 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7237 && derived_from<_InnerCat, forward_iterator_tag>
7238 && derived_from<_PatternCat, forward_iterator_tag>)
7239 return forward_iterator_tag{};
7241 return input_iterator_tag{};
7244 using iterator_category = decltype(_S_iter_cat());
7247 template<bool> class _Iterator;
7248 template<bool> class _Sentinel;
7251 join_with_view() requires (default_initializable<_Vp>
7252 && default_initializable<_Pattern>)
7256 join_with_view(_Vp __base, _Pattern __pattern)
7257 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7260 template<input_range _Range>
7261 requires constructible_from<_Vp, views::all_t<_Range>>
7262 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7264 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7265 : _M_base(views::all(std::forward<_Range>(__r))),
7266 _M_pattern(views::single(std::move(__e)))
7270 base() const& requires copy_constructible<_Vp>
7275 { return std::move(_M_base); }
7280 if constexpr (forward_range<_Vp>)
7282 constexpr bool __use_const = is_reference_v<_InnerRange>
7283 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7284 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7288 _M_outer_it = ranges::begin(_M_base);
7289 return _Iterator<false>{*this};
7295 requires forward_range<const _Vp>
7296 && forward_range<const _Pattern>
7297 && is_reference_v<range_reference_t<const _Vp>>
7298 && input_range<range_reference_t<const _Vp>>
7299 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7304 constexpr bool __use_const
7305 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7306 if constexpr (is_reference_v<_InnerRange>
7307 && forward_range<_Vp> && common_range<_Vp>
7308 && forward_range<_InnerRange> && common_range<_InnerRange>)
7309 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7311 return _Sentinel<__use_const>{*this};
7316 requires forward_range<const _Vp>
7317 && forward_range<const _Pattern>
7318 && is_reference_v<range_reference_t<const _Vp>>
7319 && input_range<range_reference_t<const _Vp>>
7321 using _InnerConstRange = range_reference_t<const _Vp>;
7322 if constexpr (forward_range<_InnerConstRange>
7323 && common_range<const _Vp>
7324 && common_range<_InnerConstRange>)
7325 return _Iterator<true>{*this, ranges::end(_M_base)};
7327 return _Sentinel<true>{*this};
7331 template<typename _Range, typename _Pattern>
7332 join_with_view(_Range&&, _Pattern&&)
7333 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7335 template<input_range _Range>
7336 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7337 -> join_with_view<views::all_t<_Range>,
7338 single_view<range_value_t<range_reference_t<_Range>>>>;
7340 template<input_range _Vp, forward_range _Pattern>
7341 requires view<_Vp> && view<_Pattern>
7342 && input_range<range_reference_t<_Vp>>
7343 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7344 template<bool _Const>
7345 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7347 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7348 using _Base = join_with_view::_Base<_Const>;
7349 using _InnerBase = join_with_view::_InnerBase<_Const>;
7350 using _PatternBase = join_with_view::_PatternBase<_Const>;
7352 using _OuterIter = join_with_view::_OuterIter<_Const>;
7353 using _InnerIter = join_with_view::_InnerIter<_Const>;
7354 using _PatternIter = join_with_view::_PatternIter<_Const>;
7356 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7358 _Parent* _M_parent = nullptr;
7359 [[no_unique_address]]
7360 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
7361 = decltype(_M_outer_it)();
7362 variant<_PatternIter, _InnerIter> _M_inner_it;
7364 constexpr _OuterIter&
7367 if constexpr (forward_range<_Base>)
7370 return *_M_parent->_M_outer_it;
7373 constexpr const _OuterIter&
7374 _M_get_outer() const
7376 if constexpr (forward_range<_Base>)
7379 return *_M_parent->_M_outer_it;
7383 _Iterator(_Parent& __parent, _OuterIter __outer)
7384 requires forward_range<_Base>
7385 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7387 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7389 auto&& __inner = _M_update_inner();
7390 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7396 _Iterator(_Parent& __parent)
7397 requires (!forward_range<_Base>)
7398 : _M_parent(std::__addressof(__parent))
7400 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7402 auto&& __inner = _M_update_inner();
7403 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7411 _OuterIter& __outer = _M_get_outer();
7412 if constexpr (_S_ref_is_glvalue)
7413 return __detail::__as_lvalue(*__outer);
7415 return _M_parent->_M_inner._M_emplace_deref(__outer);
7421 if constexpr (_S_ref_is_glvalue)
7422 return __detail::__as_lvalue(*_M_get_outer());
7424 return *_M_parent->_M_inner;
7432 if (_M_inner_it.index() == 0)
7434 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7437 auto&& __inner = _M_update_inner();
7438 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7442 auto&& __inner = _M_get_inner();
7443 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7446 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7448 if constexpr (_S_ref_is_glvalue)
7449 _M_inner_it.template emplace<0>();
7453 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7461 if constexpr (_S_ref_is_glvalue
7462 && bidirectional_range<_Base>
7463 && __detail::__bidirectional_common<_InnerBase>
7464 && __detail::__bidirectional_common<_PatternBase>)
7465 return bidirectional_iterator_tag{};
7466 else if constexpr (_S_ref_is_glvalue
7467 && forward_range<_Base>
7468 && forward_range<_InnerBase>)
7469 return forward_iterator_tag{};
7471 return input_iterator_tag{};
7474 friend join_with_view;
7477 using iterator_concept = decltype(_S_iter_concept());
7478 // iterator_category defined in join_with_view::__iter_cat
7479 using value_type = common_type_t<iter_value_t<_InnerIter>,
7480 iter_value_t<_PatternIter>>;
7481 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7482 iter_difference_t<_InnerIter>,
7483 iter_difference_t<_PatternIter>>;
7485 _Iterator() = default;
7488 _Iterator(_Iterator<!_Const> __i)
7490 && convertible_to<iterator_t<_Vp>, _OuterIter>
7491 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7492 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7493 : _M_parent(__i._M_parent),
7494 _M_outer_it(std::move(__i._M_outer_it))
7496 if (__i._M_inner_it.index() == 0)
7497 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7499 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7502 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7503 iter_reference_t<_PatternIter>>
7506 if (_M_inner_it.index() == 0)
7507 return *std::get<0>(_M_inner_it);
7509 return *std::get<1>(_M_inner_it);
7512 constexpr _Iterator&
7515 if (_M_inner_it.index() == 0)
7516 ++std::get<0>(_M_inner_it);
7518 ++std::get<1>(_M_inner_it);
7529 requires _S_ref_is_glvalue
7530 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7532 _Iterator __tmp = *this;
7537 constexpr _Iterator&
7539 requires _S_ref_is_glvalue
7540 && bidirectional_range<_Base>
7541 && __detail::__bidirectional_common<_InnerBase>
7542 && __detail::__bidirectional_common<_PatternBase>
7544 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7546 auto&& __inner = *--_M_outer_it;
7547 _M_inner_it.template emplace<1>(ranges::end(__inner));
7552 if (_M_inner_it.index() == 0)
7554 auto& __it = std::get<0>(_M_inner_it);
7555 if (__it == ranges::begin(_M_parent->_M_pattern))
7557 auto&& __inner = *--_M_outer_it;
7558 _M_inner_it.template emplace<1>(ranges::end(__inner));
7565 auto& __it = std::get<1>(_M_inner_it);
7566 auto&& __inner = *_M_outer_it;
7567 if (__it == ranges::begin(__inner))
7568 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7574 if (_M_inner_it.index() == 0)
7575 --std::get<0>(_M_inner_it);
7577 --std::get<1>(_M_inner_it);
7583 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7584 && __detail::__bidirectional_common<_InnerBase>
7585 && __detail::__bidirectional_common<_PatternBase>
7587 _Iterator __tmp = *this;
7592 friend constexpr bool
7593 operator==(const _Iterator& __x, const _Iterator& __y)
7594 requires _S_ref_is_glvalue
7595 && forward_range<_Base> && equality_comparable<_InnerIter>
7596 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7598 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7599 iter_rvalue_reference_t<_PatternIter>>
7600 iter_move(const _Iterator& __x)
7602 if (__x._M_inner_it.index() == 0)
7603 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7605 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7608 friend constexpr void
7609 iter_swap(const _Iterator& __x, const _Iterator& __y)
7610 requires indirectly_swappable<_InnerIter, _PatternIter>
7612 if (__x._M_inner_it.index() == 0)
7614 if (__y._M_inner_it.index() == 0)
7615 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7617 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7621 if (__y._M_inner_it.index() == 0)
7622 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7624 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7629 template<input_range _Vp, forward_range _Pattern>
7630 requires view<_Vp> && view<_Pattern>
7631 && input_range<range_reference_t<_Vp>>
7632 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7633 template<bool _Const>
7634 class join_with_view<_Vp, _Pattern>::_Sentinel
7636 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7637 using _Base = join_with_view::_Base<_Const>;
7639 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7642 _Sentinel(_Parent& __parent)
7643 : _M_end(ranges::end(__parent._M_base))
7646 friend join_with_view;
7649 _Sentinel() = default;
7652 _Sentinel(_Sentinel<!_Const> __s)
7653 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7654 : _M_end(std::move(__s._M_end))
7657 template<bool _OtherConst>
7658 requires sentinel_for<sentinel_t<_Base>,
7659 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7660 friend constexpr bool
7661 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7662 { return __x._M_get_outer() == __y._M_end; }
7669 template<typename _Range, typename _Pattern>
7670 concept __can_join_with_view
7671 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7672 } // namespace __detail
7674 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7676 template<viewable_range _Range, typename _Pattern>
7677 requires __detail::__can_join_with_view<_Range, _Pattern>
7679 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7681 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7684 using _RangeAdaptor<_JoinWith>::operator();
7685 static constexpr int _S_arity = 2;
7686 template<typename _Pattern>
7687 static constexpr bool _S_has_simple_extra_args
7688 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7691 inline constexpr _JoinWith join_with;
7692 } // namespace views
7693#endif // __cpp_lib_ranges_join_with
7695#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7696 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7697 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7698 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7699 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7701 __detail::__box<_Tp> _M_value;
7702 [[no_unique_address]] _Bound _M_bound = _Bound();
7706 template<typename _Range>
7707 friend constexpr auto
7708 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7710 template<typename _Range>
7711 friend constexpr auto
7712 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7715 repeat_view() requires default_initializable<_Tp> = default;
7718 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7719 requires copy_constructible<_Tp>
7720 : _M_value(__value), _M_bound(__bound)
7722 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7723 __glibcxx_assert(__bound >= 0);
7727 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7728 : _M_value(std::move(__value)), _M_bound(__bound)
7731 template<typename... _Args, typename... _BoundArgs>
7732 requires constructible_from<_Tp, _Args...>
7733 && constructible_from<_Bound, _BoundArgs...>
7735 repeat_view(piecewise_construct_t,
7736 tuple<_Args...> __args,
7737 tuple<_BoundArgs...> __bound_args = tuple<>{})
7738 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7739 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7744 { return _Iterator(std::__addressof(*_M_value)); }
7747 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7748 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7750 constexpr unreachable_sentinel_t
7751 end() const noexcept
7752 { return unreachable_sentinel; }
7755 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7756 { return __detail::__to_unsigned_like(_M_bound); }
7759 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7760 // 4053. Unary call to std::views::repeat does not decay the argument
7761 template<typename _Tp, typename _Bound = unreachable_sentinel_t>
7762 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7764 template<move_constructible _Tp, semiregular _Bound>
7765 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7766 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7767 class repeat_view<_Tp, _Bound>::_Iterator
7770 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7772 const _Tp* _M_value = nullptr;
7773 __index_type _M_current = __index_type();
7776 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7777 : _M_value(__value), _M_current(__bound)
7779 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7780 __glibcxx_assert(__bound >= 0);
7786 using iterator_concept = random_access_iterator_tag;
7787 using iterator_category = random_access_iterator_tag;
7788 using value_type = _Tp;
7789 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7791 __detail::__iota_diff_t<__index_type>>;
7793 _Iterator() = default;
7795 constexpr const _Tp&
7796 operator*() const noexcept
7797 { return *_M_value; }
7799 constexpr _Iterator&
7814 constexpr _Iterator&
7817 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7818 __glibcxx_assert(_M_current > 0);
7831 constexpr _Iterator&
7832 operator+=(difference_type __n)
7834 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7835 __glibcxx_assert(_M_current + __n >= 0);
7840 constexpr _Iterator&
7841 operator-=(difference_type __n)
7843 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7844 __glibcxx_assert(_M_current - __n >= 0);
7849 constexpr const _Tp&
7850 operator[](difference_type __n) const noexcept
7851 { return *(*this + __n); }
7853 friend constexpr bool
7854 operator==(const _Iterator& __x, const _Iterator& __y)
7855 { return __x._M_current == __y._M_current; }
7857 friend constexpr auto
7858 operator<=>(const _Iterator& __x, const _Iterator& __y)
7859 { return __x._M_current <=> __y._M_current; }
7861 friend constexpr _Iterator
7862 operator+(_Iterator __i, difference_type __n)
7868 friend constexpr _Iterator
7869 operator+(difference_type __n, _Iterator __i)
7870 { return __i + __n; }
7872 friend constexpr _Iterator
7873 operator-(_Iterator __i, difference_type __n)
7879 friend constexpr difference_type
7880 operator-(const _Iterator& __x, const _Iterator& __y)
7882 return (static_cast<difference_type>(__x._M_current)
7883 - static_cast<difference_type>(__y._M_current));
7891 template<typename _Tp, typename _Bound>
7892 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7894 template<typename _Tp>
7895 concept __can_repeat_view
7896 = requires { repeat_view(std::declval<_Tp>()); };
7898 template<typename _Tp, typename _Bound>
7899 concept __can_bounded_repeat_view
7900 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7905 template<typename _Tp>
7906 requires __detail::__can_repeat_view<_Tp>
7908 operator() [[nodiscard]] (_Tp&& __value) const
7910 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7911 // 4054. Repeating a repeat_view should repeat the view
7912 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7915 template<typename _Tp, typename _Bound>
7916 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7918 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7919 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7922 inline constexpr _Repeat repeat;
7926 template<typename _Range>
7928 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7930 using _Tp = remove_cvref_t<_Range>;
7931 static_assert(__is_repeat_view<_Tp>);
7932 if constexpr (sized_range<_Tp>)
7933 return views::repeat(*std::forward<_Range>(__r)._M_value,
7934 std::min(ranges::distance(__r), __n));
7936 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7939 template<typename _Range>
7941 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7943 using _Tp = remove_cvref_t<_Range>;
7944 static_assert(__is_repeat_view<_Tp>);
7945 if constexpr (sized_range<_Tp>)
7947 auto __sz = ranges::distance(__r);
7948 return views::repeat(*std::forward<_Range>(__r)._M_value,
7949 __sz - std::min(__sz, __n));
7956#endif // __cpp_lib_ranges_repeat
7958#ifdef __cpp_lib_ranges_stride // C++ >= 23
7959 template<input_range _Vp>
7961 class stride_view : public view_interface<stride_view<_Vp>>
7964 range_difference_t<_Vp> _M_stride;
7966 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7968 template<bool _Const>
7972 template<bool _Const>
7973 requires forward_range<_Base<_Const>>
7974 struct __iter_cat<_Const>
7980 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7981 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7982 return random_access_iterator_tag{};
7987 using iterator_category = decltype(_S_iter_cat());
7990 template<bool> class _Iterator;
7994 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7995 : _M_base(std::move(__base)), _M_stride(__stride)
7996 { __glibcxx_assert(__stride > 0); }
7999 base() const& requires copy_constructible<_Vp>
8004 { return std::move(_M_base); }
8006 constexpr range_difference_t<_Vp>
8007 stride() const noexcept
8008 { return _M_stride; }
8011 begin() requires (!__detail::__simple_view<_Vp>)
8012 { return _Iterator<false>(this, ranges::begin(_M_base)); }
8015 begin() const requires range<const _Vp>
8016 { return _Iterator<true>(this, ranges::begin(_M_base)); }
8019 end() requires (!__detail::__simple_view<_Vp>)
8021 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8023 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8024 return _Iterator<false>(this, ranges::end(_M_base), __missing);
8026 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8027 return _Iterator<false>(this, ranges::end(_M_base));
8029 return default_sentinel;
8033 end() const requires range<const _Vp>
8035 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8036 && forward_range<const _Vp>)
8038 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8039 return _Iterator<true>(this, ranges::end(_M_base), __missing);
8041 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8042 return _Iterator<true>(this, ranges::end(_M_base));
8044 return default_sentinel;
8048 size() requires sized_range<_Vp>
8050 return __detail::__to_unsigned_like
8051 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8055 size() const requires sized_range<const _Vp>
8057 return __detail::__to_unsigned_like
8058 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8062 template<typename _Range>
8063 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8065 template<typename _Vp>
8066 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8067 = enable_borrowed_range<_Vp>;
8069 template<input_range _Vp>
8071 template<bool _Const>
8072 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8074 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8075 using _Base = stride_view::_Base<_Const>;
8077 iterator_t<_Base> _M_current = iterator_t<_Base>();
8078 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8079 range_difference_t<_Base> _M_stride = 0;
8080 range_difference_t<_Base> _M_missing = 0;
8083 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8084 range_difference_t<_Base> __missing = 0)
8085 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8086 _M_stride(__parent->_M_stride), _M_missing(__missing)
8092 if constexpr (random_access_range<_Base>)
8093 return random_access_iterator_tag{};
8094 else if constexpr (bidirectional_range<_Base>)
8095 return bidirectional_iterator_tag{};
8096 else if constexpr (forward_range<_Base>)
8097 return forward_iterator_tag{};
8099 return input_iterator_tag{};
8105 using difference_type = range_difference_t<_Base>;
8106 using value_type = range_value_t<_Base>;
8107 using iterator_concept = decltype(_S_iter_concept());
8108 // iterator_category defined in stride_view::__iter_cat
8110 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8113 _Iterator(_Iterator<!_Const> __other)
8115 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8116 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8117 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8118 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8121 constexpr iterator_t<_Base>
8123 { return std::move(_M_current); }
8125 constexpr const iterator_t<_Base>&
8126 base() const & noexcept
8127 { return _M_current; }
8129 constexpr decltype(auto)
8131 { return *_M_current; }
8133 constexpr _Iterator&
8136 __glibcxx_assert(_M_current != _M_end);
8137 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8146 operator++(int) requires forward_range<_Base>
8153 constexpr _Iterator&
8154 operator--() requires bidirectional_range<_Base>
8156 ranges::advance(_M_current, _M_missing - _M_stride);
8162 operator--(int) requires bidirectional_range<_Base>
8169 constexpr _Iterator&
8170 operator+=(difference_type __n) requires random_access_range<_Base>
8174 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8175 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8179 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8185 constexpr _Iterator&
8186 operator-=(difference_type __n) requires random_access_range<_Base>
8187 { return *this += -__n; }
8189 constexpr decltype(auto) operator[](difference_type __n) const
8190 requires random_access_range<_Base>
8191 { return *(*this + __n); }
8193 friend constexpr bool
8194 operator==(const _Iterator& __x, default_sentinel_t)
8195 { return __x._M_current == __x._M_end; }
8197 friend constexpr bool
8198 operator==(const _Iterator& __x, const _Iterator& __y)
8199 requires equality_comparable<iterator_t<_Base>>
8200 { return __x._M_current == __y._M_current; }
8202 friend constexpr bool
8203 operator<(const _Iterator& __x, const _Iterator& __y)
8204 requires random_access_range<_Base>
8205 { return __x._M_current < __y._M_current; }
8207 friend constexpr bool
8208 operator>(const _Iterator& __x, const _Iterator& __y)
8209 requires random_access_range<_Base>
8210 { return __y._M_current < __x._M_current; }
8212 friend constexpr bool
8213 operator<=(const _Iterator& __x, const _Iterator& __y)
8214 requires random_access_range<_Base>
8215 { return !(__y._M_current < __x._M_current); }
8217 friend constexpr bool
8218 operator>=(const _Iterator& __x, const _Iterator& __y)
8219 requires random_access_range<_Base>
8220 { return !(__x._M_current < __y._M_current); }
8222 friend constexpr auto
8223 operator<=>(const _Iterator& __x, const _Iterator& __y)
8224 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8225 { return __x._M_current <=> __y._M_current; }
8227 friend constexpr _Iterator
8228 operator+(const _Iterator& __i, difference_type __n)
8229 requires random_access_range<_Base>
8236 friend constexpr _Iterator
8237 operator+(difference_type __n, const _Iterator& __i)
8238 requires random_access_range<_Base>
8239 { return __i + __n; }
8241 friend constexpr _Iterator
8242 operator-(const _Iterator& __i, difference_type __n)
8243 requires random_access_range<_Base>
8250 friend constexpr difference_type
8251 operator-(const _Iterator& __x, const _Iterator& __y)
8252 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8254 auto __n = __x._M_current - __y._M_current;
8255 if constexpr (forward_range<_Base>)
8256 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8258 return -__detail::__div_ceil(-__n, __x._M_stride);
8260 return __detail::__div_ceil(__n, __x._M_stride);
8263 friend constexpr difference_type
8264 operator-(default_sentinel_t, const _Iterator& __x)
8265 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8266 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8268 friend constexpr difference_type
8269 operator-(const _Iterator& __x, default_sentinel_t __y)
8270 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8271 { return -(__y - __x); }
8273 friend constexpr range_rvalue_reference_t<_Base>
8274 iter_move(const _Iterator& __i)
8275 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8276 { return ranges::iter_move(__i._M_current); }
8278 friend constexpr void
8279 iter_swap(const _Iterator& __x, const _Iterator& __y)
8280 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8281 requires indirectly_swappable<iterator_t<_Base>>
8282 { ranges::iter_swap(__x._M_current, __y._M_current); }
8289 template<typename _Range, typename _Dp>
8290 concept __can_stride_view
8291 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8294 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8296 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8297 requires __detail::__can_stride_view<_Range, _Dp>
8299 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8300 { return stride_view(std::forward<_Range>(__r), __n); }
8302 using __adaptor::_RangeAdaptor<_Stride>::operator();
8303 static constexpr int _S_arity = 2;
8304 static constexpr bool _S_has_simple_extra_args = true;
8307 inline constexpr _Stride stride;
8309#endif // __cpp_lib_ranges_stride
8311#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8314 template<bool _Const, typename _First, typename... _Vs>
8315 concept __cartesian_product_is_random_access
8316 = (random_access_range<__maybe_const_t<_Const, _First>>
8318 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8319 && sized_range<__maybe_const_t<_Const, _Vs>>));
8321 template<typename _Range>
8322 concept __cartesian_product_common_arg
8323 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8325 template<bool _Const, typename _First, typename... _Vs>
8326 concept __cartesian_product_is_bidirectional
8327 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8329 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8330 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8332 template<typename _First, typename... _Vs>
8333 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8335 template<typename... _Vs>
8336 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8338 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8339 concept __cartesian_is_sized_sentinel
8340 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8341 iterator_t<__maybe_const_t<_Const, _First>>>
8343 && (sized_range<__maybe_const_t<_Const, _Vs>>
8344 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8345 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8347 template<__cartesian_product_common_arg _Range>
8349 __cartesian_common_arg_end(_Range& __r)
8351 if constexpr (common_range<_Range>)
8352 return ranges::end(__r);
8354 return ranges::begin(__r) + ranges::distance(__r);
8356 } // namespace __detail
8358 template<input_range _First, forward_range... _Vs>
8359 requires (view<_First> && ... && view<_Vs>)
8360 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8362 tuple<_First, _Vs...> _M_bases;
8364 template<bool> class _Iterator;
8367 _S_difference_type()
8369 // TODO: Implement the recommended practice of using the smallest
8370 // sufficiently wide type according to the maximum sizes of the
8371 // underlying ranges?
8372 return common_type_t<ptrdiff_t,
8373 range_difference_t<_First>,
8374 range_difference_t<_Vs>...>{};
8378 cartesian_product_view() = default;
8381 cartesian_product_view(_First __first, _Vs... __rest)
8382 : _M_bases(std::move(__first), std::move(__rest)...)
8385 constexpr _Iterator<false>
8386 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8387 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8389 constexpr _Iterator<true>
8390 begin() const requires (range<const _First> && ... && range<const _Vs>)
8391 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8393 constexpr _Iterator<false>
8394 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8395 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8397 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8398 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8399 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8400 auto& __first = std::get<0>(_M_bases);
8401 return _Ret{(__empty_tail
8402 ? ranges::begin(__first)
8403 : __detail::__cartesian_common_arg_end(__first)),
8404 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8405 }(make_index_sequence<sizeof...(_Vs)>{});
8407 return _Iterator<false>{*this, std::move(__its)};
8410 constexpr _Iterator<true>
8411 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8413 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8414 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8415 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8416 auto& __first = std::get<0>(_M_bases);
8417 return _Ret{(__empty_tail
8418 ? ranges::begin(__first)
8419 : __detail::__cartesian_common_arg_end(__first)),
8420 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8421 }(make_index_sequence<sizeof...(_Vs)>{});
8423 return _Iterator<true>{*this, std::move(__its)};
8426 constexpr default_sentinel_t
8427 end() const noexcept
8428 { return default_sentinel; }
8431 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8433 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8434 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8435 auto __size = static_cast<_ST>(1);
8436#ifdef _GLIBCXX_ASSERTIONS
8437 if constexpr (integral<_ST>)
8440 = (__builtin_mul_overflow(__size,
8441 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8444 __glibcxx_assert(!__overflow);
8448 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8450 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8454 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8456 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8457 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8458 auto __size = static_cast<_ST>(1);
8459#ifdef _GLIBCXX_ASSERTIONS
8460 if constexpr (integral<_ST>)
8463 = (__builtin_mul_overflow(__size,
8464 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8467 __glibcxx_assert(!__overflow);
8471 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8473 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8477 template<typename... _Vs>
8478 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8480 template<input_range _First, forward_range... _Vs>
8481 requires (view<_First> && ... && view<_Vs>)
8482 template<bool _Const>
8483 class cartesian_product_view<_First, _Vs...>::_Iterator
8485 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8486 _Parent* _M_parent = nullptr;
8487 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8488 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8491 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8492 : _M_parent(std::__addressof(__parent)),
8493 _M_current(std::move(__current))
8499 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8500 return random_access_iterator_tag{};
8501 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8502 return bidirectional_iterator_tag{};
8503 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8504 return forward_iterator_tag{};
8506 return input_iterator_tag{};
8509 friend cartesian_product_view;
8512 using iterator_category = input_iterator_tag;
8513 using iterator_concept = decltype(_S_iter_concept());
8515 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8516 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8518 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8519 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8520 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8522 _Iterator() = default;
8525 _Iterator(_Iterator<!_Const> __i)
8527 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8528 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8529 : _M_parent(std::__addressof(__i._M_parent)),
8530 _M_current(std::move(__i._M_current))
8536 auto __f = [](auto& __i) -> decltype(auto) {
8539 return __detail::__tuple_transform(__f, _M_current);
8542 constexpr _Iterator&
8554 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8561 constexpr _Iterator&
8563 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8571 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8578 constexpr _Iterator&
8579 operator+=(difference_type __x)
8580 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8586 constexpr _Iterator&
8587 operator-=(difference_type __x)
8588 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8589 { return *this += -__x; }
8592 operator[](difference_type __n) const
8593 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8594 { return *((*this) + __n); }
8596 friend constexpr bool
8597 operator==(const _Iterator& __x, const _Iterator& __y)
8598 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8599 { return __x._M_current == __y._M_current; }
8601 friend constexpr bool
8602 operator==(const _Iterator& __x, default_sentinel_t)
8604 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8605 return ((std::get<_Is>(__x._M_current)
8606 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8608 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8611 friend constexpr auto
8612 operator<=>(const _Iterator& __x, const _Iterator& __y)
8613 requires __detail::__all_random_access<_Const, _First, _Vs...>
8614 { return __x._M_current <=> __y._M_current; }
8616 friend constexpr _Iterator
8617 operator+(_Iterator __x, difference_type __y)
8618 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8619 { return __x += __y; }
8621 friend constexpr _Iterator
8622 operator+(difference_type __x, _Iterator __y)
8623 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8624 { return __y += __x; }
8626 friend constexpr _Iterator
8627 operator-(_Iterator __x, difference_type __y)
8628 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8629 { return __x -= __y; }
8631 friend constexpr difference_type
8632 operator-(const _Iterator& __x, const _Iterator& __y)
8633 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8634 { return __x._M_distance_from(__y._M_current); }
8636 friend constexpr difference_type
8637 operator-(const _Iterator& __i, default_sentinel_t)
8638 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8640 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8641 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8642 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8643 }(make_index_sequence<sizeof...(_Vs)>{});
8644 return __i._M_distance_from(__end_tuple);
8647 friend constexpr difference_type
8648 operator-(default_sentinel_t, const _Iterator& __i)
8649 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8650 { return -(__i - default_sentinel); }
8652 friend constexpr auto
8653 iter_move(const _Iterator& __i)
8654 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8656 friend constexpr void
8657 iter_swap(const _Iterator& __l, const _Iterator& __r)
8658 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8660 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8662 [&]<size_t... _Is>(index_sequence<_Is...>) {
8663 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8664 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8668 template<size_t _Nm = sizeof...(_Vs)>
8672 auto& __it = std::get<_Nm>(_M_current);
8674 if constexpr (_Nm > 0)
8675 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8677 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8682 template<size_t _Nm = sizeof...(_Vs)>
8686 auto& __it = std::get<_Nm>(_M_current);
8687 if constexpr (_Nm > 0)
8688 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8690 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8696 template<size_t _Nm = sizeof...(_Vs)>
8698 _M_advance(difference_type __x)
8699 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8707 // Constant time iterator advancement.
8708 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8709 auto& __it = std::get<_Nm>(_M_current);
8710 if constexpr (_Nm == 0)
8712#ifdef _GLIBCXX_ASSERTIONS
8713 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8715 auto __size = ranges::ssize(__r);
8716 auto __begin = ranges::begin(__r);
8717 auto __offset = __it - __begin;
8718 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8725 auto __size = ranges::ssize(__r);
8726 auto __begin = ranges::begin(__r);
8727 auto __offset = __it - __begin;
8729 __x = __offset / __size;
8733 __offset = __size + __offset;
8736 __it = __begin + __offset;
8737 _M_advance<_Nm - 1>(__x);
8742 template<typename _Tuple>
8743 constexpr difference_type
8744 _M_distance_from(const _Tuple& __t) const
8746 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8747 auto __sum = static_cast<difference_type>(0);
8748#ifdef _GLIBCXX_ASSERTIONS
8749 if constexpr (integral<difference_type>)
8752 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8754 __glibcxx_assert(!__overflow);
8758 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8760 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8763 template<size_t _Nm, typename _Tuple>
8764 constexpr difference_type
8765 _M_scaled_distance(const _Tuple& __t) const
8767 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8768 - std::get<_Nm>(__t));
8769#ifdef _GLIBCXX_ASSERTIONS
8770 if constexpr (integral<difference_type>)
8772 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8773 __glibcxx_assert(!__overflow);
8777 __dist *= _M_scaled_size<_Nm+1>();
8781 template<size_t _Nm>
8782 constexpr difference_type
8783 _M_scaled_size() const
8785 if constexpr (_Nm <= sizeof...(_Vs))
8787 auto __size = static_cast<difference_type>(ranges::size
8788 (std::get<_Nm>(_M_parent->_M_bases)));
8789#ifdef _GLIBCXX_ASSERTIONS
8790 if constexpr (integral<difference_type>)
8792 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8793 __glibcxx_assert(!__overflow);
8797 __size *= _M_scaled_size<_Nm+1>();
8801 return static_cast<difference_type>(1);
8809 template<typename... _Ts>
8810 concept __can_cartesian_product_view
8811 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8814 struct _CartesianProduct
8816 template<typename... _Ts>
8817 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8819 operator() [[nodiscard]] (_Ts&&... __ts) const
8821 if constexpr (sizeof...(_Ts) == 0)
8822 return views::single(tuple{});
8824 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8828 inline constexpr _CartesianProduct cartesian_product;
8830#endif // __cpp_lib_ranges_cartesian_product
8832#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8833 template<input_range _Vp>
8835 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8837 _Vp _M_base = _Vp();
8840 as_rvalue_view() requires default_initializable<_Vp> = default;
8843 as_rvalue_view(_Vp __base)
8844 : _M_base(std::move(__base))
8848 base() const& requires copy_constructible<_Vp>
8853 { return std::move(_M_base); }
8856 begin() requires (!__detail::__simple_view<_Vp>)
8857 { return move_iterator(ranges::begin(_M_base)); }
8860 begin() const requires range<const _Vp>
8861 { return move_iterator(ranges::begin(_M_base)); }
8864 end() requires (!__detail::__simple_view<_Vp>)
8866 if constexpr (common_range<_Vp>)
8867 return move_iterator(ranges::end(_M_base));
8869 return move_sentinel(ranges::end(_M_base));
8873 end() const requires range<const _Vp>
8875 if constexpr (common_range<const _Vp>)
8876 return move_iterator(ranges::end(_M_base));
8878 return move_sentinel(ranges::end(_M_base));
8882 size() requires sized_range<_Vp>
8883 { return ranges::size(_M_base); }
8886 size() const requires sized_range<const _Vp>
8887 { return ranges::size(_M_base); }
8890 template<typename _Range>
8891 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8893 template<typename _Tp>
8894 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8895 = enable_borrowed_range<_Tp>;
8901 template<typename _Tp>
8902 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8905 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8907 template<viewable_range _Range>
8908 requires __detail::__can_as_rvalue_view<_Range>
8910 operator() [[nodiscard]] (_Range&& __r) const
8912 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8913 range_reference_t<_Range>>)
8914 return views::all(std::forward<_Range>(__r));
8916 return as_rvalue_view(std::forward<_Range>(__r));
8920 inline constexpr _AsRvalue as_rvalue;
8922#endif // __cpp_lib_as_rvalue
8924#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8927 template<typename _Range>
8928 concept __range_with_movable_reference = input_range<_Range>
8929 && move_constructible<range_reference_t<_Range>>
8930 && move_constructible<range_rvalue_reference_t<_Range>>;
8934 requires __detail::__range_with_movable_reference<_Vp>
8935 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8937 _Vp _M_base = _Vp();
8939 template<bool _Const> class _Iterator;
8940 template<bool _Const> class _Sentinel;
8943 enumerate_view() requires default_initializable<_Vp> = default;
8946 enumerate_view(_Vp __base)
8947 : _M_base(std::move(__base))
8951 begin() requires (!__detail::__simple_view<_Vp>)
8952 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8955 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8956 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8959 end() requires (!__detail::__simple_view<_Vp>)
8961 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8962 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8964 return _Sentinel<false>(ranges::end(_M_base));
8968 end() const requires __detail::__range_with_movable_reference<const _Vp>
8970 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8971 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8973 return _Sentinel<true>(ranges::end(_M_base));
8977 size() requires sized_range<_Vp>
8978 { return ranges::size(_M_base); }
8981 size() const requires sized_range<const _Vp>
8982 { return ranges::size(_M_base); }
8985 base() const & requires copy_constructible<_Vp>
8990 { return std::move(_M_base); }
8993 template<typename _Range>
8994 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
8996 template<typename _Tp>
8997 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
8998 = enable_borrowed_range<_Tp>;
9001 requires __detail::__range_with_movable_reference<_Vp>
9002 template<bool _Const>
9003 class enumerate_view<_Vp>::_Iterator
9005 using _Base = __maybe_const_t<_Const, _Vp>;
9010 if constexpr (random_access_range<_Base>)
9011 return random_access_iterator_tag{};
9012 else if constexpr (bidirectional_range<_Base>)
9013 return bidirectional_iterator_tag{};
9014 else if constexpr (forward_range<_Base>)
9015 return forward_iterator_tag{};
9017 return input_iterator_tag{};
9020 friend enumerate_view;
9023 using iterator_category = input_iterator_tag;
9024 using iterator_concept = decltype(_S_iter_concept());
9025 using difference_type = range_difference_t<_Base>;
9026 using value_type = tuple<difference_type, range_value_t<_Base>>;
9029 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9031 iterator_t<_Base> _M_current = iterator_t<_Base>();
9032 difference_type _M_pos = 0;
9035 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9036 : _M_current(std::move(__current)), _M_pos(__pos)
9040 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
9043 _Iterator(_Iterator<!_Const> __i)
9044 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9045 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9048 constexpr const iterator_t<_Base> &
9049 base() const & noexcept
9050 { return _M_current; }
9052 constexpr iterator_t<_Base>
9054 { return std::move(_M_current); }
9056 constexpr difference_type
9057 index() const noexcept
9062 { return __reference_type(_M_pos, *_M_current); }
9064 constexpr _Iterator&
9077 operator++(int) requires forward_range<_Base>
9084 constexpr _Iterator&
9085 operator--() requires bidirectional_range<_Base>
9093 operator--(int) requires bidirectional_range<_Base>
9100 constexpr _Iterator&
9101 operator+=(difference_type __n) requires random_access_range<_Base>
9108 constexpr _Iterator&
9109 operator-=(difference_type __n) requires random_access_range<_Base>
9117 operator[](difference_type __n) const requires random_access_range<_Base>
9118 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9120 friend constexpr bool
9121 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9122 { return __x._M_pos == __y._M_pos; }
9124 friend constexpr strong_ordering
9125 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9126 { return __x._M_pos <=> __y._M_pos; }
9128 friend constexpr _Iterator
9129 operator+(const _Iterator& __x, difference_type __y)
9130 requires random_access_range<_Base>
9131 { return (auto(__x) += __y); }
9133 friend constexpr _Iterator
9134 operator+(difference_type __x, const _Iterator& __y)
9135 requires random_access_range<_Base>
9136 { return auto(__y) += __x; }
9138 friend constexpr _Iterator
9139 operator-(const _Iterator& __x, difference_type __y)
9140 requires random_access_range<_Base>
9141 { return auto(__x) -= __y; }
9143 friend constexpr difference_type
9144 operator-(const _Iterator& __x, const _Iterator& __y) noexcept
9145 { return __x._M_pos - __y._M_pos; }
9147 friend constexpr auto
9148 iter_move(const _Iterator& __i)
9149 noexcept(noexcept(ranges::iter_move(__i._M_current))
9150 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9152 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9153 (__i._M_pos, ranges::iter_move(__i._M_current));
9158 requires __detail::__range_with_movable_reference<_Vp>
9159 template<bool _Const>
9160 class enumerate_view<_Vp>::_Sentinel
9162 using _Base = __maybe_const_t<_Const, _Vp>;
9164 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9167 _Sentinel(sentinel_t<_Base> __end)
9168 : _M_end(std::move(__end))
9171 friend enumerate_view;
9174 _Sentinel() = default;
9177 _Sentinel(_Sentinel<!_Const> __other)
9178 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9179 : _M_end(std::move(__other._M_end))
9182 constexpr sentinel_t<_Base>
9186 template<bool _OtherConst>
9187 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9188 friend constexpr bool
9189 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9190 { return __x._M_current == __y._M_end; }
9192 template<bool _OtherConst>
9193 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9194 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9195 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9196 { return __x._M_current - __y._M_end; }
9198 template<bool _OtherConst>
9199 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9200 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9201 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9202 { return __x._M_end - __y._M_current; }
9209 template<typename _Tp>
9210 concept __can_enumerate_view
9211 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9214 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9216 template<viewable_range _Range>
9217 requires __detail::__can_enumerate_view<_Range>
9219 operator() [[nodiscard]] (_Range&& __r) const
9220 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9223 inline constexpr _Enumerate enumerate;
9225#endif // __cpp_lib_ranges_enumerate
9227#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9229 requires input_range<_Vp>
9230 class as_const_view : public view_interface<as_const_view<_Vp>>
9232 _Vp _M_base = _Vp();
9235 as_const_view() requires default_initializable<_Vp> = default;
9238 as_const_view(_Vp __base)
9239 noexcept(is_nothrow_move_constructible_v<_Vp>)
9240 : _M_base(std::move(__base))
9245 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9246 requires copy_constructible<_Vp>
9251 noexcept(is_nothrow_move_constructible_v<_Vp>)
9252 { return std::move(_M_base); }
9255 begin() requires (!__detail::__simple_view<_Vp>)
9256 { return ranges::cbegin(_M_base); }
9259 begin() const requires range<const _Vp>
9260 { return ranges::cbegin(_M_base); }
9263 end() requires (!__detail::__simple_view<_Vp>)
9264 { return ranges::cend(_M_base); }
9267 end() const requires range<const _Vp>
9268 { return ranges::cend(_M_base); }
9271 size() requires sized_range<_Vp>
9272 { return ranges::size(_M_base); }
9275 size() const requires sized_range<const _Vp>
9276 { return ranges::size(_M_base); }
9279 template<typename _Range>
9280 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9282 template<typename _Tp>
9283 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9284 = enable_borrowed_range<_Tp>;
9290 template<typename _Tp>
9291 inline constexpr bool __is_constable_ref_view = false;
9293 template<typename _Range>
9294 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9295 = constant_range<const _Range>;
9297 template<typename _Range>
9298 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9301 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9303 template<viewable_range _Range>
9305 operator()(_Range&& __r) const
9306 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9307 requires __detail::__can_as_const_view<_Range>
9309 using _Tp = remove_cvref_t<_Range>;
9310 using element_type = remove_reference_t<range_reference_t<_Range>>;
9311 if constexpr (constant_range<views::all_t<_Range>>)
9312 return views::all(std::forward<_Range>(__r));
9313 else if constexpr (__detail::__is_empty_view<_Tp>)
9314 return views::empty<const element_type>;
9315 else if constexpr (std::__detail::__is_span<_Tp>)
9316 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9317 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9318 return ref_view(std::as_const(std::forward<_Range>(__r).base()));
9319 else if constexpr (is_lvalue_reference_v<_Range>
9320 && constant_range<const _Tp>
9322 return ref_view(static_cast<const _Tp&>(__r));
9324 return as_const_view(std::forward<_Range>(__r));
9328 inline constexpr _AsConst as_const;
9330#endif // __cpp_lib_as_const
9331} // namespace ranges
9333 namespace views = ranges::views;
9335#if __cpp_lib_ranges_to_container // C++ >= 23
9338/// @cond undocumented
9341 template<typename _Container>
9342 constexpr bool __reservable_container
9343 = sized_range<_Container>
9344 && requires(_Container& __c, range_size_t<_Container> __n) {
9346 { __c.capacity() } -> same_as<decltype(__n)>;
9347 { __c.max_size() } -> same_as<decltype(__n)>;
9350 template<typename _Cont, typename _Range>
9351 constexpr bool __toable = requires {
9352 requires (!input_range<_Cont>
9353 || convertible_to<range_reference_t<_Range>,
9354 range_value_t<_Cont>>);
9356} // namespace __detail
9359 /// Convert a range to a container.
9361 * @tparam _Cont A container type.
9362 * @param __r A range that models the `input_range` concept.
9363 * @param __args... Arguments to pass to the container constructor.
9366 * This function converts a range to the `_Cont` type.
9368 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9369 * will convert the view to `std::vector<int>`.
9371 * Additional constructor arguments for the container can be supplied after
9372 * the input range argument, e.g.
9373 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9375 template<typename _Cont, input_range _Rg, typename... _Args>
9376 requires (!view<_Cont>)
9378 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9380 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9381 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9383 if constexpr (__detail::__toable<_Cont, _Rg>)
9385 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9386 return _Cont(std::forward<_Rg>(__r),
9387 std::forward<_Args>(__args)...);
9388 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9389 return _Cont(from_range, std::forward<_Rg>(__r),
9390 std::forward<_Args>(__args)...);
9391 else if constexpr (requires { requires common_range<_Rg>;
9392 typename __iter_category_t<iterator_t<_Rg>>;
9393 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9394 input_iterator_tag>;
9395 requires constructible_from<_Cont, iterator_t<_Rg>,
9396 sentinel_t<_Rg>, _Args...>;
9398 return _Cont(ranges::begin(__r), ranges::end(__r),
9399 std::forward<_Args>(__args)...);
9402 static_assert(constructible_from<_Cont, _Args...>);
9403 _Cont __c(std::forward<_Args>(__args)...);
9404 if constexpr (sized_range<_Rg>
9405 && __detail::__reservable_container<_Cont>)
9406 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9407 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9408 // 4016. container-insertable checks do not match what
9409 // container-inserter does
9410 auto __it = ranges::begin(__r);
9411 const auto __sent = ranges::end(__r);
9412 while (__it != __sent)
9414 if constexpr (requires { __c.emplace_back(*__it); })
9415 __c.emplace_back(*__it);
9416 else if constexpr (requires { __c.push_back(*__it); })
9417 __c.push_back(*__it);
9418 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9419 __c.emplace(__c.end(), *__it);
9421 __c.insert(__c.end(), *__it);
9429 static_assert(input_range<range_reference_t<_Rg>>);
9430 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9431 // 3984. ranges::to's recursion branch may be ill-formed
9432 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9433 []<typename _Elt>(_Elt&& __elem) {
9434 using _ValT = range_value_t<_Cont>;
9435 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9436 }), std::forward<_Args>(__args)...);
9440/// @cond undocumented
9443 template<typename _Rg>
9446 using iterator_category = input_iterator_tag;
9447 using value_type = range_value_t<_Rg>;
9448 using difference_type = ptrdiff_t;
9449 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9450 using reference = range_reference_t<_Rg>;
9451 reference operator*() const;
9452 pointer operator->() const;
9453 _InputIter& operator++();
9454 _InputIter operator++(int);
9455 bool operator==(const _InputIter&) const;
9458 template<template<typename...> typename _Cont, input_range _Rg,
9461 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9463 template<template<typename...> typename _Cont, input_range _Rg,
9466 = decltype(_Cont(from_range, std::declval<_Rg>(),
9467 std::declval<_Args>()...));
9469 template<template<typename...> typename _Cont, input_range _Rg,
9472 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9473 std::declval<_InputIter<_Rg>>(),
9474 std::declval<_Args>()...));
9476} // namespace __detail
9479 template<template<typename...> typename _Cont, input_range _Rg,
9482 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9484 using __detail::_DeduceExpr1;
9485 using __detail::_DeduceExpr2;
9486 using __detail::_DeduceExpr3;
9487 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9488 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9489 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9490 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9491 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9492 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9493 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9494 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9495 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9497 static_assert(false); // Cannot deduce container specialization.
9500/// @cond undocumented
9503 template<typename _Cont>
9506 template<typename _Range, typename... _Args>
9507 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9508 std::declval<_Args>()...); }
9510 operator()(_Range&& __r, _Args&&... __args) const
9512 return ranges::to<_Cont>(std::forward<_Range>(__r),
9513 std::forward<_Args>(__args)...);
9516} // namespace __detail
9519 /// ranges::to adaptor for converting a range to a container type
9521 * @tparam _Cont A container type.
9522 * @param __args... Arguments to pass to the container constructor.
9525 * This range adaptor returns a range adaptor closure object that converts
9526 * a range to the `_Cont` type.
9528 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9529 * will convert the view to `std::vector<int>`.
9531 * Additional constructor arguments for the container can be supplied, e.g.
9532 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9534 template<typename _Cont, typename... _Args>
9535 requires (!view<_Cont>)
9537 to [[nodiscard]] (_Args&&... __args)
9539 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9540 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9542 using __detail::_To;
9543 using views::__adaptor::_Partial;
9544 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9547/// @cond undocumented
9550 template<template<typename...> typename _Cont>
9553 template<typename _Range, typename... _Args>
9554 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9555 std::declval<_Args>()...); }
9557 operator()(_Range&& __r, _Args&&... __args) const
9559 return ranges::to<_Cont>(std::forward<_Range>(__r),
9560 std::forward<_Args>(__args)...);
9563} // namespace __detail
9566 /// ranges::to adaptor for converting a range to a deduced container type.
9568 * @tparam _Cont A container template.
9569 * @param __args... Arguments to pass to the container constructor.
9572 * This range adaptor returns a range adaptor closure object that converts
9573 * a range to a specialization of the `_Cont` class template. The specific
9574 * specialization of `_Cont` to be used is deduced automatically.
9576 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9577 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9578 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9580 * Additional constructor arguments for the container can be supplied, e.g.
9581 * `r | std::ranges::to<std::vector>(an_allocator)`.
9583 template<template<typename...> typename _Cont, typename... _Args>
9585 to [[nodiscard]] (_Args&&... __args)
9587 using __detail::_To2;
9588 using views::__adaptor::_Partial;
9589 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9592} // namespace ranges
9593#endif // __cpp_lib_ranges_to_container
9595#if __cpp_lib_ranges_concat // C++ >= C++26
9600 template<typename... _Rs>
9601 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9603 template<typename... _Rs>
9604 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9606 template<typename... _Rs>
9607 using __concat_rvalue_reference_t
9608 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9610 template<typename _Ref, typename _RRef, typename _It>
9611 concept __concat_indirectly_readable_impl = requires(const _It __it) {
9612 { *__it } -> convertible_to<_Ref>;
9613 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9616 template<typename... _Rs>
9617 concept __concat_indirectly_readable
9618 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9619 && common_reference_with<__concat_reference_t<_Rs...>&&,
9620 __concat_rvalue_reference_t<_Rs...>&&>
9621 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9622 __concat_value_t<_Rs...> const&>
9623 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9624 __concat_rvalue_reference_t<_Rs...>,
9628 template<typename... _Rs>
9629 concept __concatable = requires {
9630 typename __concat_reference_t<_Rs...>;
9631 typename __concat_value_t<_Rs...>;
9632 typename __concat_rvalue_reference_t<_Rs...>;
9633 } && __concat_indirectly_readable<_Rs...>;
9635 template<bool _Const, typename _Range, typename... _Rs>
9636 struct __all_but_last_common
9638 static inline constexpr bool value
9639 = requires { requires (common_range<__maybe_const_t<_Const, _Range>>
9640 && __all_but_last_common<_Const, _Rs...>::value); };
9643 template<bool _Const, typename _Range>
9644 struct __all_but_last_common<_Const, _Range>
9645 { static inline constexpr bool value = true; };
9647 template<bool _Const, typename... _Rs>
9648 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9649 && __all_but_last_common<_Const, _Rs...>::value;
9651 template<bool _Const, typename... _Rs>
9652 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9653 && __all_but_last_common<_Const, _Rs...>::value;
9655 template<typename _Range, typename... _Rs>
9656 struct __all_but_first_sized
9657 { static inline constexpr bool value = (sized_range<_Rs> && ...); };
9658 } // namespace __detail
9660 template<input_range... _Vs>
9661 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9662 class concat_view : public view_interface<concat_view<_Vs...>>
9664 tuple<_Vs...> _M_views;
9666 template<bool _Const> class _Iterator;
9669 constexpr concat_view() = default;
9672 concat_view(_Vs... __views)
9673 : _M_views(std::move(__views)...)
9676 constexpr _Iterator<false>
9677 begin() requires (!(__detail::__simple_view<_Vs> && ...))
9679 _Iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9680 __it.template _M_satisfy<0>();
9684 constexpr _Iterator<true>
9685 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9687 _Iterator<true> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9688 __it.template _M_satisfy<0>();
9693 end() requires (!(__detail::__simple_view<_Vs> && ...))
9695 constexpr auto __n = sizeof...(_Vs);
9696 if constexpr (__detail::__all_forward<false, _Vs...>
9697 && common_range<_Vs...[__n - 1]>)
9698 return _Iterator<false>(this, in_place_index<__n - 1>,
9699 ranges::end(std::get<__n - 1>(_M_views)));
9701 return default_sentinel;
9705 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9707 constexpr auto __n = sizeof...(_Vs);
9708 if constexpr (__detail::__all_forward<true, _Vs...>
9709 && common_range<const _Vs...[__n - 1]>)
9710 return _Iterator<true>(this, in_place_index<__n - 1>,
9711 ranges::end(std::get<__n - 1>(_M_views)));
9713 return default_sentinel;
9717 size() requires (sized_range<_Vs>&&...)
9719 return std::apply([](auto... __sizes) {
9720 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9721 return (_CT(__sizes) + ...);
9722 }, __detail::__tuple_transform(ranges::size, _M_views));
9726 size() const requires (sized_range<const _Vs>&&...)
9728 return std::apply([](auto... __sizes) {
9729 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9730 return (_CT(__sizes) + ...);
9731 }, __detail::__tuple_transform(ranges::size, _M_views));
9735 template<typename... _Rs>
9736 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9740 template<bool _Const, typename... _Vs>
9741 struct __concat_view_iter_cat
9744 template<bool _Const, typename... _Vs>
9745 requires __detail::__all_forward<_Const, _Vs...>
9746 struct __concat_view_iter_cat<_Const, _Vs...>
9751 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9752 return input_iterator_tag{};
9754 return []<typename... _Cats>(_Cats... __cats) {
9755 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9756 && __concat_is_random_access<_Const, _Vs...>)
9757 return random_access_iterator_tag{};
9758 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9759 && __concat_is_bidirectional<_Const, _Vs...>)
9760 return bidirectional_iterator_tag{};
9761 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9762 return forward_iterator_tag{};
9764 return input_iterator_tag{};
9765 }(typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9766 ::iterator_category{}...);
9771 template<input_range... _Vs>
9772 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9773 template<bool _Const>
9774 class concat_view<_Vs...>::_Iterator
9775 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9780 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9781 return random_access_iterator_tag{};
9782 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9783 return bidirectional_iterator_tag{};
9784 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9785 return forward_iterator_tag{};
9787 return input_iterator_tag{};
9791 friend _Iterator<!_Const>;
9794 // iterator_category defined in __concat_view_iter_cat
9795 using iterator_concept = decltype(_S_iter_concept());
9796 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9797 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9800 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9802 __maybe_const_t<_Const, concat_view>* _M_parent = nullptr;
9805 template<size_t _Nm>
9809 if constexpr (_Nm < (sizeof...(_Vs) - 1))
9811 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9813 _M_it.template emplace<_Nm + 1>(ranges::begin
9814 (std::get<_Nm + 1>(_M_parent->_M_views)));
9815 _M_satisfy<_Nm + 1>();
9820 template<size_t _Nm>
9824 if constexpr (_Nm == 0)
9825 --std::get<0>(_M_it);
9828 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
9830 _M_it.template emplace<_Nm - 1>(ranges::end
9831 (std::get<_Nm - 1>(_M_parent->_M_views)));
9835 --std::get<_Nm>(_M_it);
9839 template<size_t _Nm>
9841 _M_advance_fwd(difference_type __offset, difference_type __steps)
9843 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9844 if constexpr (_Nm == sizeof...(_Vs) - 1)
9845 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9848 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
9849 if (__offset + __steps < __n_size)
9850 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9853 _M_it.template emplace<_Nm + 1>(ranges::begin
9854 (std::get<_Nm + 1>(_M_parent->_M_views)));
9855 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
9860 template<size_t _Nm>
9862 _M_advance_bwd(difference_type __offset, difference_type __steps)
9864 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9865 if constexpr (_Nm == 0)
9866 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9868 if (__offset >= __steps)
9869 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9872 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
9873 _M_it.template emplace<_Nm - 1>(ranges::end
9874 (std::get<_Nm - 1>(_M_parent->_M_views)));
9875 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
9880 // Invoke the function object __f, which has a call operator with a size_t
9881 // template parameter (corresponding to an index into the pack of views),
9882 // using the runtime value of __index as the template argument.
9883 template<typename _Fp>
9884 static constexpr auto
9885 _S_invoke_with_runtime_index(_Fp&& __f, size_t __index)
9887 return [&__f, __index]<size_t _Idx>(this auto&& __self) {
9888 if (_Idx == __index)
9889 return __f.template operator()<_Idx>();
9890 if constexpr (_Idx + 1 < sizeof...(_Vs))
9891 return __self.template operator()<_Idx + 1>();
9892 __builtin_unreachable();
9893 }.template operator()<0>();
9896 template<typename _Fp>
9898 _M_invoke_with_runtime_index(_Fp&& __f)
9899 { return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); }
9901 template<typename... _Args>
9903 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
9904 requires constructible_from<__base_iter, _Args&&...>
9905 : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...)
9909 _Iterator() = default;
9912 _Iterator(_Iterator<!_Const> __it)
9913 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
9914 : _M_parent(__it._M_parent),
9915 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
9916 return __base_iter(in_place_index<_Idx>,
9917 std::get<_Idx>(std::move(__it._M_it)));
9918 }, __it._M_it.index()))
9921 constexpr decltype(auto)
9924 __glibcxx_assert(!_M_it.valueless_by_exception());
9925 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
9926 return std::visit([](auto&& __it) -> reference { return *__it; }, _M_it);
9929 constexpr _Iterator&
9932 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9933 ++std::get<_Idx>(_M_it);
9945 requires __detail::__all_forward<_Const, _Vs...>
9952 constexpr _Iterator&
9954 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9956 __glibcxx_assert(!_M_it.valueless_by_exception());
9957 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9965 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9972 constexpr _Iterator&
9973 operator+=(difference_type __n)
9974 requires __detail::__concat_is_random_access<_Const, _Vs...>
9976 __glibcxx_assert(!_M_it.valueless_by_exception());
9977 _M_invoke_with_runtime_index([this, __n]<size_t _Idx>() {
9978 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
9980 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
9982 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
9987 constexpr _Iterator&
9988 operator-=(difference_type __n)
9989 requires __detail::__concat_is_random_access<_Const, _Vs...>
9995 constexpr decltype(auto)
9996 operator[](difference_type __n) const
9997 requires __detail::__concat_is_random_access<_Const, _Vs...>
9998 { return *((*this) + __n); }
10000 friend constexpr bool
10001 operator==(const _Iterator& __x, const _Iterator& __y)
10002 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10004 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10005 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10006 return __x._M_it == __y._M_it;
10009 friend constexpr bool
10010 operator==(const _Iterator& __it, default_sentinel_t)
10012 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10013 constexpr auto __last_idx = sizeof...(_Vs) - 1;
10014 return (__it._M_it.index() == __last_idx
10015 && (std::get<__last_idx>(__it._M_it)
10016 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10019 friend constexpr bool
10020 operator<(const _Iterator& __x, const _Iterator& __y)
10021 requires __detail::__all_random_access<_Const, _Vs...>
10022 { return __x._M_it < __y._M_it; }
10024 friend constexpr bool
10025 operator>(const _Iterator& __x, const _Iterator& __y)
10026 requires __detail::__all_random_access<_Const, _Vs...>
10027 { return __x._M_it > __y._M_it; }
10029 friend constexpr bool
10030 operator<=(const _Iterator& __x, const _Iterator& __y)
10031 requires __detail::__all_random_access<_Const, _Vs...>
10032 { return __x._M_it <= __y._M_it; }
10034 friend constexpr bool
10035 operator>=(const _Iterator& __x, const _Iterator& __y)
10036 requires __detail::__all_random_access<_Const, _Vs...>
10037 { return __x._M_it >= __y._M_it; }
10039 friend constexpr auto
10040 operator<=>(const _Iterator& __x, const _Iterator& __y)
10041 requires __detail::__all_random_access<_Const, _Vs...>
10042 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10043 { return __x._M_it <=> __y._M_it; }
10045 friend constexpr _Iterator
10046 operator+(const _Iterator& __it, difference_type __n)
10047 requires __detail::__concat_is_random_access<_Const, _Vs...>
10048 { return auto(__it) += __n; }
10050 friend constexpr _Iterator
10051 operator+(difference_type __n, const _Iterator& __it)
10052 requires __detail::__concat_is_random_access<_Const, _Vs...>
10053 { return __it + __n; }
10055 friend constexpr _Iterator
10056 operator-(const _Iterator& __it, difference_type __n)
10057 requires __detail::__concat_is_random_access<_Const, _Vs...>
10058 { return auto(__it) -= __n; }
10060 friend constexpr difference_type
10061 operator-(const _Iterator& __x, const _Iterator& __y)
10062 requires __detail::__concat_is_random_access<_Const, _Vs...>
10064 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10065 return _S_invoke_with_runtime_index([&]<size_t _Iy>() -> difference_type {
10066 if constexpr (_Ix > _Iy)
10068 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10069 ranges::end(std::get<_Iy>(__y._M_parent
10071 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10073 std::get<_Ix>(__x._M_it));
10074 difference_type __s = 0;
10075 [&]<size_t _Idx = _Iy + 1>(this auto&& __self) {
10076 if constexpr (_Idx < _Ix)
10078 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10079 __self.template operator()<_Idx + 1>();
10082 return __dy + __s + __dx;
10084 else if constexpr (_Ix < _Iy)
10085 return -(__y - __x);
10087 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10088 }, __y._M_it.index());
10089 }, __x._M_it.index());
10092 friend constexpr difference_type
10093 operator-(const _Iterator& __x, default_sentinel_t)
10094 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10095 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10096 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10098 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10099 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10100 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10101 difference_type __s = 0;
10102 [&]<size_t _Idx = _Ix + 1>(this auto&& __self) {
10103 if constexpr (_Idx < sizeof...(_Vs))
10105 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10106 __self.template operator()<_Idx + 1>();
10109 return -(__dx + __s);
10110 }, __x._M_it.index());
10113 friend constexpr difference_type
10114 operator-(default_sentinel_t, const _Iterator& __x)
10115 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10116 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10117 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10118 { return -(__x - default_sentinel); }
10120 friend constexpr decltype(auto)
10121 iter_move(const _Iterator& __it)
10123 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10124 return std::visit([](const auto& __i) -> _Res {
10125 return ranges::iter_move(__i);
10129 friend constexpr void
10130 iter_swap(const _Iterator& __x, const _Iterator& __y)
10131 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10132 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10134 std::visit([&]<typename _Tp, typename _Up>(const _Tp& __it1, const _Up& __it2) {
10135 if constexpr (is_same_v<_Tp, _Up>)
10136 ranges::iter_swap(__it1, __it2);
10138 ranges::swap(*__it1, *__it2);
10139 }, __x._M_it, __y._M_it);
10147 template<typename... _Ts>
10148 concept __can_concat_view = requires { concat_view(std::declval<_Ts>()...); };
10153 template<typename... _Ts>
10154 requires __detail::__can_concat_view<_Ts...>
10156 operator() [[nodiscard]] (_Ts&&... __ts) const
10157 { return concat_view(std::forward<_Ts>(__ts)...); }
10159 template<input_range _Range>
10161 operator() [[nodiscard]] (_Range&& __t) const
10162 { return views::all(std::forward<_Range>(__t)); }
10165 inline constexpr _Concat concat;
10168} // namespace ranges
10169#endif // __cpp_lib_ranges_concat
10171#if __cpp_lib_ranges_cache_latest // C++ >= 26
10174 template<input_range _Vp>
10176 class cache_latest_view : public view_interface<cache_latest_view<_Vp>>
10178 _Vp _M_base = _Vp();
10180 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10181 add_pointer_t<range_reference_t<_Vp>>,
10182 range_reference_t<_Vp>>;
10183 __detail::__non_propagating_cache<__cache_t> _M_cache;
10189 cache_latest_view() requires default_initializable<_Vp> = default;
10192 cache_latest_view(_Vp __base)
10193 : _M_base(std::move(__base))
10197 base() const & requires copy_constructible<_Vp>
10198 { return _M_base; }
10202 { return std::move(_M_base); }
10206 { return _Iterator(*this); }
10210 { return _Sentinel(*this); }
10213 size() requires sized_range<_Vp>
10214 { return ranges::size(_M_base); }
10217 size() const requires sized_range<const _Vp>
10218 { return ranges::size(_M_base); }
10221 template<typename _Range>
10222 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10224 template<input_range _Vp>
10226 class cache_latest_view<_Vp>::_Iterator
10228 cache_latest_view* _M_parent;
10229 iterator_t<_Vp> _M_current;
10232 _Iterator(cache_latest_view& __parent)
10233 : _M_parent(std::__addressof(__parent)),
10234 _M_current(ranges::begin(__parent._M_base))
10237 friend class cache_latest_view;
10240 using difference_type = range_difference_t<_Vp>;
10241 using value_type = range_value_t<_Vp>;
10242 using iterator_concept = input_iterator_tag;
10244 _Iterator(_Iterator&&) = default;
10247 operator=(_Iterator&&) = default;
10249 constexpr iterator_t<_Vp>
10251 { return std::move(_M_current); }
10253 constexpr const iterator_t<_Vp>&
10254 base() const & noexcept
10255 { return _M_current; }
10257 constexpr range_reference_t<_Vp>&
10260 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10262 if (!_M_parent->_M_cache)
10263 _M_parent->_M_cache = std::__addressof(__detail::__as_lvalue(*_M_current));
10264 return **_M_parent->_M_cache;
10268 if (!_M_parent->_M_cache)
10269 _M_parent->_M_cache._M_emplace_deref(_M_current);
10270 return *_M_parent->_M_cache;
10274 constexpr _Iterator&
10277 _M_parent->_M_cache._M_reset();
10286 friend constexpr range_rvalue_reference_t<_Vp>
10287 iter_move(const _Iterator& __i)
10288 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10289 { return ranges::iter_move(__i._M_current); }
10291 friend constexpr void
10292 iter_swap(const _Iterator& __x, const _Iterator& __y)
10293 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10294 requires indirectly_swappable<iterator_t<_Vp>>
10295 { ranges::iter_swap(__x._M_current, __y._M_current); }
10298 template<input_range _Vp>
10300 class cache_latest_view<_Vp>::_Sentinel
10302 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10305 _Sentinel(cache_latest_view& __parent)
10306 : _M_end(ranges::end(__parent._M_base))
10309 friend class cache_latest_view;
10312 _Sentinel() = default;
10314 constexpr sentinel_t<_Vp>
10318 friend constexpr bool
10319 operator==(const _Iterator& __x, const _Sentinel& __y)
10320 { return __x._M_current == __y._M_end; }
10322 friend constexpr range_difference_t<_Vp>
10323 operator-(const _Iterator& __x, const _Sentinel& __y)
10324 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10325 { return __x._M_current - __y._M_end; }
10327 friend constexpr range_difference_t<_Vp>
10328 operator-(const _Sentinel& __x, const _Iterator& __y)
10329 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10330 { return __x._M_end - __y._M_current; }
10337 template<typename _Tp>
10338 concept __can_cache_latest = requires { cache_latest_view(std::declval<_Tp>()); };
10341 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10343 template<viewable_range _Range>
10344 requires __detail::__can_cache_latest<_Range>
10346 operator() [[nodiscard]] (_Range&& __r) const
10347 { return cache_latest_view(std::forward<_Range>(__r)); }
10349 static constexpr bool _S_has_simple_call_op = true;
10352 inline constexpr _CacheLatest cache_latest;
10354} // namespace ranges
10355#endif // __cpp_lib_ranges_cache_latest
10357#if __cpp_lib_ranges_to_input // C++ >= 26
10360 template<input_range _Vp>
10362 class to_input_view : public view_interface<to_input_view<_Vp>>
10364 _Vp _M_base = _Vp();
10366 template<bool _Const>
10370 to_input_view() requires default_initializable<_Vp> = default;
10373 to_input_view(_Vp __base)
10374 : _M_base(std::move(__base))
10378 base() const & requires copy_constructible<_Vp>
10379 { return _M_base; }
10383 { return std::move(_M_base); }
10386 begin() requires (!__detail::__simple_view<_Vp>)
10387 { return _Iterator<false>(ranges::begin(_M_base)); }
10390 begin() const requires range<const _Vp>
10391 { return _Iterator<true>(ranges::begin(_M_base)); }
10394 end() requires (!__detail::__simple_view<_Vp>)
10395 { return ranges::end(_M_base); }
10398 end() const requires range<const _Vp>
10399 { return ranges::end(_M_base); }
10402 size() requires sized_range<_Vp>
10403 { return ranges::size(_M_base); }
10406 size() const requires sized_range<const _Vp>
10407 { return ranges::size(_M_base); }
10410 template<typename _Range>
10411 to_input_view(_Range&&) -> to_input_view<views::all_t<_Range>>;
10413 template<input_range _Vp>
10415 template<bool _Const>
10416 class to_input_view<_Vp>::_Iterator
10418 using _Base = __maybe_const_t<_Const, _Vp>;
10420 iterator_t<_Base> _M_current = iterator_t<_Base>();
10423 _Iterator(iterator_t<_Base> __current)
10424 : _M_current(std::move(__current))
10427 friend to_input_view;
10428 friend _Iterator<!_Const>;
10431 using difference_type = range_difference_t<_Base>;
10432 using value_type = range_value_t<_Base>;
10433 using iterator_concept = input_iterator_tag;
10435 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
10437 _Iterator(_Iterator&&) = default;
10438 _Iterator& operator=(_Iterator&&) = default;
10441 _Iterator(_Iterator<!_Const> __i)
10442 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10443 : _M_current(std::move(__i._M_current))
10446 constexpr iterator_t<_Base>
10448 { return std::move(_M_current); }
10450 constexpr const iterator_t<_Base>&
10451 base() const & noexcept
10452 { return _M_current; }
10454 constexpr decltype(auto)
10456 { return *_M_current; }
10458 constexpr _Iterator&
10469 friend constexpr bool
10470 operator==(const _Iterator& __x, const sentinel_t<_Base>& __y)
10471 { return __x._M_current == __y; }
10473 friend constexpr difference_type
10474 operator-(const sentinel_t<_Base>& __y, const _Iterator& __x)
10475 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10476 { return __y - __x._M_current; }
10478 friend constexpr difference_type
10479 operator-(const _Iterator& __x, const sentinel_t<_Base>& __y)
10480 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10481 { return __x._M_current - __y; }
10483 friend constexpr range_rvalue_reference_t<_Base>
10484 iter_move(const _Iterator& __i)
10485 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10486 { return ranges::iter_move(__i._M_current); }
10488 friend constexpr void
10489 iter_swap(const _Iterator& __x, const _Iterator& __y)
10490 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10491 requires indirectly_swappable<iterator_t<_Base>>
10492 { ranges::iter_swap(__x._M_current, __y._M_current); }
10499 template<typename _Tp>
10500 concept __can_to_input = requires { to_input_view(std::declval<_Tp>()); };
10503 struct _ToInput : __adaptor::_RangeAdaptorClosure<_ToInput>
10505 template<viewable_range _Range>
10506 requires __detail::__can_to_input<_Range>
10508 operator() [[nodiscard]] (_Range&& __r) const
10510 if constexpr (input_range<_Range>
10511 && !common_range<_Range>
10512 && !forward_range<_Range>)
10513 return views::all(std::forward<_Range>(__r));
10515 return to_input_view(std::forward<_Range>(__r));
10518 static constexpr bool _S_has_simple_call_op = true;
10521 inline constexpr _ToInput to_input;
10523} // namespace ranges
10524#endif // __cpp_lib_ranges_to_input
10526_GLIBCXX_END_NAMESPACE_VERSION
10528#endif // library concepts
10530#endif /* _GLIBCXX_RANGES */