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 [[nodiscard]] constexpr auto
795 operator() (_Tp __e) const noexcept
796 { return iota(_Tp{}, __e); }
799 inline constexpr _Indices indices{};
800#endif // __cpp_lib_ranges_indices
806 template<typename _Val, typename _CharT, typename _Traits>
807 concept __stream_extractable
808 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
809 } // namespace __detail
811 template<movable _Val, typename _CharT,
812 typename _Traits = char_traits<_CharT>>
813 requires default_initializable<_Val>
814 && __detail::__stream_extractable<_Val, _CharT, _Traits>
815 class basic_istream_view
816 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
820 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
821 : _M_stream(std::__addressof(__stream))
827 *_M_stream >> _M_object;
828 return _Iterator{this};
831 constexpr default_sentinel_t
833 { return default_sentinel; }
836 basic_istream<_CharT, _Traits>* _M_stream;
837 _Val _M_object = _Val();
842 using iterator_concept = input_iterator_tag;
843 using difference_type = ptrdiff_t;
844 using value_type = _Val;
847 _Iterator(basic_istream_view* __parent) noexcept
848 : _M_parent(__parent)
851 _Iterator(const _Iterator&) = delete;
852 _Iterator(_Iterator&&) = default;
853 _Iterator& operator=(const _Iterator&) = delete;
854 _Iterator& operator=(_Iterator&&) = default;
859 *_M_parent->_M_stream >> _M_parent->_M_object;
869 { return _M_parent->_M_object; }
872 operator==(const _Iterator& __x, default_sentinel_t)
873 { return __x._M_at_end(); }
876 basic_istream_view* _M_parent;
880 { return !*_M_parent->_M_stream; }
886 template<typename _Val>
887 using istream_view = basic_istream_view<_Val, char>;
889 template<typename _Val>
890 using wistream_view = basic_istream_view<_Val, wchar_t>;
896 template<typename _Tp, typename _Up>
897 concept __can_istream_view = requires (_Up __e) {
898 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
900 } // namespace __detail
902 template<typename _Tp>
905 template<typename _CharT, typename _Traits>
907 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
908 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
909 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
912 template<typename _Tp>
913 inline constexpr _Istream<_Tp> istream;
917 // C++20 24.7 [range.adaptors] Range adaptors
921 template<typename _Tp, int _Disc>
924 // Alias for a type that is conditionally present
925 // (and is an empty type otherwise).
926 // Data members using this alias should use [[no_unique_address]] so that
927 // they take no space when not needed.
928 // The optional template parameter _Disc is for discriminating two otherwise
929 // equivalent absent types so that even they can overlap.
930 template<bool _Present, typename _Tp, int _Disc = 0>
931 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
933 // Alias for a type that is conditionally const.
934 template<bool _Const, typename _Tp>
935 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
937} // namespace __detail
939// Shorthand for __detail::__maybe_const_t.
940using __detail::__maybe_const_t;
942namespace views::__adaptor
944 // True if the range adaptor _Adaptor can be applied with _Args.
945 template<typename _Adaptor, typename... _Args>
946 concept __adaptor_invocable
947 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
949 // True if the range adaptor non-closure _Adaptor can be partially applied
951 template<typename _Adaptor, typename... _Args>
952 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
953 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
954 && (constructible_from<decay_t<_Args>, _Args> && ...);
956 template<typename _Adaptor, typename... _Args>
959 template<typename _Lhs, typename _Rhs>
962 // The base class of every range adaptor closure.
964 // The derived class should define the optional static data member
965 // _S_has_simple_call_op to true if the behavior of this adaptor is
966 // independent of the constness/value category of the adaptor object.
967 template<typename _Derived>
968 struct _RangeAdaptorClosure;
970 template<typename _Tp, typename _Up>
971 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
972 void __is_range_adaptor_closure_fn
973 (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined
975 template<typename _Tp>
976 concept __is_range_adaptor_closure
977 = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
979#pragma GCC diagnostic push
980#pragma GCC diagnostic ignored "-Wdangling-reference"
981 // range | adaptor is equivalent to adaptor(range).
982 template<typename _Self, typename _Range>
983 requires __is_range_adaptor_closure<_Self>
984 && __adaptor_invocable<_Self, _Range>
986 operator|(_Range&& __r, _Self&& __self)
987 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
989 // Compose the adaptors __lhs and __rhs into a pipeline, returning
990 // another range adaptor closure object.
991 template<typename _Lhs, typename _Rhs>
992 requires __is_range_adaptor_closure<_Lhs>
993 && __is_range_adaptor_closure<_Rhs>
995 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
997 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
998 std::forward<_Rhs>(__rhs)};
1000#pragma GCC diagnostic pop
1002 template<typename _Derived>
1003 struct _RangeAdaptorClosure
1005 // In non-modules compilation ADL finds these operators either way and
1006 // the friend declarations are redundant. But with the std module these
1007 // friend declarations enable ADL to find these operators without having
1009 template<typename _Self, typename _Range>
1010 requires __is_range_adaptor_closure<_Self>
1011 && __adaptor_invocable<_Self, _Range>
1012 friend constexpr auto
1013 operator|(_Range&& __r, _Self&& __self);
1015 template<typename _Lhs, typename _Rhs>
1016 requires __is_range_adaptor_closure<_Lhs>
1017 && __is_range_adaptor_closure<_Rhs>
1018 friend constexpr auto
1019 operator|(_Lhs&& __lhs, _Rhs&& __rhs);
1022 // The base class of every range adaptor non-closure.
1024 // The static data member _Derived::_S_arity must contain the total number of
1025 // arguments that the adaptor takes, and the class _Derived must introduce
1026 // _RangeAdaptor::operator() into the class scope via a using-declaration.
1028 // The optional static data member _Derived::_S_has_simple_extra_args should
1029 // be defined to true if the behavior of this adaptor is independent of the
1030 // constness/value category of the extra arguments. This data member could
1031 // also be defined as a variable template parameterized by the types of the
1033 template<typename _Derived>
1034 struct _RangeAdaptor
1036 // Partially apply the arguments __args to the range adaptor _Derived,
1037 // returning a range adaptor closure object.
1038 template<typename... _Args>
1039 requires __adaptor_partial_app_viable<_Derived, _Args...>
1041 operator()(_Args&&... __args) const
1043 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
1047 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
1048 // one that's not overloaded according to constness or value category of the
1050 template<typename _Adaptor>
1051 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1053 // True if the behavior of the range adaptor non-closure _Adaptor is
1054 // independent of the value category of its extra arguments _Args.
1055 template<typename _Adaptor, typename... _Args>
1056 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1057 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1059 // A range adaptor closure that represents partial application of
1060 // the range adaptor _Adaptor with arguments _Args.
1061 template<typename _Adaptor, typename... _Args>
1062 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1064 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1065 [[no_unique_address]] _Binder _M_binder;
1067 // First parameter is to ensure this constructor is never used
1068 // instead of the copy/move constructor.
1069 template<typename... _Ts>
1071 _Partial(int, _Ts&&... __args)
1072 : _M_binder(0, _Adaptor(), std::forward<_Ts>(__args)...)
1075 // Invoke _Adaptor with arguments __r, _M_args... according to the
1076 // value category of this _Partial object.
1077#if __cpp_explicit_this_parameter
1078 template<typename _Self, typename _Range>
1079 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1081 operator()(this _Self&& __self, _Range&& __r)
1083 return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
1084 std::forward<_Range>(__r));
1087 template<typename _Range>
1088 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1090 operator()(_Range&& __r) const &
1091 { return _Binder::_S_call(_M_binder, std::forward<_Range>(__r)); }
1093 template<typename _Range>
1094 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1096 operator()(_Range&& __r) &&
1097 { return _Binder::_S_call(std::move(_M_binder), std::forward<_Range>(__r)); }
1099 template<typename _Range>
1101 operator()(_Range&& __r) const && = delete;
1105 // Partial specialization of the primary template for the case where the extra
1106 // arguments of the adaptor can always be safely and efficiently forwarded by
1107 // const reference. This lets us get away with a single operator() overload,
1108 // which makes overload resolution failure diagnostics more concise.
1109 template<typename _Adaptor, typename... _Args>
1110 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1111 && (is_trivially_copy_constructible_v<_Args> && ...)
1112 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1114 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1115 [[no_unique_address]] _Binder _M_binder;
1117 template<typename... _Ts>
1119 _Partial(int, _Ts&&... __args)
1120 : _M_binder(0, _Adaptor(), std::forward<_Ts>(__args)...)
1123 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1124 // of the value category of this _Partial object.
1125 template<typename _Range>
1126 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1128 operator()(_Range&& __r) const
1129 { return _Binder::_S_call(_M_binder, std::forward<_Range>(__r)); }
1131 static constexpr bool _S_has_simple_call_op = true;
1134 template<typename _Lhs, typename _Rhs, typename _Range>
1135 concept __pipe_invocable
1136 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1138 // A range adaptor closure that represents composition of the range
1139 // adaptor closures _Lhs and _Rhs.
1140 template<typename _Lhs, typename _Rhs>
1141 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1143 [[no_unique_address]] _Lhs _M_lhs;
1144 [[no_unique_address]] _Rhs _M_rhs;
1146 template<typename _Tp, typename _Up>
1148 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1149 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1152 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1153 // range adaptor closure object.
1154#if __cpp_explicit_this_parameter
1155 template<typename _Self, typename _Range>
1156 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1158 operator()(this _Self&& __self, _Range&& __r)
1160 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1161 (__like_t<_Self, _Pipe>(__self)._M_lhs
1162 (std::forward<_Range>(__r))));
1165 template<typename _Range>
1166 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1168 operator()(_Range&& __r) const &
1169 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1171 template<typename _Range>
1172 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1174 operator()(_Range&& __r) &&
1175 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1177 template<typename _Range>
1179 operator()(_Range&& __r) const && = delete;
1183 // A partial specialization of the above primary template for the case where
1184 // both adaptor operands have a simple operator(). This in turn lets us
1185 // implement composition using a single simple operator(), which makes
1186 // overload resolution failure diagnostics more concise.
1187 template<typename _Lhs, typename _Rhs>
1188 requires __closure_has_simple_call_op<_Lhs>
1189 && __closure_has_simple_call_op<_Rhs>
1190 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1192 [[no_unique_address]] _Lhs _M_lhs;
1193 [[no_unique_address]] _Rhs _M_rhs;
1195 template<typename _Tp, typename _Up>
1197 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1198 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1201 template<typename _Range>
1202 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1204 operator()(_Range&& __r) const
1205 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1207 static constexpr bool _S_has_simple_call_op = true;
1209} // namespace views::__adaptor
1211#if __cpp_lib_ranges >= 202202L
1212 // P2387R3 Pipe support for user-defined range adaptors
1213 template<typename _Derived>
1214 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1215 class range_adaptor_closure
1216 : public views::__adaptor::_RangeAdaptorClosure<_Derived>
1220 template<range _Range> requires is_object_v<_Range>
1221 class ref_view : public view_interface<ref_view<_Range>>
1226 static void _S_fun(_Range&); // not defined
1227 static void _S_fun(_Range&&) = delete;
1230 template<__detail::__different_from<ref_view> _Tp>
1231 requires convertible_to<_Tp, _Range&>
1232 && requires { _S_fun(declval<_Tp>()); }
1235 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1236 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1243 constexpr iterator_t<_Range>
1245 { return ranges::begin(*_M_r); }
1247 constexpr sentinel_t<_Range>
1249 { return ranges::end(*_M_r); }
1252 empty() const requires requires { ranges::empty(*_M_r); }
1253 { return ranges::empty(*_M_r); }
1256 size() const requires sized_range<_Range>
1257 { return ranges::size(*_M_r); }
1260 data() const requires contiguous_range<_Range>
1261 { return ranges::data(*_M_r); }
1264 template<typename _Range>
1265 ref_view(_Range&) -> ref_view<_Range>;
1267 template<typename _Tp>
1268 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1270 template<range _Range>
1271 requires movable<_Range>
1272 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1273 class owning_view : public view_interface<owning_view<_Range>>
1276 _Range _M_r = _Range();
1279 owning_view() requires default_initializable<_Range> = default;
1282 owning_view(_Range&& __t)
1283 noexcept(is_nothrow_move_constructible_v<_Range>)
1284 : _M_r(std::move(__t))
1287 owning_view(owning_view&&) = default;
1288 owning_view& operator=(owning_view&&) = default;
1294 constexpr const _Range&
1295 base() const& noexcept
1300 { return std::move(_M_r); }
1302 constexpr const _Range&&
1303 base() const&& noexcept
1304 { return std::move(_M_r); }
1306 constexpr iterator_t<_Range>
1308 { return ranges::begin(_M_r); }
1310 constexpr sentinel_t<_Range>
1312 { return ranges::end(_M_r); }
1315 begin() const requires range<const _Range>
1316 { return ranges::begin(_M_r); }
1319 end() const requires range<const _Range>
1320 { return ranges::end(_M_r); }
1323 empty() requires requires { ranges::empty(_M_r); }
1324 { return ranges::empty(_M_r); }
1327 empty() const requires requires { ranges::empty(_M_r); }
1328 { return ranges::empty(_M_r); }
1331 size() requires sized_range<_Range>
1332 { return ranges::size(_M_r); }
1335 size() const requires sized_range<const _Range>
1336 { return ranges::size(_M_r); }
1339 data() requires contiguous_range<_Range>
1340 { return ranges::data(_M_r); }
1343 data() const requires contiguous_range<const _Range>
1344 { return ranges::data(_M_r); }
1347 template<typename _Tp>
1348 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1349 = enable_borrowed_range<_Tp>;
1355 template<typename _Range>
1356 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1358 template<typename _Range>
1359 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1360 } // namespace __detail
1362 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1364 template<typename _Range>
1365 static constexpr bool
1368 if constexpr (view<decay_t<_Range>>)
1369 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1370 else if constexpr (__detail::__can_ref_view<_Range>)
1373 return noexcept(owning_view{std::declval<_Range>()});
1376 template<viewable_range _Range>
1377 requires view<decay_t<_Range>>
1378 || __detail::__can_ref_view<_Range>
1379 || __detail::__can_owning_view<_Range>
1381 operator() [[nodiscard]] (_Range&& __r) const
1382 noexcept(_S_noexcept<_Range>())
1384 if constexpr (view<decay_t<_Range>>)
1385 return std::forward<_Range>(__r);
1386 else if constexpr (__detail::__can_ref_view<_Range>)
1387 return ref_view{std::forward<_Range>(__r)};
1389 return owning_view{std::forward<_Range>(__r)};
1392 static constexpr bool _S_has_simple_call_op = true;
1395 inline constexpr _All all;
1397 template<viewable_range _Range>
1398 using all_t = decltype(all(std::declval<_Range>()));
1399 } // namespace views
1403 template<typename _Tp>
1404 struct __non_propagating_cache
1406 // When _Tp is not an object type (e.g. is a reference type), we make
1407 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1408 // users can easily conditionally declare data members with this type
1409 // (such as join_view::_M_inner).
1412 template<typename _Tp>
1413 requires is_object_v<_Tp>
1414 struct __non_propagating_cache<_Tp>
1415 : protected _Optional_base<_Tp>
1417 __non_propagating_cache() = default;
1420 __non_propagating_cache(const __non_propagating_cache&) noexcept
1424 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1425 { __other._M_reset(); }
1427 constexpr __non_propagating_cache&
1428 operator=(const __non_propagating_cache& __other) noexcept
1430 if (std::__addressof(__other) != this)
1435 constexpr __non_propagating_cache&
1436 operator=(__non_propagating_cache&& __other) noexcept
1443 constexpr __non_propagating_cache&
1444 operator=(_Tp __val)
1447 this->_M_payload._M_construct(std::move(__val));
1452 operator bool() const noexcept
1453 { return this->_M_is_engaged(); }
1456 operator*() noexcept
1457 { return this->_M_get(); }
1459 constexpr const _Tp&
1460 operator*() const noexcept
1461 { return this->_M_get(); }
1463 template<typename _Iter>
1465 _M_emplace_deref(const _Iter& __i)
1468 auto __f = [] (auto& __x) { return *__x; };
1469 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1470 return this->_M_get();
1473 using _Optional_base<_Tp>::_M_reset;
1476 template<range _Range>
1477 struct _CachedPosition
1480 _M_has_value() const
1483 constexpr iterator_t<_Range>
1484 _M_get(const _Range&) const
1486 __glibcxx_assert(false);
1487 __builtin_unreachable();
1491 _M_set(const _Range&, const iterator_t<_Range>&) const
1495 template<forward_range _Range>
1496 struct _CachedPosition<_Range>
1497 : protected __non_propagating_cache<iterator_t<_Range>>
1500 _M_has_value() const
1501 { return this->_M_is_engaged(); }
1503 constexpr iterator_t<_Range>
1504 _M_get(const _Range&) const
1506 __glibcxx_assert(_M_has_value());
1511 _M_set(const _Range&, const iterator_t<_Range>& __it)
1513 __glibcxx_assert(!_M_has_value());
1514 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1516 this->_M_payload._M_engaged = true;
1520 template<random_access_range _Range>
1521 struct _CachedPosition<_Range>
1524 range_difference_t<_Range> _M_offset = -1;
1527 _CachedPosition() = default;
1530 _CachedPosition(const _CachedPosition&) = default;
1533 _CachedPosition(_CachedPosition&& __other) noexcept
1534 { *this = std::move(__other); }
1536 constexpr _CachedPosition&
1537 operator=(const _CachedPosition&) = default;
1539 constexpr _CachedPosition&
1540 operator=(_CachedPosition&& __other) noexcept
1542 // Propagate the cached offset, but invalidate the source.
1543 _M_offset = __other._M_offset;
1544 __other._M_offset = -1;
1549 _M_has_value() const
1550 { return _M_offset >= 0; }
1552 constexpr iterator_t<_Range>
1553 _M_get(_Range& __r) const
1555 __glibcxx_assert(_M_has_value());
1556 return ranges::begin(__r) + _M_offset;
1560 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1562 __glibcxx_assert(!_M_has_value());
1563 _M_offset = __it - ranges::begin(__r);
1566 } // namespace __detail
1570 template<typename _Base>
1571 struct __filter_view_iter_cat
1574 template<forward_range _Base>
1575 struct __filter_view_iter_cat<_Base>
1581 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1582 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1583 return bidirectional_iterator_tag{};
1584 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1585 return forward_iterator_tag{};
1590 using iterator_category = decltype(_S_iter_cat());
1592 } // namespace __detail
1594 template<input_range _Vp,
1595 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1596 requires view<_Vp> && is_object_v<_Pred>
1597 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1602 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1605 static constexpr auto
1608 if constexpr (bidirectional_range<_Vp>)
1609 return bidirectional_iterator_tag{};
1610 else if constexpr (forward_range<_Vp>)
1611 return forward_iterator_tag{};
1613 return input_iterator_tag{};
1618 using _Vp_iter = iterator_t<_Vp>;
1620 _Vp_iter _M_current = _Vp_iter();
1621 filter_view* _M_parent = nullptr;
1624 using iterator_concept = decltype(_S_iter_concept());
1625 // iterator_category defined in __filter_view_iter_cat
1626 using value_type = range_value_t<_Vp>;
1627 using difference_type = range_difference_t<_Vp>;
1629 _Iterator() requires default_initializable<_Vp_iter> = default;
1632 _Iterator(filter_view* __parent, _Vp_iter __current)
1633 : _M_current(std::move(__current)),
1637 constexpr const _Vp_iter&
1638 base() const & noexcept
1639 { return _M_current; }
1643 { return std::move(_M_current); }
1645 constexpr range_reference_t<_Vp>
1647 { return *_M_current; }
1651 requires __detail::__has_arrow<_Vp_iter>
1652 && copyable<_Vp_iter>
1653 { return _M_current; }
1655 constexpr _Iterator&
1658 _M_current = ranges::find_if(std::move(++_M_current),
1659 ranges::end(_M_parent->_M_base),
1660 std::ref(*_M_parent->_M_pred));
1669 operator++(int) requires forward_range<_Vp>
1676 constexpr _Iterator&
1677 operator--() requires bidirectional_range<_Vp>
1681 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1686 operator--(int) requires bidirectional_range<_Vp>
1693 friend constexpr bool
1694 operator==(const _Iterator& __x, const _Iterator& __y)
1695 requires equality_comparable<_Vp_iter>
1696 { return __x._M_current == __y._M_current; }
1698 friend constexpr range_rvalue_reference_t<_Vp>
1699 iter_move(const _Iterator& __i)
1700 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1701 { return ranges::iter_move(__i._M_current); }
1703 friend constexpr void
1704 iter_swap(const _Iterator& __x, const _Iterator& __y)
1705 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1706 requires indirectly_swappable<_Vp_iter>
1707 { ranges::iter_swap(__x._M_current, __y._M_current); }
1713 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1716 __equal(const _Iterator& __i) const
1717 { return __i._M_current == _M_end; }
1720 _Sentinel() = default;
1723 _Sentinel(filter_view* __parent)
1724 : _M_end(ranges::end(__parent->_M_base))
1727 constexpr sentinel_t<_Vp>
1731 friend constexpr bool
1732 operator==(const _Iterator& __x, const _Sentinel& __y)
1733 { return __y.__equal(__x); }
1736 _Vp _M_base = _Vp();
1737 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1738 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1741 filter_view() requires (default_initializable<_Vp>
1742 && default_initializable<_Pred>)
1746 filter_view(_Vp __base, _Pred __pred)
1747 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1751 base() const& requires copy_constructible<_Vp>
1756 { return std::move(_M_base); }
1758 constexpr const _Pred&
1760 { return *_M_pred; }
1765 if (_M_cached_begin._M_has_value())
1766 return {this, _M_cached_begin._M_get(_M_base)};
1768 __glibcxx_assert(_M_pred.has_value());
1769 auto __it = ranges::find_if(ranges::begin(_M_base),
1770 ranges::end(_M_base),
1771 std::ref(*_M_pred));
1772 _M_cached_begin._M_set(_M_base, __it);
1773 return {this, std::move(__it)};
1779 if constexpr (common_range<_Vp>)
1780 return _Iterator{this, ranges::end(_M_base)};
1782 return _Sentinel{this};
1786 template<typename _Range, typename _Pred>
1787 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1793 template<typename _Range, typename _Pred>
1794 concept __can_filter_view
1795 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1796 } // namespace __detail
1798 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1800 template<viewable_range _Range, typename _Pred>
1801 requires __detail::__can_filter_view<_Range, _Pred>
1803 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1805 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1808 using _RangeAdaptor<_Filter>::operator();
1809 static constexpr int _S_arity = 2;
1810 static constexpr bool _S_has_simple_extra_args = true;
1813 inline constexpr _Filter filter;
1814 } // namespace views
1816#if __cpp_lib_ranges >= 202207L // C++ >= 23
1817 template<input_range _Vp, move_constructible _Fp>
1819 template<input_range _Vp, copy_constructible _Fp>
1821 requires view<_Vp> && is_object_v<_Fp>
1822 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1823 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1824 range_reference_t<_Vp>>>
1825 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1828 template<bool _Const>
1829 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1831 template<bool _Const>
1835 template<bool _Const>
1836 requires forward_range<_Base<_Const>>
1837 struct __iter_cat<_Const>
1843 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1844 // 3564. transform_view::iterator<true>::value_type and
1845 // iterator_category should use const F&
1846 using _Base = transform_view::_Base<_Const>;
1847 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1848 range_reference_t<_Base>>;
1849 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1850 // 3798. Rvalue reference and iterator_category
1851 if constexpr (is_reference_v<_Res>)
1854 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1855 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1856 return random_access_iterator_tag{};
1861 return input_iterator_tag{};
1864 using iterator_category = decltype(_S_iter_cat());
1867 template<bool _Const>
1870 template<bool _Const>
1871 struct _Iterator : __iter_cat<_Const>
1874 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1875 using _Base = transform_view::_Base<_Const>;
1880 if constexpr (random_access_range<_Base>)
1881 return random_access_iterator_tag{};
1882 else if constexpr (bidirectional_range<_Base>)
1883 return bidirectional_iterator_tag{};
1884 else if constexpr (forward_range<_Base>)
1885 return forward_iterator_tag{};
1887 return input_iterator_tag{};
1890 using _Base_iter = iterator_t<_Base>;
1892 _Base_iter _M_current = _Base_iter();
1893 _Parent* _M_parent = nullptr;
1896 using iterator_concept = decltype(_S_iter_concept());
1897 // iterator_category defined in __transform_view_iter_cat
1899 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1900 range_reference_t<_Base>>>;
1901 using difference_type = range_difference_t<_Base>;
1903 _Iterator() requires default_initializable<_Base_iter> = default;
1906 _Iterator(_Parent* __parent, _Base_iter __current)
1907 : _M_current(std::move(__current)),
1912 _Iterator(_Iterator<!_Const> __i)
1914 && convertible_to<iterator_t<_Vp>, _Base_iter>
1915 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1918 constexpr const _Base_iter&
1919 base() const & noexcept
1920 { return _M_current; }
1922 constexpr _Base_iter
1924 { return std::move(_M_current); }
1926 constexpr decltype(auto)
1928 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1929 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1931 constexpr _Iterator&
1943 operator++(int) requires forward_range<_Base>
1950 constexpr _Iterator&
1951 operator--() requires bidirectional_range<_Base>
1958 operator--(int) requires bidirectional_range<_Base>
1965 constexpr _Iterator&
1966 operator+=(difference_type __n) requires random_access_range<_Base>
1972 constexpr _Iterator&
1973 operator-=(difference_type __n) requires random_access_range<_Base>
1979 constexpr decltype(auto)
1980 operator[](difference_type __n) const
1981 requires random_access_range<_Base>
1982 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1984 friend constexpr bool
1985 operator==(const _Iterator& __x, const _Iterator& __y)
1986 requires equality_comparable<_Base_iter>
1987 { return __x._M_current == __y._M_current; }
1989 friend constexpr bool
1990 operator<(const _Iterator& __x, const _Iterator& __y)
1991 requires random_access_range<_Base>
1992 { return __x._M_current < __y._M_current; }
1994 friend constexpr bool
1995 operator>(const _Iterator& __x, const _Iterator& __y)
1996 requires random_access_range<_Base>
1997 { return __y < __x; }
1999 friend constexpr bool
2000 operator<=(const _Iterator& __x, const _Iterator& __y)
2001 requires random_access_range<_Base>
2002 { return !(__y < __x); }
2004 friend constexpr bool
2005 operator>=(const _Iterator& __x, const _Iterator& __y)
2006 requires random_access_range<_Base>
2007 { return !(__x < __y); }
2009#ifdef __cpp_lib_three_way_comparison
2010 friend constexpr auto
2011 operator<=>(const _Iterator& __x, const _Iterator& __y)
2012 requires random_access_range<_Base>
2013 && three_way_comparable<_Base_iter>
2014 { return __x._M_current <=> __y._M_current; }
2017 friend constexpr _Iterator
2018 operator+(_Iterator __i, difference_type __n)
2019 requires random_access_range<_Base>
2020 { return {__i._M_parent, __i._M_current + __n}; }
2022 friend constexpr _Iterator
2023 operator+(difference_type __n, _Iterator __i)
2024 requires random_access_range<_Base>
2025 { return {__i._M_parent, __i._M_current + __n}; }
2027 friend constexpr _Iterator
2028 operator-(_Iterator __i, difference_type __n)
2029 requires random_access_range<_Base>
2030 { return {__i._M_parent, __i._M_current - __n}; }
2032 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2033 // 3483. transform_view::iterator's difference is overconstrained
2034 friend constexpr difference_type
2035 operator-(const _Iterator& __x, const _Iterator& __y)
2036 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2037 { return __x._M_current - __y._M_current; }
2039 friend constexpr decltype(auto)
2040 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
2042 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
2043 return std::move(*__i);
2048 friend _Iterator<!_Const>;
2049 template<bool> friend struct _Sentinel;
2052 template<bool _Const>
2056 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2057 using _Base = transform_view::_Base<_Const>;
2059 template<bool _Const2>
2061 __distance_from(const _Iterator<_Const2>& __i) const
2062 { return _M_end - __i._M_current; }
2064 template<bool _Const2>
2066 __equal(const _Iterator<_Const2>& __i) const
2067 { return __i._M_current == _M_end; }
2069 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2072 _Sentinel() = default;
2075 _Sentinel(sentinel_t<_Base> __end)
2080 _Sentinel(_Sentinel<!_Const> __i)
2082 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2083 : _M_end(std::move(__i._M_end))
2086 constexpr sentinel_t<_Base>
2090 template<bool _Const2>
2091 requires sentinel_for<sentinel_t<_Base>,
2092 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2093 friend constexpr bool
2094 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2095 { return __y.__equal(__x); }
2097 template<bool _Const2,
2098 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2099 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2100 friend constexpr range_difference_t<_Base2>
2101 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2102 { return -__y.__distance_from(__x); }
2104 template<bool _Const2,
2105 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2106 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2107 friend constexpr range_difference_t<_Base2>
2108 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2109 { return __y.__distance_from(__x); }
2111 friend _Sentinel<!_Const>;
2114 _Vp _M_base = _Vp();
2115 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2118 transform_view() requires (default_initializable<_Vp>
2119 && default_initializable<_Fp>)
2123 transform_view(_Vp __base, _Fp __fun)
2124 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2128 base() const& requires copy_constructible<_Vp>
2129 { return _M_base ; }
2133 { return std::move(_M_base); }
2135 constexpr _Iterator<false>
2137 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2139 constexpr _Iterator<true>
2141 requires range<const _Vp>
2142 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2143 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2145 constexpr _Sentinel<false>
2147 { return _Sentinel<false>{ranges::end(_M_base)}; }
2149 constexpr _Iterator<false>
2150 end() requires common_range<_Vp>
2151 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2153 constexpr _Sentinel<true>
2155 requires range<const _Vp>
2156 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2157 { return _Sentinel<true>{ranges::end(_M_base)}; }
2159 constexpr _Iterator<true>
2161 requires common_range<const _Vp>
2162 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2163 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2166 size() requires sized_range<_Vp>
2167 { return ranges::size(_M_base); }
2170 size() const requires sized_range<const _Vp>
2171 { return ranges::size(_M_base); }
2174 template<typename _Range, typename _Fp>
2175 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2181 template<typename _Range, typename _Fp>
2182 concept __can_transform_view
2183 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2184 } // namespace __detail
2186 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2188 template<viewable_range _Range, typename _Fp>
2189 requires __detail::__can_transform_view<_Range, _Fp>
2191 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2193 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2196 using _RangeAdaptor<_Transform>::operator();
2197 static constexpr int _S_arity = 2;
2198 static constexpr bool _S_has_simple_extra_args = true;
2201 inline constexpr _Transform transform;
2202 } // namespace views
2205 class take_view : public view_interface<take_view<_Vp>>
2208 template<bool _Const>
2209 using _CI = counted_iterator<
2210 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2212 template<bool _Const>
2216 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2217 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2220 _Sentinel() = default;
2223 _Sentinel(sentinel_t<_Base> __end)
2228 _Sentinel(_Sentinel<!_Const> __s)
2229 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2230 : _M_end(std::move(__s._M_end))
2233 constexpr sentinel_t<_Base>
2237 friend constexpr bool
2238 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2239 { return __y.count() == 0 || __y.base() == __x._M_end; }
2241 template<bool _OtherConst = !_Const,
2242 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2243 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2244 friend constexpr bool
2245 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2246 { return __y.count() == 0 || __y.base() == __x._M_end; }
2248 friend _Sentinel<!_Const>;
2251 _Vp _M_base = _Vp();
2252 range_difference_t<_Vp> _M_count = 0;
2255 take_view() requires default_initializable<_Vp> = default;
2258 take_view(_Vp __base, range_difference_t<_Vp> __count)
2259 : _M_base(std::move(__base)), _M_count(std::move(__count))
2263 base() const& requires copy_constructible<_Vp>
2268 { return std::move(_M_base); }
2271 begin() requires (!__detail::__simple_view<_Vp>)
2273 if constexpr (sized_range<_Vp>)
2275 if constexpr (random_access_range<_Vp>)
2276 return ranges::begin(_M_base);
2280 return counted_iterator(ranges::begin(_M_base), __sz);
2284 return counted_iterator(ranges::begin(_M_base), _M_count);
2288 begin() const requires range<const _Vp>
2290 if constexpr (sized_range<const _Vp>)
2292 if constexpr (random_access_range<const _Vp>)
2293 return ranges::begin(_M_base);
2297 return counted_iterator(ranges::begin(_M_base), __sz);
2301 return counted_iterator(ranges::begin(_M_base), _M_count);
2305 end() requires (!__detail::__simple_view<_Vp>)
2307 if constexpr (sized_range<_Vp>)
2309 if constexpr (random_access_range<_Vp>)
2310 return ranges::begin(_M_base) + size();
2312 return default_sentinel;
2315 return _Sentinel<false>{ranges::end(_M_base)};
2319 end() const requires range<const _Vp>
2321 if constexpr (sized_range<const _Vp>)
2323 if constexpr (random_access_range<const _Vp>)
2324 return ranges::begin(_M_base) + size();
2326 return default_sentinel;
2329 return _Sentinel<true>{ranges::end(_M_base)};
2333 size() requires sized_range<_Vp>
2335 auto __n = ranges::size(_M_base);
2336 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2340 size() const requires sized_range<const _Vp>
2342 auto __n = ranges::size(_M_base);
2343 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2347 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2348 // 3447. Deduction guides for take_view and drop_view have different
2350 template<typename _Range>
2351 take_view(_Range&&, range_difference_t<_Range>)
2352 -> take_view<views::all_t<_Range>>;
2354 template<typename _Tp>
2355 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2356 = enable_borrowed_range<_Tp>;
2362 template<typename _Range>
2363 inline constexpr bool __is_empty_view = false;
2365 template<typename _Tp>
2366 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2368 template<typename _Range>
2369 inline constexpr bool __is_basic_string_view = false;
2371 template<typename _CharT, typename _Traits>
2372 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2375 using ranges::__detail::__is_subrange;
2377 template<typename _Range>
2378 inline constexpr bool __is_iota_view = false;
2380 template<typename _Winc, typename _Bound>
2381 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2383 template<typename _Range>
2384 inline constexpr bool __is_repeat_view = false;
2386 template<typename _Range>
2388 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2390 template<typename _Range, typename _Dp>
2391 concept __can_take_view
2392 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2393 } // namespace __detail
2395 struct _Take : __adaptor::_RangeAdaptor<_Take>
2397 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2398 requires __detail::__can_take_view<_Range, _Dp>
2400 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2402 using _Tp = remove_cvref_t<_Range>;
2403 if constexpr (__detail::__is_empty_view<_Tp>)
2405 else if constexpr (random_access_range<_Tp>
2407 && (std::__detail::__is_span<_Tp>
2408 || __detail::__is_basic_string_view<_Tp>
2409 || __detail::__is_subrange<_Tp>
2410 || __detail::__is_iota_view<_Tp>))
2412 __n = std::min<_Dp>(ranges::distance(__r), __n);
2413 auto __begin = ranges::begin(__r);
2414 auto __end = __begin + __n;
2415 if constexpr (std::__detail::__is_span<_Tp>)
2416 return span<typename _Tp::element_type>(__begin, __end);
2417 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2418 return _Tp(__begin, __end);
2419 else if constexpr (__detail::__is_subrange<_Tp>)
2420 return subrange<iterator_t<_Tp>>(__begin, __end);
2422 return iota_view(*__begin, *__end);
2424 else if constexpr (__detail::__is_repeat_view<_Tp>)
2425 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2427 return take_view(std::forward<_Range>(__r), __n);
2430 using _RangeAdaptor<_Take>::operator();
2431 static constexpr int _S_arity = 2;
2432 // The count argument of views::take is not always simple -- it can be
2433 // e.g. a move-only class that's implicitly convertible to the difference
2434 // type. But an integer-like count argument is surely simple.
2435 template<typename _Tp>
2436 static constexpr bool _S_has_simple_extra_args
2437 = ranges::__detail::__is_integer_like<_Tp>;
2440 inline constexpr _Take take;
2441 } // namespace views
2443 template<view _Vp, typename _Pred>
2444 requires input_range<_Vp> && is_object_v<_Pred>
2445 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2446 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2448 template<bool _Const>
2452 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2454 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2455 const _Pred* _M_pred = nullptr;
2458 _Sentinel() = default;
2461 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2462 : _M_end(__end), _M_pred(__pred)
2466 _Sentinel(_Sentinel<!_Const> __s)
2467 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2468 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2471 constexpr sentinel_t<_Base>
2472 base() const { return _M_end; }
2474 friend constexpr bool
2475 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2476 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2478 template<bool _OtherConst = !_Const,
2479 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2480 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2481 friend constexpr bool
2482 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2483 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2485 friend _Sentinel<!_Const>;
2488 _Vp _M_base = _Vp();
2489 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2492 take_while_view() requires (default_initializable<_Vp>
2493 && default_initializable<_Pred>)
2497 take_while_view(_Vp __base, _Pred __pred)
2498 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2502 base() const& requires copy_constructible<_Vp>
2507 { return std::move(_M_base); }
2509 constexpr const _Pred&
2511 { return *_M_pred; }
2514 begin() requires (!__detail::__simple_view<_Vp>)
2515 { return ranges::begin(_M_base); }
2518 begin() const requires range<const _Vp>
2519 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2520 { return ranges::begin(_M_base); }
2523 end() requires (!__detail::__simple_view<_Vp>)
2524 { return _Sentinel<false>(ranges::end(_M_base),
2525 std::__addressof(*_M_pred)); }
2528 end() const requires range<const _Vp>
2529 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2530 { return _Sentinel<true>(ranges::end(_M_base),
2531 std::__addressof(*_M_pred)); }
2534 template<typename _Range, typename _Pred>
2535 take_while_view(_Range&&, _Pred)
2536 -> take_while_view<views::all_t<_Range>, _Pred>;
2542 template<typename _Range, typename _Pred>
2543 concept __can_take_while_view
2544 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2545 } // namespace __detail
2547 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2549 template<viewable_range _Range, typename _Pred>
2550 requires __detail::__can_take_while_view<_Range, _Pred>
2552 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2554 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2557 using _RangeAdaptor<_TakeWhile>::operator();
2558 static constexpr int _S_arity = 2;
2559 static constexpr bool _S_has_simple_extra_args = true;
2562 inline constexpr _TakeWhile take_while;
2563 } // namespace views
2566 class drop_view : public view_interface<drop_view<_Vp>>
2569 _Vp _M_base = _Vp();
2570 range_difference_t<_Vp> _M_count = 0;
2572 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2573 // both random_access_range and sized_range. Otherwise, cache its result.
2574 static constexpr bool _S_needs_cached_begin
2575 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2576 [[no_unique_address]]
2577 __detail::__maybe_present_t<_S_needs_cached_begin,
2578 __detail::_CachedPosition<_Vp>>
2582 drop_view() requires default_initializable<_Vp> = default;
2585 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2586 : _M_base(std::move(__base)), _M_count(__count)
2587 { __glibcxx_assert(__count >= 0); }
2590 base() const& requires copy_constructible<_Vp>
2595 { return std::move(_M_base); }
2597 // This overload is disabled for simple views with constant-time begin().
2600 requires (!(__detail::__simple_view<_Vp>
2601 && random_access_range<const _Vp>
2602 && sized_range<const _Vp>))
2604 if constexpr (_S_needs_cached_begin)
2605 if (_M_cached_begin._M_has_value())
2606 return _M_cached_begin._M_get(_M_base);
2608 auto __it = ranges::next(ranges::begin(_M_base),
2609 _M_count, ranges::end(_M_base));
2610 if constexpr (_S_needs_cached_begin)
2611 _M_cached_begin._M_set(_M_base, __it);
2615 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2616 // 3482. drop_view's const begin should additionally require sized_range
2619 requires random_access_range<const _Vp> && sized_range<const _Vp>
2621 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2626 end() requires (!__detail::__simple_view<_Vp>)
2627 { return ranges::end(_M_base); }
2630 end() const requires range<const _Vp>
2631 { return ranges::end(_M_base); }
2634 size() requires sized_range<_Vp>
2636 const auto __s = ranges::size(_M_base);
2637 const auto __c = static_cast<decltype(__s)>(_M_count);
2638 return __s < __c ? 0 : __s - __c;
2642 size() const requires sized_range<const _Vp>
2644 const auto __s = ranges::size(_M_base);
2645 const auto __c = static_cast<decltype(__s)>(_M_count);
2646 return __s < __c ? 0 : __s - __c;
2650 template<typename _Range>
2651 drop_view(_Range&&, range_difference_t<_Range>)
2652 -> drop_view<views::all_t<_Range>>;
2654 template<typename _Tp>
2655 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2656 = enable_borrowed_range<_Tp>;
2662 template<typename _Range>
2664 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2666 template<typename _Range, typename _Dp>
2667 concept __can_drop_view
2668 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2669 } // namespace __detail
2671 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2673 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2674 requires __detail::__can_drop_view<_Range, _Dp>
2676 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2678 using _Tp = remove_cvref_t<_Range>;
2679 if constexpr (__detail::__is_empty_view<_Tp>)
2681 else if constexpr (random_access_range<_Tp>
2683 && (std::__detail::__is_span<_Tp>
2684 || __detail::__is_basic_string_view<_Tp>
2685 || __detail::__is_iota_view<_Tp>
2686 || __detail::__is_subrange<_Tp>))
2688 __n = std::min<_Dp>(ranges::distance(__r), __n);
2689 auto __begin = ranges::begin(__r) + __n;
2690 auto __end = ranges::end(__r);
2691 if constexpr (std::__detail::__is_span<_Tp>)
2692 return span<typename _Tp::element_type>(__begin, __end);
2693 else if constexpr (__detail::__is_subrange<_Tp>)
2695 if constexpr (_Tp::_S_store_size)
2697 using ranges::__detail::__to_unsigned_like;
2698 auto __m = ranges::distance(__r) - __n;
2699 return _Tp(__begin, __end, __to_unsigned_like(__m));
2702 return _Tp(__begin, __end);
2705 return _Tp(__begin, __end);
2707 else if constexpr (__detail::__is_repeat_view<_Tp>)
2708 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2710 return drop_view(std::forward<_Range>(__r), __n);
2713 using _RangeAdaptor<_Drop>::operator();
2714 static constexpr int _S_arity = 2;
2715 template<typename _Tp>
2716 static constexpr bool _S_has_simple_extra_args
2717 = _Take::_S_has_simple_extra_args<_Tp>;
2720 inline constexpr _Drop drop;
2721 } // namespace views
2723 template<view _Vp, typename _Pred>
2724 requires input_range<_Vp> && is_object_v<_Pred>
2725 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2726 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2729 _Vp _M_base = _Vp();
2730 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2731 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2734 drop_while_view() requires (default_initializable<_Vp>
2735 && default_initializable<_Pred>)
2739 drop_while_view(_Vp __base, _Pred __pred)
2740 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2744 base() const& requires copy_constructible<_Vp>
2749 { return std::move(_M_base); }
2751 constexpr const _Pred&
2753 { return *_M_pred; }
2758 if (_M_cached_begin._M_has_value())
2759 return _M_cached_begin._M_get(_M_base);
2761 __glibcxx_assert(_M_pred.has_value());
2762 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2763 ranges::end(_M_base),
2764 std::cref(*_M_pred));
2765 _M_cached_begin._M_set(_M_base, __it);
2771 { return ranges::end(_M_base); }
2774 template<typename _Range, typename _Pred>
2775 drop_while_view(_Range&&, _Pred)
2776 -> drop_while_view<views::all_t<_Range>, _Pred>;
2778 template<typename _Tp, typename _Pred>
2779 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2780 = enable_borrowed_range<_Tp>;
2786 template<typename _Range, typename _Pred>
2787 concept __can_drop_while_view
2788 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2789 } // namespace __detail
2791 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2793 template<viewable_range _Range, typename _Pred>
2794 requires __detail::__can_drop_while_view<_Range, _Pred>
2796 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2798 return drop_while_view(std::forward<_Range>(__r),
2799 std::forward<_Pred>(__p));
2802 using _RangeAdaptor<_DropWhile>::operator();
2803 static constexpr int _S_arity = 2;
2804 static constexpr bool _S_has_simple_extra_args = true;
2807 inline constexpr _DropWhile drop_while;
2808 } // namespace views
2812 template<typename _Tp>
2814 __as_lvalue(_Tp&& __t)
2815 { return static_cast<_Tp&>(__t); }
2816 } // namespace __detail
2818 template<input_range _Vp>
2819 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2820 class join_view : public view_interface<join_view<_Vp>>
2823 using _InnerRange = range_reference_t<_Vp>;
2825 template<bool _Const>
2826 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2828 template<bool _Const>
2829 using _Outer_iter = iterator_t<_Base<_Const>>;
2831 template<bool _Const>
2832 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2834 template<bool _Const>
2835 static constexpr bool _S_ref_is_glvalue
2836 = is_reference_v<range_reference_t<_Base<_Const>>>;
2838 template<bool _Const>
2842 template<bool _Const>
2843 requires _S_ref_is_glvalue<_Const>
2844 && forward_range<_Base<_Const>>
2845 && forward_range<range_reference_t<_Base<_Const>>>
2846 struct __iter_cat<_Const>
2849 static constexpr auto
2852 using _Outer_iter = join_view::_Outer_iter<_Const>;
2853 using _Inner_iter = join_view::_Inner_iter<_Const>;
2854 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2855 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2856 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2857 && derived_from<_InnerCat, bidirectional_iterator_tag>
2858 && common_range<range_reference_t<_Base<_Const>>>)
2859 return bidirectional_iterator_tag{};
2860 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2861 && derived_from<_InnerCat, forward_iterator_tag>)
2862 return forward_iterator_tag{};
2864 return input_iterator_tag{};
2867 using iterator_category = decltype(_S_iter_cat());
2870 template<bool _Const>
2873 template<bool _Const>
2874 struct _Iterator : __iter_cat<_Const>
2877 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2878 using _Base = join_view::_Base<_Const>;
2882 static constexpr bool _S_ref_is_glvalue
2883 = join_view::_S_ref_is_glvalue<_Const>;
2888 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2889 if constexpr (_S_ref_is_glvalue)
2892 return _M_parent->_M_inner._M_emplace_deref(__x);
2895 _Outer_iter& __outer = _M_get_outer();
2896 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2898 auto&& __inner = __update_inner(__outer);
2899 _M_inner = ranges::begin(__inner);
2900 if (_M_inner != ranges::end(__inner))
2904 if constexpr (_S_ref_is_glvalue)
2906 if constexpr (forward_iterator<_Inner_iter>)
2907 _M_inner = _Inner_iter();
2913 static constexpr auto
2916 if constexpr (_S_ref_is_glvalue
2917 && bidirectional_range<_Base>
2918 && bidirectional_range<range_reference_t<_Base>>
2919 && common_range<range_reference_t<_Base>>)
2920 return bidirectional_iterator_tag{};
2921 else if constexpr (_S_ref_is_glvalue
2922 && forward_range<_Base>
2923 && forward_range<range_reference_t<_Base>>)
2924 return forward_iterator_tag{};
2926 return input_iterator_tag{};
2929 using _Outer_iter = join_view::_Outer_iter<_Const>;
2930 using _Inner_iter = join_view::_Inner_iter<_Const>;
2932 constexpr _Outer_iter&
2935 if constexpr (forward_range<_Base>)
2938 return *_M_parent->_M_outer;
2941 constexpr const _Outer_iter&
2942 _M_get_outer() const
2944 if constexpr (forward_range<_Base>)
2947 return *_M_parent->_M_outer;
2950 constexpr _Inner_iter&
2951 _M_get_inner() noexcept
2953 if constexpr (forward_iterator<_Inner_iter>)
2959 constexpr const _Inner_iter&
2960 _M_get_inner() const noexcept
2962 if constexpr (forward_iterator<_Inner_iter>)
2969 _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base>
2970 : _M_outer(std::move(__outer)), _M_parent(__parent)
2974 _Iterator(_Parent* __parent) requires (!forward_range<_Base>)
2975 : _M_parent(__parent)
2978 [[no_unique_address]]
2979 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer
2980 = decltype(_M_outer)();
2981 __conditional_t<forward_iterator<_Inner_iter>,
2982 _Inner_iter, optional<_Inner_iter>> _M_inner
2983 = decltype(_M_inner)();
2984 _Parent* _M_parent = nullptr;
2987 using iterator_concept = decltype(_S_iter_concept());
2988 // iterator_category defined in __join_view_iter_cat
2989 using value_type = range_value_t<range_reference_t<_Base>>;
2990 using difference_type
2991 = common_type_t<range_difference_t<_Base>,
2992 range_difference_t<range_reference_t<_Base>>>;
2994 _Iterator() = default;
2997 _Iterator(_Iterator<!_Const> __i)
2999 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3000 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3001 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
3002 _M_parent(__i._M_parent)
3005 constexpr decltype(auto)
3007 { return *_M_get_inner(); }
3009 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3010 // 3500. join_view::iterator::operator->() is bogus
3011 constexpr _Inner_iter
3013 requires __detail::__has_arrow<_Inner_iter>
3014 && copyable<_Inner_iter>
3015 { return _M_get_inner(); }
3017 constexpr _Iterator&
3020 auto&& __inner_range = [this] () -> auto&& {
3021 if constexpr (_S_ref_is_glvalue)
3022 return *_M_get_outer();
3024 return *_M_parent->_M_inner;
3026 if (++_M_get_inner() == ranges::end(__inner_range))
3040 requires _S_ref_is_glvalue && forward_range<_Base>
3041 && forward_range<range_reference_t<_Base>>
3048 constexpr _Iterator&
3050 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3051 && bidirectional_range<range_reference_t<_Base>>
3052 && common_range<range_reference_t<_Base>>
3054 if (_M_outer == ranges::end(_M_parent->_M_base))
3055 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3056 while (_M_get_inner() == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3057 _M_get_inner() = ranges::end(__detail::__as_lvalue(*--_M_outer));
3064 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3065 && bidirectional_range<range_reference_t<_Base>>
3066 && common_range<range_reference_t<_Base>>
3073 friend constexpr bool
3074 operator==(const _Iterator& __x, const _Iterator& __y)
3075 requires _S_ref_is_glvalue
3076 && forward_range<_Base>
3077 && equality_comparable<_Inner_iter>
3079 return (__x._M_outer == __y._M_outer
3080 && __x._M_inner == __y._M_inner);
3083 friend constexpr decltype(auto)
3084 iter_move(const _Iterator& __i)
3085 noexcept(noexcept(ranges::iter_move(__i._M_get_inner())))
3086 { return ranges::iter_move(__i._M_get_inner()); }
3088 friend constexpr void
3089 iter_swap(const _Iterator& __x, const _Iterator& __y)
3090 noexcept(noexcept(ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner())))
3091 requires indirectly_swappable<_Inner_iter>
3092 { return ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner()); }
3094 friend _Iterator<!_Const>;
3095 template<bool> friend struct _Sentinel;
3098 template<bool _Const>
3102 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3103 using _Base = join_view::_Base<_Const>;
3105 template<bool _Const2>
3107 __equal(const _Iterator<_Const2>& __i) const
3108 { return __i._M_get_outer() == _M_end; }
3110 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3113 _Sentinel() = default;
3116 _Sentinel(_Parent* __parent)
3117 : _M_end(ranges::end(__parent->_M_base))
3121 _Sentinel(_Sentinel<!_Const> __s)
3122 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3123 : _M_end(std::move(__s._M_end))
3126 template<bool _Const2>
3127 requires sentinel_for<sentinel_t<_Base>,
3128 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3129 friend constexpr bool
3130 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3131 { return __y.__equal(__x); }
3133 friend _Sentinel<!_Const>;
3136 _Vp _M_base = _Vp();
3137 [[no_unique_address]]
3138 __detail::__maybe_present_t<!forward_range<_Vp>,
3139 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3140 [[no_unique_address]]
3141 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3144 join_view() requires default_initializable<_Vp> = default;
3147 join_view(_Vp __base)
3148 : _M_base(std::move(__base))
3152 base() const& requires copy_constructible<_Vp>
3157 { return std::move(_M_base); }
3162 if constexpr (forward_range<_Vp>)
3164 constexpr bool __use_const
3165 = (__detail::__simple_view<_Vp>
3166 && is_reference_v<range_reference_t<_Vp>>);
3167 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3171 _M_outer = ranges::begin(_M_base);
3172 return _Iterator<false>{this};
3178 requires forward_range<const _Vp>
3179 && is_reference_v<range_reference_t<const _Vp>>
3180 && input_range<range_reference_t<const _Vp>>
3182 return _Iterator<true>{this, ranges::begin(_M_base)};
3188 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3189 && forward_range<_InnerRange>
3190 && common_range<_Vp> && common_range<_InnerRange>)
3191 return _Iterator<__detail::__simple_view<_Vp>>{this,
3192 ranges::end(_M_base)};
3194 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3199 requires forward_range<const _Vp>
3200 && is_reference_v<range_reference_t<const _Vp>>
3201 && input_range<range_reference_t<const _Vp>>
3203 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3204 && forward_range<range_reference_t<const _Vp>>
3205 && common_range<const _Vp>
3206 && common_range<range_reference_t<const _Vp>>)
3207 return _Iterator<true>{this, ranges::end(_M_base)};
3209 return _Sentinel<true>{this};
3213 template<typename _Range>
3214 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3220 template<typename _Range>
3221 concept __can_join_view
3222 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3223 } // namespace __detail
3225 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3227 template<viewable_range _Range>
3228 requires __detail::__can_join_view<_Range>
3230 operator() [[nodiscard]] (_Range&& __r) const
3232 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3233 // 3474. Nesting join_views is broken because of CTAD
3234 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3237 static constexpr bool _S_has_simple_call_op = true;
3240 inline constexpr _Join join;
3241 } // namespace views
3246 struct __require_constant;
3248 template<typename _Range>
3249 concept __tiny_range = sized_range<_Range>
3251 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3252 && (remove_reference_t<_Range>::size() <= 1);
3254 template<typename _Base>
3255 struct __lazy_split_view_outer_iter_cat
3258 template<forward_range _Base>
3259 struct __lazy_split_view_outer_iter_cat<_Base>
3260 { using iterator_category = input_iterator_tag; };
3262 template<typename _Base>
3263 struct __lazy_split_view_inner_iter_cat
3266 template<forward_range _Base>
3267 struct __lazy_split_view_inner_iter_cat<_Base>
3270 static constexpr auto
3273 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3274 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3275 return forward_iterator_tag{};
3280 using iterator_category = decltype(_S_iter_cat());
3284 template<input_range _Vp, forward_range _Pattern>
3285 requires view<_Vp> && view<_Pattern>
3286 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3288 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3289 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3292 template<bool _Const>
3293 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3295 template<bool _Const>
3298 template<bool _Const>
3300 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3303 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3304 using _Base = lazy_split_view::_Base<_Const>;
3308 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3310 // [range.lazy.split.outer] p1
3311 // Many of the following specifications refer to the notional member
3312 // current of outer-iterator. current is equivalent to current_ if
3313 // V models forward_range, and parent_->current_ otherwise.
3315 __current() noexcept
3317 if constexpr (forward_range<_Vp>)
3320 return *_M_parent->_M_current;
3324 __current() const noexcept
3326 if constexpr (forward_range<_Vp>)
3329 return *_M_parent->_M_current;
3332 _Parent* _M_parent = nullptr;
3334 [[no_unique_address]]
3335 __detail::__maybe_present_t<forward_range<_Vp>,
3336 iterator_t<_Base>> _M_current
3337 = decltype(_M_current)();
3338 bool _M_trailing_empty = false;
3341 using iterator_concept = __conditional_t<forward_range<_Base>,
3342 forward_iterator_tag,
3343 input_iterator_tag>;
3344 // iterator_category defined in __lazy_split_view_outer_iter_cat
3345 using difference_type = range_difference_t<_Base>;
3347 struct value_type : view_interface<value_type>
3350 _OuterIter _M_i = _OuterIter();
3352 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3353 // 4013. lazy_split_view::outer-iterator::value_type should not
3354 // provide default constructor
3356 value_type(_OuterIter __i)
3357 : _M_i(std::move(__i))
3363 constexpr _InnerIter<_Const>
3365 { return _InnerIter<_Const>{_M_i}; }
3367 constexpr default_sentinel_t
3368 end() const noexcept
3369 { return default_sentinel; }
3372 _OuterIter() = default;
3375 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3376 : _M_parent(__parent)
3380 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3381 requires forward_range<_Base>
3382 : _M_parent(__parent),
3383 _M_current(std::move(__current))
3387 _OuterIter(_OuterIter<!_Const> __i)
3389 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3390 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3391 _M_trailing_empty(__i._M_trailing_empty)
3394 constexpr value_type
3396 { return value_type{*this}; }
3398 constexpr _OuterIter&
3401 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3402 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3403 const auto __end = ranges::end(_M_parent->_M_base);
3404 if (__current() == __end)
3406 _M_trailing_empty = false;
3409 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3410 if (__pbegin == __pend)
3412 else if constexpr (__detail::__tiny_range<_Pattern>)
3414 __current() = ranges::find(std::move(__current()), __end,
3416 if (__current() != __end)
3419 if (__current() == __end)
3420 _M_trailing_empty = true;
3427 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3431 if (__current() == __end)
3432 _M_trailing_empty = true;
3435 } while (++__current() != __end);
3439 constexpr decltype(auto)
3442 if constexpr (forward_range<_Base>)
3452 friend constexpr bool
3453 operator==(const _OuterIter& __x, const _OuterIter& __y)
3454 requires forward_range<_Base>
3456 return __x._M_current == __y._M_current
3457 && __x._M_trailing_empty == __y._M_trailing_empty;
3460 friend constexpr bool
3461 operator==(const _OuterIter& __x, default_sentinel_t)
3462 { return __x.__at_end(); };
3464 friend _OuterIter<!_Const>;
3465 friend _InnerIter<_Const>;
3468 template<bool _Const>
3470 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3473 using _Base = lazy_split_view::_Base<_Const>;
3478 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3479 auto __end = ranges::end(_M_i._M_parent->_M_base);
3480 if constexpr (__detail::__tiny_range<_Pattern>)
3482 const auto& __cur = _M_i_current();
3485 if (__pcur == __pend)
3486 return _M_incremented;
3487 return *__cur == *__pcur;
3491 auto __cur = _M_i_current();
3494 if (__pcur == __pend)
3495 return _M_incremented;
3498 if (*__cur != *__pcur)
3500 if (++__pcur == __pend)
3502 } while (++__cur != __end);
3508 _M_i_current() noexcept
3509 { return _M_i.__current(); }
3512 _M_i_current() const noexcept
3513 { return _M_i.__current(); }
3515 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3516 bool _M_incremented = false;
3519 using iterator_concept
3520 = typename _OuterIter<_Const>::iterator_concept;
3521 // iterator_category defined in __lazy_split_view_inner_iter_cat
3522 using value_type = range_value_t<_Base>;
3523 using difference_type = range_difference_t<_Base>;
3525 _InnerIter() = default;
3528 _InnerIter(_OuterIter<_Const> __i)
3529 : _M_i(std::move(__i))
3532 constexpr const iterator_t<_Base>&
3533 base() const& noexcept
3534 { return _M_i_current(); }
3536 constexpr iterator_t<_Base>
3537 base() && requires forward_range<_Vp>
3538 { return std::move(_M_i_current()); }
3540 constexpr decltype(auto)
3542 { return *_M_i_current(); }
3544 constexpr _InnerIter&
3547 _M_incremented = true;
3548 if constexpr (!forward_range<_Base>)
3549 if constexpr (_Pattern::size() == 0)
3555 constexpr decltype(auto)
3558 if constexpr (forward_range<_Base>)
3568 friend constexpr bool
3569 operator==(const _InnerIter& __x, const _InnerIter& __y)
3570 requires forward_range<_Base>
3571 { return __x._M_i == __y._M_i; }
3573 friend constexpr bool
3574 operator==(const _InnerIter& __x, default_sentinel_t)
3575 { return __x.__at_end(); }
3577 friend constexpr decltype(auto)
3578 iter_move(const _InnerIter& __i)
3579 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3580 { return ranges::iter_move(__i._M_i_current()); }
3582 friend constexpr void
3583 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3584 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3585 __y._M_i_current())))
3586 requires indirectly_swappable<iterator_t<_Base>>
3587 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3590 _Vp _M_base = _Vp();
3591 _Pattern _M_pattern = _Pattern();
3592 [[no_unique_address]]
3593 __detail::__maybe_present_t<!forward_range<_Vp>,
3594 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3598 lazy_split_view() requires (default_initializable<_Vp>
3599 && default_initializable<_Pattern>)
3603 lazy_split_view(_Vp __base, _Pattern __pattern)
3604 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3607 template<input_range _Range>
3608 requires constructible_from<_Vp, views::all_t<_Range>>
3609 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3611 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3612 : _M_base(views::all(std::forward<_Range>(__r))),
3613 _M_pattern(views::single(std::move(__e)))
3617 base() const& requires copy_constructible<_Vp>
3622 { return std::move(_M_base); }
3627 if constexpr (forward_range<_Vp>)
3629 constexpr bool __simple
3630 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3631 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3635 _M_current = ranges::begin(_M_base);
3636 return _OuterIter<false>{this};
3641 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3643 return _OuterIter<true>{this, ranges::begin(_M_base)};
3647 end() requires forward_range<_Vp> && common_range<_Vp>
3649 constexpr bool __simple
3650 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3651 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3657 if constexpr (forward_range<_Vp>
3658 && forward_range<const _Vp>
3659 && common_range<const _Vp>)
3660 return _OuterIter<true>{this, ranges::end(_M_base)};
3662 return default_sentinel;
3666 template<typename _Range, typename _Pattern>
3667 lazy_split_view(_Range&&, _Pattern&&)
3668 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3670 template<input_range _Range>
3671 lazy_split_view(_Range&&, range_value_t<_Range>)
3672 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3678 template<typename _Range, typename _Pattern>
3679 concept __can_lazy_split_view
3680 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3681 } // namespace __detail
3683 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3685 template<viewable_range _Range, typename _Pattern>
3686 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3688 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3690 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3693 using _RangeAdaptor<_LazySplit>::operator();
3694 static constexpr int _S_arity = 2;
3695 // The pattern argument of views::lazy_split is not always simple -- it can be
3696 // a non-view range, the value category of which affects whether the call
3697 // is well-formed. But a scalar or a view pattern argument is surely
3699 template<typename _Pattern>
3700 static constexpr bool _S_has_simple_extra_args
3701 = is_scalar_v<_Pattern> || (view<_Pattern>
3702 && copy_constructible<_Pattern>);
3705 inline constexpr _LazySplit lazy_split;
3706 } // namespace views
3708 template<forward_range _Vp, forward_range _Pattern>
3709 requires view<_Vp> && view<_Pattern>
3710 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3712 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3715 _Vp _M_base = _Vp();
3716 _Pattern _M_pattern = _Pattern();
3717 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3723 split_view() requires (default_initializable<_Vp>
3724 && default_initializable<_Pattern>)
3728 split_view(_Vp __base, _Pattern __pattern)
3729 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3732 template<forward_range _Range>
3733 requires constructible_from<_Vp, views::all_t<_Range>>
3734 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3736 split_view(_Range&& __r, range_value_t<_Range> __e)
3737 : _M_base(views::all(std::forward<_Range>(__r))),
3738 _M_pattern(views::single(std::move(__e)))
3742 base() const& requires copy_constructible<_Vp>
3747 { return std::move(_M_base); }
3752 if (!_M_cached_begin)
3753 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3754 return {this, ranges::begin(_M_base), *_M_cached_begin};
3760 if constexpr (common_range<_Vp>)
3761 return _Iterator{this, ranges::end(_M_base), {}};
3763 return _Sentinel{this};
3766 constexpr subrange<iterator_t<_Vp>>
3767 _M_find_next(iterator_t<_Vp> __it)
3769 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3770 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3782 split_view* _M_parent = nullptr;
3783 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3784 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3785 bool _M_trailing_empty = false;
3787 friend struct _Sentinel;
3790 using iterator_concept = forward_iterator_tag;
3791 using iterator_category = input_iterator_tag;
3792 using value_type = subrange<iterator_t<_Vp>>;
3793 using difference_type = range_difference_t<_Vp>;
3795 _Iterator() = default;
3798 _Iterator(split_view* __parent,
3799 iterator_t<_Vp> __current,
3800 subrange<iterator_t<_Vp>> __next)
3801 : _M_parent(__parent),
3802 _M_cur(std::move(__current)),
3803 _M_next(std::move(__next))
3806 constexpr iterator_t<_Vp>
3810 constexpr value_type
3812 { return {_M_cur, _M_next.begin()}; }
3814 constexpr _Iterator&
3817 _M_cur = _M_next.begin();
3818 if (_M_cur != ranges::end(_M_parent->_M_base))
3820 _M_cur = _M_next.end();
3821 if (_M_cur == ranges::end(_M_parent->_M_base))
3823 _M_trailing_empty = true;
3824 _M_next = {_M_cur, _M_cur};
3827 _M_next = _M_parent->_M_find_next(_M_cur);
3830 _M_trailing_empty = false;
3842 friend constexpr bool
3843 operator==(const _Iterator& __x, const _Iterator& __y)
3845 return __x._M_cur == __y._M_cur
3846 && __x._M_trailing_empty == __y._M_trailing_empty;
3853 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3856 _M_equal(const _Iterator& __x) const
3857 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3860 _Sentinel() = default;
3863 _Sentinel(split_view* __parent)
3864 : _M_end(ranges::end(__parent->_M_base))
3867 friend constexpr bool
3868 operator==(const _Iterator& __x, const _Sentinel& __y)
3869 { return __y._M_equal(__x); }
3873 template<typename _Range, typename _Pattern>
3874 split_view(_Range&&, _Pattern&&)
3875 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3877 template<forward_range _Range>
3878 split_view(_Range&&, range_value_t<_Range>)
3879 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3885 template<typename _Range, typename _Pattern>
3886 concept __can_split_view
3887 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3888 } // namespace __detail
3890 struct _Split : __adaptor::_RangeAdaptor<_Split>
3892 template<viewable_range _Range, typename _Pattern>
3893 requires __detail::__can_split_view<_Range, _Pattern>
3895 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3897 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3900 using _RangeAdaptor<_Split>::operator();
3901 static constexpr int _S_arity = 2;
3902 template<typename _Pattern>
3903 static constexpr bool _S_has_simple_extra_args
3904 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3907 inline constexpr _Split split;
3908 } // namespace views
3914 template<input_or_output_iterator _Iter>
3916 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3918 if constexpr (contiguous_iterator<_Iter>)
3919 return span(std::to_address(__i), __n);
3920 else if constexpr (random_access_iterator<_Iter>)
3921 return subrange(__i, __i + __n);
3923 return subrange(counted_iterator(std::move(__i), __n),
3928 inline constexpr _Counted counted{};
3929 } // namespace views
3932 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3933 class common_view : public view_interface<common_view<_Vp>>
3936 _Vp _M_base = _Vp();
3939 common_view() requires default_initializable<_Vp> = default;
3942 common_view(_Vp __r)
3943 : _M_base(std::move(__r))
3947 base() const& requires copy_constructible<_Vp>
3952 { return std::move(_M_base); }
3954 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3955 // 4012. common_view::begin/end are missing the simple-view check
3957 begin() requires (!__detail::__simple_view<_Vp>)
3959 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3960 return ranges::begin(_M_base);
3962 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3963 (ranges::begin(_M_base));
3967 begin() const requires range<const _Vp>
3969 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3970 return ranges::begin(_M_base);
3972 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3973 (ranges::begin(_M_base));
3977 end() requires (!__detail::__simple_view<_Vp>)
3979 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3980 return ranges::begin(_M_base) + ranges::size(_M_base);
3982 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3983 (ranges::end(_M_base));
3987 end() const requires range<const _Vp>
3989 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3990 return ranges::begin(_M_base) + ranges::size(_M_base);
3992 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3993 (ranges::end(_M_base));
3997 size() requires sized_range<_Vp>
3998 { return ranges::size(_M_base); }
4001 size() const requires sized_range<const _Vp>
4002 { return ranges::size(_M_base); }
4005 template<typename _Range>
4006 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4008 template<typename _Tp>
4009 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4010 = enable_borrowed_range<_Tp>;
4016 template<typename _Range>
4017 concept __already_common = common_range<_Range>
4018 && requires { views::all(std::declval<_Range>()); };
4020 template<typename _Range>
4021 concept __can_common_view
4022 = requires { common_view{std::declval<_Range>()}; };
4023 } // namespace __detail
4025 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4027 template<viewable_range _Range>
4028 requires __detail::__already_common<_Range>
4029 || __detail::__can_common_view<_Range>
4031 operator() [[nodiscard]] (_Range&& __r) const
4033 if constexpr (__detail::__already_common<_Range>)
4034 return views::all(std::forward<_Range>(__r));
4036 return common_view{std::forward<_Range>(__r)};
4039 static constexpr bool _S_has_simple_call_op = true;
4042 inline constexpr _Common common;
4043 } // namespace views
4046 requires bidirectional_range<_Vp>
4047 class reverse_view : public view_interface<reverse_view<_Vp>>
4050 static constexpr bool _S_needs_cached_begin
4051 = !common_range<_Vp> && !(random_access_range<_Vp>
4052 && sized_sentinel_for<sentinel_t<_Vp>,
4055 _Vp _M_base = _Vp();
4056 [[no_unique_address]]
4057 __detail::__maybe_present_t<_S_needs_cached_begin,
4058 __detail::_CachedPosition<_Vp>>
4062 reverse_view() requires default_initializable<_Vp> = default;
4065 reverse_view(_Vp __r)
4066 : _M_base(std::move(__r))
4070 base() const& requires copy_constructible<_Vp>
4075 { return std::move(_M_base); }
4077 constexpr reverse_iterator<iterator_t<_Vp>>
4080 if constexpr (_S_needs_cached_begin)
4081 if (_M_cached_begin._M_has_value())
4082 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
4084 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4085 if constexpr (_S_needs_cached_begin)
4086 _M_cached_begin._M_set(_M_base, __it);
4087 return std::make_reverse_iterator(std::move(__it));
4091 begin() requires common_range<_Vp>
4092 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4095 begin() const requires common_range<const _Vp>
4096 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4098 constexpr reverse_iterator<iterator_t<_Vp>>
4100 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4103 end() const requires common_range<const _Vp>
4104 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4107 size() requires sized_range<_Vp>
4108 { return ranges::size(_M_base); }
4111 size() const requires sized_range<const _Vp>
4112 { return ranges::size(_M_base); }
4115 template<typename _Range>
4116 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4118 template<typename _Tp>
4119 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4120 = enable_borrowed_range<_Tp>;
4127 inline constexpr bool __is_reversible_subrange = false;
4129 template<typename _Iter, subrange_kind _Kind>
4130 inline constexpr bool
4131 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4132 reverse_iterator<_Iter>,
4136 inline constexpr bool __is_reverse_view = false;
4138 template<typename _Vp>
4139 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
4141 template<typename _Range>
4142 concept __can_reverse_view
4143 = requires { reverse_view{std::declval<_Range>()}; };
4144 } // namespace __detail
4146 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4148 template<viewable_range _Range>
4149 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4150 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4151 || __detail::__can_reverse_view<_Range>
4153 operator() [[nodiscard]] (_Range&& __r) const
4155 using _Tp = remove_cvref_t<_Range>;
4156 if constexpr (__detail::__is_reverse_view<_Tp>)
4157 return std::forward<_Range>(__r).base();
4158 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4160 using _Iter = decltype(ranges::begin(__r).base());
4161 if constexpr (sized_range<_Tp>)
4162 return subrange<_Iter, _Iter, subrange_kind::sized>
4163 {__r.end().base(), __r.begin().base(), __r.size()};
4165 return subrange<_Iter, _Iter, subrange_kind::unsized>
4166 {__r.end().base(), __r.begin().base()};
4169 return reverse_view{std::forward<_Range>(__r)};
4172 static constexpr bool _S_has_simple_call_op = true;
4175 inline constexpr _Reverse reverse;
4176 } // namespace views
4180#if __cpp_lib_tuple_like // >= C++23
4181 template<typename _Tp, size_t _Nm>
4182 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4184 template<typename _Tp, size_t _Nm>
4185 concept __has_tuple_element = requires(_Tp __t)
4187 typename tuple_size<_Tp>::type;
4188 requires _Nm < tuple_size_v<_Tp>;
4189 typename tuple_element_t<_Nm, _Tp>;
4190 { std::get<_Nm>(__t) }
4191 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4195 template<typename _Tp, size_t _Nm>
4196 concept __returnable_element
4197 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4200 template<input_range _Vp, size_t _Nm>
4202 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4203 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4205 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4206 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4209 elements_view() requires default_initializable<_Vp> = default;
4212 elements_view(_Vp __base)
4213 : _M_base(std::move(__base))
4217 base() const& requires copy_constructible<_Vp>
4222 { return std::move(_M_base); }
4225 begin() requires (!__detail::__simple_view<_Vp>)
4226 { return _Iterator<false>(ranges::begin(_M_base)); }
4229 begin() const requires range<const _Vp>
4230 { return _Iterator<true>(ranges::begin(_M_base)); }
4233 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4234 { return _Sentinel<false>{ranges::end(_M_base)}; }
4237 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4238 { return _Iterator<false>{ranges::end(_M_base)}; }
4241 end() const requires range<const _Vp>
4242 { return _Sentinel<true>{ranges::end(_M_base)}; }
4245 end() const requires common_range<const _Vp>
4246 { return _Iterator<true>{ranges::end(_M_base)}; }
4249 size() requires sized_range<_Vp>
4250 { return ranges::size(_M_base); }
4253 size() const requires sized_range<const _Vp>
4254 { return ranges::size(_M_base); }
4257 template<bool _Const>
4258 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4260 template<bool _Const>
4264 template<bool _Const>
4265 requires forward_range<_Base<_Const>>
4266 struct __iter_cat<_Const>
4269 static auto _S_iter_cat()
4271 using _Base = elements_view::_Base<_Const>;
4272 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4273 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4274 if constexpr (!is_lvalue_reference_v<_Res>)
4275 return input_iterator_tag{};
4276 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4277 return random_access_iterator_tag{};
4282 using iterator_category = decltype(_S_iter_cat());
4285 template<bool _Const>
4288 template<bool _Const>
4289 struct _Iterator : __iter_cat<_Const>
4292 using _Base = elements_view::_Base<_Const>;
4294 iterator_t<_Base> _M_current = iterator_t<_Base>();
4296 static constexpr decltype(auto)
4297 _S_get_element(const iterator_t<_Base>& __i)
4299 if constexpr (is_reference_v<range_reference_t<_Base>>)
4300 return std::get<_Nm>(*__i);
4303 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4304 return static_cast<_Et>(std::get<_Nm>(*__i));
4311 if constexpr (random_access_range<_Base>)
4312 return random_access_iterator_tag{};
4313 else if constexpr (bidirectional_range<_Base>)
4314 return bidirectional_iterator_tag{};
4315 else if constexpr (forward_range<_Base>)
4316 return forward_iterator_tag{};
4318 return input_iterator_tag{};
4321 friend _Iterator<!_Const>;
4324 using iterator_concept = decltype(_S_iter_concept());
4325 // iterator_category defined in elements_view::__iter_cat
4327 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4328 using difference_type = range_difference_t<_Base>;
4330 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4333 _Iterator(iterator_t<_Base> __current)
4334 : _M_current(std::move(__current))
4338 _Iterator(_Iterator<!_Const> __i)
4339 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4340 : _M_current(std::move(__i._M_current))
4343 constexpr const iterator_t<_Base>&
4344 base() const& noexcept
4345 { return _M_current; }
4347 constexpr iterator_t<_Base>
4349 { return std::move(_M_current); }
4351 constexpr decltype(auto)
4353 { return _S_get_element(_M_current); }
4355 constexpr _Iterator&
4367 operator++(int) requires forward_range<_Base>
4374 constexpr _Iterator&
4375 operator--() requires bidirectional_range<_Base>
4382 operator--(int) requires bidirectional_range<_Base>
4389 constexpr _Iterator&
4390 operator+=(difference_type __n)
4391 requires random_access_range<_Base>
4397 constexpr _Iterator&
4398 operator-=(difference_type __n)
4399 requires random_access_range<_Base>
4405 constexpr decltype(auto)
4406 operator[](difference_type __n) const
4407 requires random_access_range<_Base>
4408 { return _S_get_element(_M_current + __n); }
4410 friend constexpr bool
4411 operator==(const _Iterator& __x, const _Iterator& __y)
4412 requires equality_comparable<iterator_t<_Base>>
4413 { return __x._M_current == __y._M_current; }
4415 friend constexpr bool
4416 operator<(const _Iterator& __x, const _Iterator& __y)
4417 requires random_access_range<_Base>
4418 { return __x._M_current < __y._M_current; }
4420 friend constexpr bool
4421 operator>(const _Iterator& __x, const _Iterator& __y)
4422 requires random_access_range<_Base>
4423 { return __y._M_current < __x._M_current; }
4425 friend constexpr bool
4426 operator<=(const _Iterator& __x, const _Iterator& __y)
4427 requires random_access_range<_Base>
4428 { return !(__y._M_current > __x._M_current); }
4430 friend constexpr bool
4431 operator>=(const _Iterator& __x, const _Iterator& __y)
4432 requires random_access_range<_Base>
4433 { return !(__x._M_current > __y._M_current); }
4435#ifdef __cpp_lib_three_way_comparison
4436 friend constexpr auto
4437 operator<=>(const _Iterator& __x, const _Iterator& __y)
4438 requires random_access_range<_Base>
4439 && three_way_comparable<iterator_t<_Base>>
4440 { return __x._M_current <=> __y._M_current; }
4443 friend constexpr _Iterator
4444 operator+(const _Iterator& __x, difference_type __y)
4445 requires random_access_range<_Base>
4446 { return _Iterator{__x} += __y; }
4448 friend constexpr _Iterator
4449 operator+(difference_type __x, const _Iterator& __y)
4450 requires random_access_range<_Base>
4451 { return __y + __x; }
4453 friend constexpr _Iterator
4454 operator-(const _Iterator& __x, difference_type __y)
4455 requires random_access_range<_Base>
4456 { return _Iterator{__x} -= __y; }
4458 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4459 // 3483. transform_view::iterator's difference is overconstrained
4460 friend constexpr difference_type
4461 operator-(const _Iterator& __x, const _Iterator& __y)
4462 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4463 { return __x._M_current - __y._M_current; }
4465 template <bool> friend struct _Sentinel;
4468 template<bool _Const>
4472 template<bool _Const2>
4474 _M_equal(const _Iterator<_Const2>& __x) const
4475 { return __x._M_current == _M_end; }
4477 template<bool _Const2>
4479 _M_distance_from(const _Iterator<_Const2>& __i) const
4480 { return _M_end - __i._M_current; }
4482 using _Base = elements_view::_Base<_Const>;
4483 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4486 _Sentinel() = default;
4489 _Sentinel(sentinel_t<_Base> __end)
4490 : _M_end(std::move(__end))
4494 _Sentinel(_Sentinel<!_Const> __other)
4496 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4497 : _M_end(std::move(__other._M_end))
4500 constexpr sentinel_t<_Base>
4504 template<bool _Const2>
4505 requires sentinel_for<sentinel_t<_Base>,
4506 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4507 friend constexpr bool
4508 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4509 { return __y._M_equal(__x); }
4511 template<bool _Const2,
4512 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4513 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4514 friend constexpr range_difference_t<_Base2>
4515 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4516 { return -__y._M_distance_from(__x); }
4518 template<bool _Const2,
4519 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4520 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4521 friend constexpr range_difference_t<_Base2>
4522 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4523 { return __x._M_distance_from(__y); }
4525 friend _Sentinel<!_Const>;
4528 _Vp _M_base = _Vp();
4531 template<typename _Tp, size_t _Nm>
4532 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4533 = enable_borrowed_range<_Tp>;
4535 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4536 // 3563. keys_view example is broken
4537 template<typename _Range>
4538 using keys_view = elements_view<_Range, 0>;
4540 template<typename _Range>
4541 using values_view = elements_view<_Range, 1>;
4547 template<size_t _Nm, typename _Range>
4548 concept __can_elements_view
4549 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4550 } // namespace __detail
4552 template<size_t _Nm>
4553 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4555 template<viewable_range _Range>
4556 requires __detail::__can_elements_view<_Nm, _Range>
4558 operator() [[nodiscard]] (_Range&& __r) const
4560 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4563 static constexpr bool _S_has_simple_call_op = true;
4566 template<size_t _Nm>
4567 inline constexpr _Elements<_Nm> elements;
4568 inline constexpr auto keys = elements<0>;
4569 inline constexpr auto values = elements<1>;
4570 } // namespace views
4572#ifdef __cpp_lib_ranges_zip // C++ >= 23
4575 template<typename... _Rs>
4576 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4577 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4578 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4580 template<typename _Fp, typename _Tuple>
4582 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4584 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4585 return tuple<invoke_result_t<_Fp&, _Ts>...>
4586 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4587 }, std::forward<_Tuple>(__tuple));
4590 template<typename _Fp, typename _Tuple>
4592 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4594 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4595 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4596 }, std::forward<_Tuple>(__tuple));
4598 } // namespace __detail
4600 template<input_range... _Vs>
4601 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4602 class zip_view : public view_interface<zip_view<_Vs...>>
4604 tuple<_Vs...> _M_views;
4606 template<bool> class _Iterator;
4607 template<bool> class _Sentinel;
4610 zip_view() = default;
4613 zip_view(_Vs... __views)
4614 : _M_views(std::move(__views)...)
4618 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4619 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4622 begin() const requires (range<const _Vs> && ...)
4623 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4626 end() requires (!(__detail::__simple_view<_Vs> && ...))
4628 if constexpr (!__detail::__zip_is_common<_Vs...>)
4629 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4630 else if constexpr ((random_access_range<_Vs> && ...))
4631 return begin() + iter_difference_t<_Iterator<false>>(size());
4633 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4637 end() const requires (range<const _Vs> && ...)
4639 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4640 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4641 else if constexpr ((random_access_range<const _Vs> && ...))
4642 return begin() + iter_difference_t<_Iterator<true>>(size());
4644 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4648 size() requires (sized_range<_Vs> && ...)
4650 return std::apply([](auto... sizes) {
4651 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4652 return ranges::min({_CT(sizes)...});
4653 }, __detail::__tuple_transform(ranges::size, _M_views));
4657 size() const requires (sized_range<const _Vs> && ...)
4659 return std::apply([](auto... sizes) {
4660 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4661 return ranges::min({_CT(sizes)...});
4662 }, __detail::__tuple_transform(ranges::size, _M_views));
4666 template<typename... _Rs>
4667 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4669 template<typename... _Views>
4670 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4671 = (enable_borrowed_range<_Views> && ...);
4675 template<bool _Const, typename... _Vs>
4676 concept __all_random_access
4677 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4679 template<bool _Const, typename... _Vs>
4680 concept __all_bidirectional
4681 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4683 template<bool _Const, typename... _Vs>
4684 concept __all_forward
4685 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4687 template<bool _Const, typename... _Views>
4688 struct __zip_view_iter_cat
4691 template<bool _Const, typename... _Views>
4692 requires __all_forward<_Const, _Views...>
4693 struct __zip_view_iter_cat<_Const, _Views...>
4694 { using iterator_category = input_iterator_tag; };
4695 } // namespace __detail
4697 template<input_range... _Vs>
4698 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4699 template<bool _Const>
4700 class zip_view<_Vs...>::_Iterator
4701 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4703#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
4706 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4709 _Iterator(decltype(_M_current) __current)
4710 : _M_current(std::move(__current))
4716 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4717 return random_access_iterator_tag{};
4718 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4719 return bidirectional_iterator_tag{};
4720 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4721 return forward_iterator_tag{};
4723 return input_iterator_tag{};
4726#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
4727 template<move_constructible _Fp, input_range... _Ws>
4728 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4729 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4730 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4731 friend class zip_transform_view;
4735 // iterator_category defined in __zip_view_iter_cat
4736 using iterator_concept = decltype(_S_iter_concept());
4738 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4739 using difference_type
4740 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4742 _Iterator() = default;
4745 _Iterator(_Iterator<!_Const> __i)
4747 && (convertible_to<iterator_t<_Vs>,
4748 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4749 : _M_current(std::move(__i._M_current))
4755 auto __f = [](auto& __i) -> decltype(auto) {
4758 return __detail::__tuple_transform(__f, _M_current);
4761 constexpr _Iterator&
4764 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4774 requires __detail::__all_forward<_Const, _Vs...>
4781 constexpr _Iterator&
4783 requires __detail::__all_bidirectional<_Const, _Vs...>
4785 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4791 requires __detail::__all_bidirectional<_Const, _Vs...>
4798 constexpr _Iterator&
4799 operator+=(difference_type __x)
4800 requires __detail::__all_random_access<_Const, _Vs...>
4802 auto __f = [&]<typename _It>(_It& __i) {
4803 __i += iter_difference_t<_It>(__x);
4805 __detail::__tuple_for_each(__f, _M_current);
4809 constexpr _Iterator&
4810 operator-=(difference_type __x)
4811 requires __detail::__all_random_access<_Const, _Vs...>
4813 auto __f = [&]<typename _It>(_It& __i) {
4814 __i -= iter_difference_t<_It>(__x);
4816 __detail::__tuple_for_each(__f, _M_current);
4821 operator[](difference_type __n) const
4822 requires __detail::__all_random_access<_Const, _Vs...>
4824 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4825 return __i[iter_difference_t<_It>(__n)];
4827 return __detail::__tuple_transform(__f, _M_current);
4830 friend constexpr bool
4831 operator==(const _Iterator& __x, const _Iterator& __y)
4832 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4834 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4835 return __x._M_current == __y._M_current;
4837 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4838 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4839 }(make_index_sequence<sizeof...(_Vs)>{});
4842 friend constexpr auto
4843 operator<=>(const _Iterator& __x, const _Iterator& __y)
4844 requires __detail::__all_random_access<_Const, _Vs...>
4845 { return __x._M_current <=> __y._M_current; }
4847 friend constexpr _Iterator
4848 operator+(const _Iterator& __i, difference_type __n)
4849 requires __detail::__all_random_access<_Const, _Vs...>
4856 friend constexpr _Iterator
4857 operator+(difference_type __n, const _Iterator& __i)
4858 requires __detail::__all_random_access<_Const, _Vs...>
4865 friend constexpr _Iterator
4866 operator-(const _Iterator& __i, difference_type __n)
4867 requires __detail::__all_random_access<_Const, _Vs...>
4874 friend constexpr difference_type
4875 operator-(const _Iterator& __x, const _Iterator& __y)
4876 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4877 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4879 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4880 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4881 - std::get<_Is>(__y._M_current))...},
4883 [](difference_type __i) {
4884 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4886 }(make_index_sequence<sizeof...(_Vs)>{});
4889 friend constexpr auto
4890 iter_move(const _Iterator& __i)
4891 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4893 friend constexpr void
4894 iter_swap(const _Iterator& __l, const _Iterator& __r)
4895 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4897 [&]<size_t... _Is>(index_sequence<_Is...>) {
4898 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4899 }(make_index_sequence<sizeof...(_Vs)>{});
4902 friend class zip_view;
4905 template<input_range... _Vs>
4906 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4907 template<bool _Const>
4908 class zip_view<_Vs...>::_Sentinel
4910 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4913 _Sentinel(decltype(_M_end) __end)
4917 friend class zip_view;
4920 _Sentinel() = default;
4923 _Sentinel(_Sentinel<!_Const> __i)
4925 && (convertible_to<sentinel_t<_Vs>,
4926 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4927 : _M_end(std::move(__i._M_end))
4930 template<bool _OtherConst>
4931 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4932 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4933 friend constexpr bool
4934 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4936 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4937 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4938 }(make_index_sequence<sizeof...(_Vs)>{});
4941 template<bool _OtherConst>
4942 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4943 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4944 friend constexpr auto
4945 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4948 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4949 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4950 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4953 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4955 }(make_index_sequence<sizeof...(_Vs)>{});
4958 template<bool _OtherConst>
4959 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4960 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4961 friend constexpr auto
4962 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4963 { return -(__x - __y); }
4970 template<typename... _Ts>
4971 concept __can_zip_view
4972 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4977 template<typename... _Ts>
4978 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4980 operator() [[nodiscard]] (_Ts&&... __ts) const
4982 if constexpr (sizeof...(_Ts) == 0)
4983 return views::empty<tuple<>>;
4985 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4989 inline constexpr _Zip zip;
4994 template<typename _Range, bool _Const>
4995 using __range_iter_cat
4996 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
4999 template<move_constructible _Fp, input_range... _Vs>
5000 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5001 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5002 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5003 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
5005 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5006 zip_view<_Vs...> _M_zip;
5008 using _InnerView = zip_view<_Vs...>;
5010 template<bool _Const>
5011 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5013 template<bool _Const>
5014 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5016 template<bool _Const>
5017 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5019 template<bool _Const>
5023 template<bool _Const>
5024 requires forward_range<_Base<_Const>>
5025 struct __iter_cat<_Const>
5031 using __detail::__maybe_const_t;
5032 using __detail::__range_iter_cat;
5033 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5034 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5035 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5036 // 3798. Rvalue reference and iterator_category
5037 if constexpr (!is_reference_v<_Res>)
5038 return input_iterator_tag{};
5039 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5040 random_access_iterator_tag> && ...))
5041 return random_access_iterator_tag{};
5042 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5043 bidirectional_iterator_tag> && ...))
5044 return bidirectional_iterator_tag{};
5045 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5046 forward_iterator_tag> && ...))
5047 return forward_iterator_tag{};
5049 return input_iterator_tag{};
5052 using iterator_category = decltype(_S_iter_cat());
5055 template<bool> class _Iterator;
5056 template<bool> class _Sentinel;
5059 zip_transform_view() = default;
5062 zip_transform_view(_Fp __fun, _Vs... __views)
5063 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5068 { return _Iterator<false>(*this, _M_zip.begin()); }
5072 requires range<const _InnerView>
5073 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5074 { return _Iterator<true>(*this, _M_zip.begin()); }
5079 if constexpr (common_range<_InnerView>)
5080 return _Iterator<false>(*this, _M_zip.end());
5082 return _Sentinel<false>(_M_zip.end());
5087 requires range<const _InnerView>
5088 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5090 if constexpr (common_range<const _InnerView>)
5091 return _Iterator<true>(*this, _M_zip.end());
5093 return _Sentinel<true>(_M_zip.end());
5097 size() requires sized_range<_InnerView>
5098 { return _M_zip.size(); }
5101 size() const requires sized_range<const _InnerView>
5102 { return _M_zip.size(); }
5105 template<class _Fp, class... Rs>
5106 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5108 template<move_constructible _Fp, input_range... _Vs>
5109 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5110 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5111 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5112 template<bool _Const>
5113 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5115 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5117 _Parent* _M_parent = nullptr;
5118 __ziperator<_Const> _M_inner;
5121 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5122 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5125 friend class zip_transform_view;
5128 // iterator_category defined in zip_transform_view::__iter_cat
5129 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
5131 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5132 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5133 using difference_type = range_difference_t<_Base<_Const>>;
5135 _Iterator() = default;
5138 _Iterator(_Iterator<!_Const> __i)
5139 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5140 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5143 constexpr decltype(auto)
5146 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5147 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5148 }, _M_inner._M_current);
5151 constexpr _Iterator&
5163 operator++(int) requires forward_range<_Base<_Const>>
5170 constexpr _Iterator&
5171 operator--() requires bidirectional_range<_Base<_Const>>
5178 operator--(int) requires bidirectional_range<_Base<_Const>>
5185 constexpr _Iterator&
5186 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5192 constexpr _Iterator&
5193 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5199 constexpr decltype(auto)
5200 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5202 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5203 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5204 }, _M_inner._M_current);
5207 friend constexpr bool
5208 operator==(const _Iterator& __x, const _Iterator& __y)
5209 requires equality_comparable<__ziperator<_Const>>
5210 { return __x._M_inner == __y._M_inner; }
5212 friend constexpr auto
5213 operator<=>(const _Iterator& __x, const _Iterator& __y)
5214 requires random_access_range<_Base<_Const>>
5215 { return __x._M_inner <=> __y._M_inner; }
5217 friend constexpr _Iterator
5218 operator+(const _Iterator& __i, difference_type __n)
5219 requires random_access_range<_Base<_Const>>
5220 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5222 friend constexpr _Iterator
5223 operator+(difference_type __n, const _Iterator& __i)
5224 requires random_access_range<_Base<_Const>>
5225 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5227 friend constexpr _Iterator
5228 operator-(const _Iterator& __i, difference_type __n)
5229 requires random_access_range<_Base<_Const>>
5230 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5232 friend constexpr difference_type
5233 operator-(const _Iterator& __x, const _Iterator& __y)
5234 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5235 { return __x._M_inner - __y._M_inner; }
5238 template<move_constructible _Fp, input_range... _Vs>
5239 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5240 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5241 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5242 template<bool _Const>
5243 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5245 __zentinel<_Const> _M_inner;
5248 _Sentinel(__zentinel<_Const> __inner)
5252 friend class zip_transform_view;
5255 _Sentinel() = default;
5258 _Sentinel(_Sentinel<!_Const> __i)
5259 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5260 : _M_inner(std::move(__i._M_inner))
5263 template<bool _OtherConst>
5264 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5265 friend constexpr bool
5266 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5267 { return __x._M_inner == __y._M_inner; }
5269 template<bool _OtherConst>
5270 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5271 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5272 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5273 { return __x._M_inner - __y._M_inner; }
5275 template<bool _OtherConst>
5276 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5277 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5278 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5279 { return __x._M_inner - __y._M_inner; }
5286 template<typename _Fp, typename... _Ts>
5287 concept __can_zip_transform_view
5288 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5291 struct _ZipTransform
5293 template<typename _Fp>
5294 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
5295 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
5297 operator() [[nodiscard]] (_Fp&&) const
5299 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5302 template<typename _Fp, typename... _Ts>
5303 requires (sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
5305 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5307 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5311 inline constexpr _ZipTransform zip_transform;
5314 template<forward_range _Vp, size_t _Nm>
5315 requires view<_Vp> && (_Nm > 0)
5316 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5318 _Vp _M_base = _Vp();
5320 template<bool> class _Iterator;
5321 template<bool> class _Sentinel;
5323 struct __as_sentinel
5327 adjacent_view() requires default_initializable<_Vp> = default;
5330 adjacent_view(_Vp __base)
5331 : _M_base(std::move(__base))
5334 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5335 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5337 base() const & requires copy_constructible<_Vp>
5342 { return std::move(_M_base); }
5345 begin() requires (!__detail::__simple_view<_Vp>)
5346 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5349 begin() const requires range<const _Vp>
5350 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5353 end() requires (!__detail::__simple_view<_Vp>)
5355 if constexpr (common_range<_Vp>)
5356 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5358 return _Sentinel<false>(ranges::end(_M_base));
5362 end() const requires range<const _Vp>
5364 if constexpr (common_range<const _Vp>)
5365 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5367 return _Sentinel<true>(ranges::end(_M_base));
5371 size() requires sized_range<_Vp>
5373 using _ST = decltype(ranges::size(_M_base));
5374 using _CT = common_type_t<_ST, size_t>;
5375 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5376 __sz -= std::min<_CT>(__sz, _Nm - 1);
5377 return static_cast<_ST>(__sz);
5381 size() const requires sized_range<const _Vp>
5383 using _ST = decltype(ranges::size(_M_base));
5384 using _CT = common_type_t<_ST, size_t>;
5385 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5386 __sz -= std::min<_CT>(__sz, _Nm - 1);
5387 return static_cast<_ST>(__sz);
5391 template<typename _Vp, size_t _Nm>
5392 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5393 = enable_borrowed_range<_Vp>;
5397 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5398 template<typename _Tp, size_t _Nm>
5399 using __repeated_tuple = typename __make_tuple<array<_Tp, _Nm>>::__type;
5401 // For a functor F that is callable with N arguments, the expression
5402 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5403 template<typename _Fp, size_t _Nm>
5406 template<typename... _Ts>
5407 static invoke_result_t<_Fp, _Ts...>
5408 __tuple_apply(const tuple<_Ts...>&); // not defined
5410 template<typename _Tp>
5411 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5412 operator()(_Tp&&); // not defined
5416 template<forward_range _Vp, size_t _Nm>
5417 requires view<_Vp> && (_Nm > 0)
5418 template<bool _Const>
5419 class adjacent_view<_Vp, _Nm>::_Iterator
5421#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
5424 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5425 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5428 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5430 for (auto& __i : _M_current)
5433 ranges::advance(__first, 1, __last);
5438 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5440 if constexpr (!bidirectional_range<_Base>)
5441 for (auto& __it : _M_current)
5444 for (size_t __i = 0; __i < _Nm; ++__i)
5446 _M_current[_Nm - 1 - __i] = __last;
5447 ranges::advance(__last, -1, __first);
5454 if constexpr (random_access_range<_Base>)
5455 return random_access_iterator_tag{};
5456 else if constexpr (bidirectional_range<_Base>)
5457 return bidirectional_iterator_tag{};
5459 return forward_iterator_tag{};
5462 friend class adjacent_view;
5464#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
5465 template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
5466 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5467 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5468 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5469 range_reference_t<_Wp>>>
5470 friend class adjacent_transform_view;
5474 using iterator_category = input_iterator_tag;
5475 using iterator_concept = decltype(_S_iter_concept());
5476 using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
5477 using difference_type = range_difference_t<_Base>;
5479 _Iterator() = default;
5482 _Iterator(_Iterator<!_Const> __i)
5483 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5485 for (size_t __j = 0; __j < _Nm; ++__j)
5486 _M_current[__j] = std::move(__i._M_current[__j]);
5492 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5493 return __detail::__tuple_transform(__f, _M_current);
5496 constexpr _Iterator&
5499 for (auto& __i : _M_current)
5512 constexpr _Iterator&
5513 operator--() requires bidirectional_range<_Base>
5515 for (auto& __i : _M_current)
5521 operator--(int) requires bidirectional_range<_Base>
5528 constexpr _Iterator&
5529 operator+=(difference_type __x)
5530 requires random_access_range<_Base>
5532 for (auto& __i : _M_current)
5537 constexpr _Iterator&
5538 operator-=(difference_type __x)
5539 requires random_access_range<_Base>
5541 for (auto& __i : _M_current)
5547 operator[](difference_type __n) const
5548 requires random_access_range<_Base>
5550 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5551 return __detail::__tuple_transform(__f, _M_current);
5554 friend constexpr bool
5555 operator==(const _Iterator& __x, const _Iterator& __y)
5556 { return __x._M_current.back() == __y._M_current.back(); }
5558 friend constexpr bool
5559 operator<(const _Iterator& __x, const _Iterator& __y)
5560 requires random_access_range<_Base>
5561 { return __x._M_current.back() < __y._M_current.back(); }
5563 friend constexpr bool
5564 operator>(const _Iterator& __x, const _Iterator& __y)
5565 requires random_access_range<_Base>
5566 { return __y < __x; }
5568 friend constexpr bool
5569 operator<=(const _Iterator& __x, const _Iterator& __y)
5570 requires random_access_range<_Base>
5571 { return !(__y < __x); }
5573 friend constexpr bool
5574 operator>=(const _Iterator& __x, const _Iterator& __y)
5575 requires random_access_range<_Base>
5576 { return !(__x < __y); }
5578 friend constexpr auto
5579 operator<=>(const _Iterator& __x, const _Iterator& __y)
5580 requires random_access_range<_Base>
5581 && three_way_comparable<iterator_t<_Base>>
5582 { return __x._M_current.back() <=> __y._M_current.back(); }
5584 friend constexpr _Iterator
5585 operator+(const _Iterator& __i, difference_type __n)
5586 requires random_access_range<_Base>
5593 friend constexpr _Iterator
5594 operator+(difference_type __n, const _Iterator& __i)
5595 requires random_access_range<_Base>
5602 friend constexpr _Iterator
5603 operator-(const _Iterator& __i, difference_type __n)
5604 requires random_access_range<_Base>
5611 friend constexpr difference_type
5612 operator-(const _Iterator& __x, const _Iterator& __y)
5613 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5614 { return __x._M_current.back() - __y._M_current.back(); }
5616 friend constexpr auto
5617 iter_move(const _Iterator& __i)
5618 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5620 friend constexpr void
5621 iter_swap(const _Iterator& __l, const _Iterator& __r)
5622 requires indirectly_swappable<iterator_t<_Base>>
5624 for (size_t __i = 0; __i < _Nm; __i++)
5625 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5629 template<forward_range _Vp, size_t _Nm>
5630 requires view<_Vp> && (_Nm > 0)
5631 template<bool _Const>
5632 class adjacent_view<_Vp, _Nm>::_Sentinel
5634 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5636 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5639 _Sentinel(sentinel_t<_Base> __end)
5643 friend class adjacent_view;
5646 _Sentinel() = default;
5649 _Sentinel(_Sentinel<!_Const> __i)
5650 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5651 : _M_end(std::move(__i._M_end))
5654 template<bool _OtherConst>
5655 requires sentinel_for<sentinel_t<_Base>,
5656 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5657 friend constexpr bool
5658 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5659 { return __x._M_current.back() == __y._M_end; }
5661 template<bool _OtherConst>
5662 requires sized_sentinel_for<sentinel_t<_Base>,
5663 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5664 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5665 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5666 { return __x._M_current.back() - __y._M_end; }
5668 template<bool _OtherConst>
5669 requires sized_sentinel_for<sentinel_t<_Base>,
5670 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5671 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5672 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5673 { return __y._M_end - __x._M_current.back(); }
5680 template<size_t _Nm, typename _Range>
5681 concept __can_adjacent_view
5682 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5685 template<size_t _Nm>
5686 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5688 template<viewable_range _Range>
5689 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5691 operator() [[nodiscard]] (_Range&& __r) const
5693 if constexpr (_Nm == 0)
5694 return views::empty<tuple<>>;
5696 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5700 template<size_t _Nm>
5701 inline constexpr _Adjacent<_Nm> adjacent;
5703 inline constexpr auto pairwise = adjacent<2>;
5706 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5707 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5708 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5709 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5710 range_reference_t<_Vp>>>
5711 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5713 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5714 adjacent_view<_Vp, _Nm> _M_inner;
5716 using _InnerView = adjacent_view<_Vp, _Nm>;
5718 template<bool _Const>
5719 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5721 template<bool _Const>
5722 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5724 template<bool> class _Iterator;
5725 template<bool> class _Sentinel;
5728 adjacent_transform_view() = default;
5731 adjacent_transform_view(_Vp __base, _Fp __fun)
5732 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5735 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5736 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5737 // 3947. Unexpected constraints on adjacent_transform_view::base()
5739 base() const & requires copy_constructible<_Vp>
5740 { return _M_inner.base(); }
5744 { return std::move(_M_inner.base()); }
5748 { return _Iterator<false>(*this, _M_inner.begin()); }
5752 requires range<const _InnerView>
5753 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5754 range_reference_t<const _Vp>>
5755 { return _Iterator<true>(*this, _M_inner.begin()); }
5760 if constexpr (common_range<_InnerView>)
5761 return _Iterator<false>(*this, _M_inner.end());
5763 return _Sentinel<false>(_M_inner.end());
5768 requires range<const _InnerView>
5769 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5770 range_reference_t<const _Vp>>
5772 if constexpr (common_range<const _InnerView>)
5773 return _Iterator<true>(*this, _M_inner.end());
5775 return _Sentinel<true>(_M_inner.end());
5779 size() requires sized_range<_InnerView>
5780 { return _M_inner.size(); }
5783 size() const requires sized_range<const _InnerView>
5784 { return _M_inner.size(); }
5787 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5788 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5789 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5790 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5791 range_reference_t<_Vp>>>
5792 template<bool _Const>
5793 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5795 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5796 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5798 _Parent* _M_parent = nullptr;
5799 _InnerIter<_Const> _M_inner;
5802 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5803 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5809 using __detail::__maybe_const_t;
5810 using __detail::__unarize;
5811 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5812 range_reference_t<_Base>>;
5813 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5814 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5815 // 3798. Rvalue reference and iterator_category
5816 if constexpr (!is_reference_v<_Res>)
5817 return input_iterator_tag{};
5818 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5819 return random_access_iterator_tag{};
5820 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5821 return bidirectional_iterator_tag{};
5822 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5823 return forward_iterator_tag{};
5825 return input_iterator_tag{};
5828 friend class adjacent_transform_view;
5831 using iterator_category = decltype(_S_iter_cat());
5832 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5834 = remove_cvref_t<invoke_result_t
5835 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5836 range_reference_t<_Base>>>;
5837 using difference_type = range_difference_t<_Base>;
5839 _Iterator() = default;
5842 _Iterator(_Iterator<!_Const> __i)
5843 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5844 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5847 constexpr decltype(auto)
5850 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5851 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5852 }, _M_inner._M_current);
5855 constexpr _Iterator&
5870 constexpr _Iterator&
5871 operator--() requires bidirectional_range<_Base>
5878 operator--(int) requires bidirectional_range<_Base>
5885 constexpr _Iterator&
5886 operator+=(difference_type __x) requires random_access_range<_Base>
5892 constexpr _Iterator&
5893 operator-=(difference_type __x) requires random_access_range<_Base>
5899 constexpr decltype(auto)
5900 operator[](difference_type __n) const requires random_access_range<_Base>
5902 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5903 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5904 }, _M_inner._M_current);
5907 friend constexpr bool
5908 operator==(const _Iterator& __x, const _Iterator& __y)
5909 { return __x._M_inner == __y._M_inner; }
5911 friend constexpr bool
5912 operator<(const _Iterator& __x, const _Iterator& __y)
5913 requires random_access_range<_Base>
5914 { return __x._M_inner < __y._M_inner; }
5916 friend constexpr bool
5917 operator>(const _Iterator& __x, const _Iterator& __y)
5918 requires random_access_range<_Base>
5919 { return __x._M_inner > __y._M_inner; }
5921 friend constexpr bool
5922 operator<=(const _Iterator& __x, const _Iterator& __y)
5923 requires random_access_range<_Base>
5924 { return __x._M_inner <= __y._M_inner; }
5926 friend constexpr bool
5927 operator>=(const _Iterator& __x, const _Iterator& __y)
5928 requires random_access_range<_Base>
5929 { return __x._M_inner >= __y._M_inner; }
5931 friend constexpr auto
5932 operator<=>(const _Iterator& __x, const _Iterator& __y)
5933 requires random_access_range<_Base> &&
5934 three_way_comparable<_InnerIter<_Const>>
5935 { return __x._M_inner <=> __y._M_inner; }
5937 friend constexpr _Iterator
5938 operator+(const _Iterator& __i, difference_type __n)
5939 requires random_access_range<_Base>
5940 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5942 friend constexpr _Iterator
5943 operator+(difference_type __n, const _Iterator& __i)
5944 requires random_access_range<_Base>
5945 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5947 friend constexpr _Iterator
5948 operator-(const _Iterator& __i, difference_type __n)
5949 requires random_access_range<_Base>
5950 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5952 friend constexpr difference_type
5953 operator-(const _Iterator& __x, const _Iterator& __y)
5954 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5955 { return __x._M_inner - __y._M_inner; }
5958 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5959 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5960 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5961 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5962 range_reference_t<_Vp>>>
5963 template<bool _Const>
5964 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5966 _InnerSent<_Const> _M_inner;
5969 _Sentinel(_InnerSent<_Const> __inner)
5973 friend class adjacent_transform_view;
5976 _Sentinel() = default;
5979 _Sentinel(_Sentinel<!_Const> __i)
5980 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5981 : _M_inner(std::move(__i._M_inner))
5984 template<bool _OtherConst>
5985 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5986 friend constexpr bool
5987 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5988 { return __x._M_inner == __y._M_inner; }
5990 template<bool _OtherConst>
5991 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5992 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5993 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5994 { return __x._M_inner - __y._M_inner; }
5996 template<bool _OtherConst>
5997 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5998 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5999 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
6000 { return __x._M_inner - __y._M_inner; }
6007 template<size_t _Nm, typename _Range, typename _Fp>
6008 concept __can_adjacent_transform_view
6009 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6010 (std::declval<_Range>(), std::declval<_Fp>()); };
6013 template<size_t _Nm>
6014 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6016 template<viewable_range _Range, typename _Fp>
6017 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6019 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
6021 if constexpr (_Nm == 0)
6022 return zip_transform(std::forward<_Fp>(__f));
6024 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6025 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6028 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6029 static constexpr int _S_arity = 2;
6030 static constexpr bool _S_has_simple_extra_args = true;
6033 template<size_t _Nm>
6034 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6036 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6038#endif // __cpp_lib_ranges_zip
6040#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6043 template<typename _Tp>
6044 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6046 _Tp __r = __num / __denom;
6047 if (__num % __denom)
6054 requires input_range<_Vp>
6055 class chunk_view : public view_interface<chunk_view<_Vp>>
6058 range_difference_t<_Vp> _M_n;
6059 range_difference_t<_Vp> _M_remainder = 0;
6060 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6067 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6068 : _M_base(std::move(__base)), _M_n(__n)
6069 { __glibcxx_assert(__n >= 0); }
6072 base() const & requires copy_constructible<_Vp>
6077 { return std::move(_M_base); }
6079 constexpr _OuterIter
6082 _M_current = ranges::begin(_M_base);
6083 _M_remainder = _M_n;
6084 return _OuterIter(*this);
6087 constexpr default_sentinel_t
6088 end() const noexcept
6089 { return default_sentinel; }
6092 size() requires sized_range<_Vp>
6094 return __detail::__to_unsigned_like(__detail::__div_ceil
6095 (ranges::distance(_M_base), _M_n));
6099 size() const requires sized_range<const _Vp>
6101 return __detail::__to_unsigned_like(__detail::__div_ceil
6102 (ranges::distance(_M_base), _M_n));
6106 template<typename _Range>
6107 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6110 requires input_range<_Vp>
6111 class chunk_view<_Vp>::_OuterIter
6113 chunk_view* _M_parent;
6116 _OuterIter(chunk_view& __parent) noexcept
6117 : _M_parent(std::__addressof(__parent))
6123 using iterator_concept = input_iterator_tag;
6124 using difference_type = range_difference_t<_Vp>;
6128 _OuterIter(_OuterIter&&) = default;
6129 _OuterIter& operator=(_OuterIter&&) = default;
6131 constexpr value_type
6134 __glibcxx_assert(*this != default_sentinel);
6135 return value_type(*_M_parent);
6138 constexpr _OuterIter&
6141 __glibcxx_assert(*this != default_sentinel);
6142 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6143 ranges::end(_M_parent->_M_base));
6144 _M_parent->_M_remainder = _M_parent->_M_n;
6152 friend constexpr bool
6153 operator==(const _OuterIter& __x, default_sentinel_t)
6155 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6156 && __x._M_parent->_M_remainder != 0;
6159 friend constexpr difference_type
6160 operator-(default_sentinel_t, const _OuterIter& __x)
6161 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6163 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6165 if (__dist < __x._M_parent->_M_remainder)
6166 return __dist == 0 ? 0 : 1;
6168 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6169 __x._M_parent->_M_n);
6172 friend constexpr difference_type
6173 operator-(const _OuterIter& __x, default_sentinel_t __y)
6174 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6175 { return -(__y - __x); }
6179 requires input_range<_Vp>
6180 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6183 chunk_view* _M_parent;
6186 value_type(chunk_view& __parent) noexcept
6187 : _M_parent(std::__addressof(__parent))
6193 constexpr _InnerIter
6194 begin() const noexcept
6195 { return _InnerIter(*_M_parent); }
6197 constexpr default_sentinel_t
6198 end() const noexcept
6199 { return default_sentinel; }
6203 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6205 return __detail::__to_unsigned_like
6206 (ranges::min(_M_parent->_M_remainder,
6207 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6212 requires input_range<_Vp>
6213 class chunk_view<_Vp>::_InnerIter
6215 chunk_view* _M_parent;
6218 _InnerIter(chunk_view& __parent) noexcept
6219 : _M_parent(std::__addressof(__parent))
6222 friend _OuterIter::value_type;
6225 using iterator_concept = input_iterator_tag;
6226 using difference_type = range_difference_t<_Vp>;
6227 using value_type = range_value_t<_Vp>;
6229 _InnerIter(_InnerIter&&) = default;
6230 _InnerIter& operator=(_InnerIter&&) = default;
6232 constexpr const iterator_t<_Vp>&
6234 { return *_M_parent->_M_current; }
6236 constexpr range_reference_t<_Vp>
6239 __glibcxx_assert(*this != default_sentinel);
6240 return **_M_parent->_M_current;
6243 constexpr _InnerIter&
6246 __glibcxx_assert(*this != default_sentinel);
6247 ++*_M_parent->_M_current;
6248 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6249 _M_parent->_M_remainder = 0;
6251 --_M_parent->_M_remainder;
6259 friend constexpr bool
6260 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6261 { return __x._M_parent->_M_remainder == 0; }
6263 friend constexpr difference_type
6264 operator-(default_sentinel_t, const _InnerIter& __x)
6265 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6267 return ranges::min(__x._M_parent->_M_remainder,
6268 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6271 friend constexpr difference_type
6272 operator-(const _InnerIter& __x, default_sentinel_t __y)
6273 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6274 { return -(__y - __x); }
6276 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6277 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
6278 friend constexpr range_rvalue_reference_t<_Vp>
6279 iter_move(const _InnerIter& __i)
6280 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6281 { return ranges::iter_move(*__i._M_parent->_M_current); }
6283 friend constexpr void
6284 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
6285 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6286 *__x._M_parent->_M_current)))
6287 requires indirectly_swappable<iterator_t<_Vp>>
6288 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6292 requires forward_range<_Vp>
6293 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6296 range_difference_t<_Vp> _M_n;
6297 template<bool> class _Iterator;
6301 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6302 : _M_base(std::move(__base)), _M_n(__n)
6303 { __glibcxx_assert(__n > 0); }
6306 base() const & requires copy_constructible<_Vp>
6311 { return std::move(_M_base); }
6314 begin() requires (!__detail::__simple_view<_Vp>)
6315 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6318 begin() const requires forward_range<const _Vp>
6319 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6322 end() requires (!__detail::__simple_view<_Vp>)
6324 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6326 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6327 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6329 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6330 return _Iterator<false>(this, ranges::end(_M_base));
6332 return default_sentinel;
6336 end() const requires forward_range<const _Vp>
6338 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6340 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6341 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6343 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6344 return _Iterator<true>(this, ranges::end(_M_base));
6346 return default_sentinel;
6350 size() requires sized_range<_Vp>
6352 return __detail::__to_unsigned_like(__detail::__div_ceil
6353 (ranges::distance(_M_base), _M_n));
6357 size() const requires sized_range<const _Vp>
6359 return __detail::__to_unsigned_like(__detail::__div_ceil
6360 (ranges::distance(_M_base), _M_n));
6364 template<typename _Vp>
6365 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6366 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6369 requires forward_range<_Vp>
6370 template<bool _Const>
6371 class chunk_view<_Vp>::_Iterator
6373 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6374 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6376 iterator_t<_Base> _M_current = iterator_t<_Base>();
6377 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6378 range_difference_t<_Base> _M_n = 0;
6379 range_difference_t<_Base> _M_missing = 0;
6382 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6383 range_difference_t<_Base> __missing = 0)
6384 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6385 _M_n(__parent->_M_n), _M_missing(__missing)
6391 if constexpr (random_access_range<_Base>)
6392 return random_access_iterator_tag{};
6393 else if constexpr (bidirectional_range<_Base>)
6394 return bidirectional_iterator_tag{};
6396 return forward_iterator_tag{};
6402 using iterator_category = input_iterator_tag;
6403 using iterator_concept = decltype(_S_iter_cat());
6404 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6405 using difference_type = range_difference_t<_Base>;
6407 _Iterator() = default;
6409 constexpr _Iterator(_Iterator<!_Const> __i)
6411 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6412 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6413 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6414 _M_n(__i._M_n), _M_missing(__i._M_missing)
6417 constexpr iterator_t<_Base>
6419 { return _M_current; }
6421 constexpr value_type
6424 __glibcxx_assert(_M_current != _M_end);
6425 return views::take(subrange(_M_current, _M_end), _M_n);
6428 constexpr _Iterator&
6431 __glibcxx_assert(_M_current != _M_end);
6432 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6444 constexpr _Iterator&
6445 operator--() requires bidirectional_range<_Base>
6447 ranges::advance(_M_current, _M_missing - _M_n);
6453 operator--(int) requires bidirectional_range<_Base>
6460 constexpr _Iterator&
6461 operator+=(difference_type __x)
6462 requires random_access_range<_Base>
6466 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6467 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6471 ranges::advance(_M_current, _M_n * __x + _M_missing);
6477 constexpr _Iterator&
6478 operator-=(difference_type __x)
6479 requires random_access_range<_Base>
6480 { return *this += -__x; }
6482 constexpr value_type
6483 operator[](difference_type __n) const
6484 requires random_access_range<_Base>
6485 { return *(*this + __n); }
6487 friend constexpr bool
6488 operator==(const _Iterator& __x, const _Iterator& __y)
6489 { return __x._M_current == __y._M_current; }
6491 friend constexpr bool
6492 operator==(const _Iterator& __x, default_sentinel_t)
6493 { return __x._M_current == __x._M_end; }
6495 friend constexpr bool
6496 operator<(const _Iterator& __x, const _Iterator& __y)
6497 requires random_access_range<_Base>
6498 { return __x._M_current > __y._M_current; }
6500 friend constexpr bool
6501 operator>(const _Iterator& __x, const _Iterator& __y)
6502 requires random_access_range<_Base>
6503 { return __y < __x; }
6505 friend constexpr bool
6506 operator<=(const _Iterator& __x, const _Iterator& __y)
6507 requires random_access_range<_Base>
6508 { return !(__y < __x); }
6510 friend constexpr bool
6511 operator>=(const _Iterator& __x, const _Iterator& __y)
6512 requires random_access_range<_Base>
6513 { return !(__x < __y); }
6515 friend constexpr auto
6516 operator<=>(const _Iterator& __x, const _Iterator& __y)
6517 requires random_access_range<_Base>
6518 && three_way_comparable<iterator_t<_Base>>
6519 { return __x._M_current <=> __y._M_current; }
6521 friend constexpr _Iterator
6522 operator+(const _Iterator& __i, difference_type __n)
6523 requires random_access_range<_Base>
6530 friend constexpr _Iterator
6531 operator+(difference_type __n, const _Iterator& __i)
6532 requires random_access_range<_Base>
6539 friend constexpr _Iterator
6540 operator-(const _Iterator& __i, difference_type __n)
6541 requires random_access_range<_Base>
6548 friend constexpr difference_type
6549 operator-(const _Iterator& __x, const _Iterator& __y)
6550 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6552 return (__x._M_current - __y._M_current
6553 + __x._M_missing - __y._M_missing) / __x._M_n;
6556 friend constexpr difference_type
6557 operator-(default_sentinel_t, const _Iterator& __x)
6558 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6559 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6561 friend constexpr difference_type
6562 operator-(const _Iterator& __x, default_sentinel_t __y)
6563 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6564 { return -(__y - __x); }
6571 template<typename _Range, typename _Dp>
6572 concept __can_chunk_view
6573 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6576 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6578 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6579 requires __detail::__can_chunk_view<_Range, _Dp>
6581 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6582 { return chunk_view(std::forward<_Range>(__r), __n); }
6584 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6585 static constexpr int _S_arity = 2;
6586 static constexpr bool _S_has_simple_extra_args = true;
6589 inline constexpr _Chunk chunk;
6591#endif // __cpp_lib_ranges_chunk
6593#ifdef __cpp_lib_ranges_slide // C++ >= 23
6596 template<typename _Vp>
6597 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6599 template<typename _Vp>
6600 concept __slide_caches_last
6601 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6603 template<typename _Vp>
6604 concept __slide_caches_first
6605 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6608 template<forward_range _Vp>
6610 class slide_view : public view_interface<slide_view<_Vp>>
6613 range_difference_t<_Vp> _M_n;
6614 [[no_unique_address]]
6615 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6616 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6617 [[no_unique_address]]
6618 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6619 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6621 template<bool> class _Iterator;
6626 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6627 : _M_base(std::move(__base)), _M_n(__n)
6628 { __glibcxx_assert(__n > 0); }
6630 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6631 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
6633 base() const & requires copy_constructible<_Vp>
6638 { return std::move(_M_base); }
6641 begin() requires (!(__detail::__simple_view<_Vp>
6642 && __detail::__slide_caches_nothing<const _Vp>))
6644 if constexpr (__detail::__slide_caches_first<_Vp>)
6646 iterator_t<_Vp> __it;
6647 if (_M_cached_begin._M_has_value())
6648 __it = _M_cached_begin._M_get(_M_base);
6651 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6652 _M_cached_begin._M_set(_M_base, __it);
6654 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6657 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6661 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6662 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6665 end() requires (!(__detail::__simple_view<_Vp>
6666 && __detail::__slide_caches_nothing<const _Vp>))
6668 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6669 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6671 else if constexpr (__detail::__slide_caches_last<_Vp>)
6673 iterator_t<_Vp> __it;
6674 if (_M_cached_end._M_has_value())
6675 __it = _M_cached_end._M_get(_M_base);
6678 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6679 _M_cached_end._M_set(_M_base, __it);
6681 return _Iterator<false>(std::move(__it), _M_n);
6683 else if constexpr (common_range<_Vp>)
6684 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6686 return _Sentinel(ranges::end(_M_base));
6690 end() const requires __detail::__slide_caches_nothing<const _Vp>
6691 { return begin() + range_difference_t<const _Vp>(size()); }
6694 size() requires sized_range<_Vp>
6696 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6699 return __detail::__to_unsigned_like(__sz);
6703 size() const requires sized_range<const _Vp>
6705 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6708 return __detail::__to_unsigned_like(__sz);
6712 template<typename _Range>
6713 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6715 template<typename _Vp>
6716 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6717 = enable_borrowed_range<_Vp>;
6719 template<forward_range _Vp>
6721 template<bool _Const>
6722 class slide_view<_Vp>::_Iterator
6724 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6725 static constexpr bool _S_last_elt_present
6726 = __detail::__slide_caches_first<_Base>;
6728 iterator_t<_Base> _M_current = iterator_t<_Base>();
6729 [[no_unique_address]]
6730 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6731 _M_last_elt = decltype(_M_last_elt)();
6732 range_difference_t<_Base> _M_n = 0;
6735 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6736 requires (!_S_last_elt_present)
6737 : _M_current(__current), _M_n(__n)
6741 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6742 range_difference_t<_Base> __n)
6743 requires _S_last_elt_present
6744 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6750 if constexpr (random_access_range<_Base>)
6751 return random_access_iterator_tag{};
6752 else if constexpr (bidirectional_range<_Base>)
6753 return bidirectional_iterator_tag{};
6755 return forward_iterator_tag{};
6759 friend slide_view::_Sentinel;
6762 using iterator_category = input_iterator_tag;
6763 using iterator_concept = decltype(_S_iter_concept());
6764 using value_type = decltype(views::counted(_M_current, _M_n));
6765 using difference_type = range_difference_t<_Base>;
6767 _Iterator() = default;
6770 _Iterator(_Iterator<!_Const> __i)
6771 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6772 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6777 { return views::counted(_M_current, _M_n); }
6779 constexpr _Iterator&
6783 if constexpr (_S_last_elt_present)
6796 constexpr _Iterator&
6797 operator--() requires bidirectional_range<_Base>
6800 if constexpr (_S_last_elt_present)
6806 operator--(int) requires bidirectional_range<_Base>
6813 constexpr _Iterator&
6814 operator+=(difference_type __x)
6815 requires random_access_range<_Base>
6818 if constexpr (_S_last_elt_present)
6823 constexpr _Iterator&
6824 operator-=(difference_type __x)
6825 requires random_access_range<_Base>
6828 if constexpr (_S_last_elt_present)
6834 operator[](difference_type __n) const
6835 requires random_access_range<_Base>
6836 { return views::counted(_M_current + __n, _M_n); }
6838 friend constexpr bool
6839 operator==(const _Iterator& __x, const _Iterator& __y)
6841 if constexpr (_S_last_elt_present)
6842 return __x._M_last_elt == __y._M_last_elt;
6844 return __x._M_current == __y._M_current;
6847 friend constexpr bool
6848 operator<(const _Iterator& __x, const _Iterator& __y)
6849 requires random_access_range<_Base>
6850 { return __x._M_current < __y._M_current; }
6852 friend constexpr bool
6853 operator>(const _Iterator& __x, const _Iterator& __y)
6854 requires random_access_range<_Base>
6855 { return __y < __x; }
6857 friend constexpr bool
6858 operator<=(const _Iterator& __x, const _Iterator& __y)
6859 requires random_access_range<_Base>
6860 { return !(__y < __x); }
6862 friend constexpr bool
6863 operator>=(const _Iterator& __x, const _Iterator& __y)
6864 requires random_access_range<_Base>
6865 { return !(__x < __y); }
6867 friend constexpr auto
6868 operator<=>(const _Iterator& __x, const _Iterator& __y)
6869 requires random_access_range<_Base>
6870 && three_way_comparable<iterator_t<_Base>>
6871 { return __x._M_current <=> __y._M_current; }
6873 friend constexpr _Iterator
6874 operator+(const _Iterator& __i, difference_type __n)
6875 requires random_access_range<_Base>
6882 friend constexpr _Iterator
6883 operator+(difference_type __n, const _Iterator& __i)
6884 requires random_access_range<_Base>
6891 friend constexpr _Iterator
6892 operator-(const _Iterator& __i, difference_type __n)
6893 requires random_access_range<_Base>
6900 friend constexpr difference_type
6901 operator-(const _Iterator& __x, const _Iterator& __y)
6902 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6904 if constexpr (_S_last_elt_present)
6905 return __x._M_last_elt - __y._M_last_elt;
6907 return __x._M_current - __y._M_current;
6911 template<forward_range _Vp>
6913 class slide_view<_Vp>::_Sentinel
6915 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6918 _Sentinel(sentinel_t<_Vp> __end)
6925 _Sentinel() = default;
6927 friend constexpr bool
6928 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6929 { return __x._M_last_elt == __y._M_end; }
6931 friend constexpr range_difference_t<_Vp>
6932 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6933 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6934 { return __x._M_last_elt - __y._M_end; }
6936 friend constexpr range_difference_t<_Vp>
6937 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6938 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6939 { return __y._M_end -__x._M_last_elt; }
6946 template<typename _Range, typename _Dp>
6947 concept __can_slide_view
6948 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6951 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6953 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6954 requires __detail::__can_slide_view<_Range, _Dp>
6956 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6957 { return slide_view(std::forward<_Range>(__r), __n); }
6959 using __adaptor::_RangeAdaptor<_Slide>::operator();
6960 static constexpr int _S_arity = 2;
6961 static constexpr bool _S_has_simple_extra_args = true;
6964 inline constexpr _Slide slide;
6966#endif // __cpp_lib_ranges_slide
6968#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
6969 template<forward_range _Vp,
6970 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6971 requires view<_Vp> && is_object_v<_Pred>
6972 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6974 _Vp _M_base = _Vp();
6975 __detail::__box<_Pred> _M_pred;
6976 __detail::_CachedPosition<_Vp> _M_cached_begin;
6978 constexpr iterator_t<_Vp>
6979 _M_find_next(iterator_t<_Vp> __current)
6981 __glibcxx_assert(_M_pred.has_value());
6982 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6983 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6985 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6986 return ranges::next(__it, 1, ranges::end(_M_base));
6989 constexpr iterator_t<_Vp>
6990 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
6992 __glibcxx_assert(_M_pred.has_value());
6993 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6994 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
6996 auto __rbegin = std::make_reverse_iterator(__current);
6997 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
6998 __glibcxx_assert(__rbegin != __rend);
6999 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7000 return ranges::prev(__it, 1, ranges::begin(_M_base));
7006 chunk_by_view() requires (default_initializable<_Vp>
7007 && default_initializable<_Pred>)
7011 chunk_by_view(_Vp __base, _Pred __pred)
7012 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
7016 base() const & requires copy_constructible<_Vp>
7021 { return std::move(_M_base); }
7023 constexpr const _Pred&
7025 { return *_M_pred; }
7030 __glibcxx_assert(_M_pred.has_value());
7031 iterator_t<_Vp> __it;
7032 if (_M_cached_begin._M_has_value())
7033 __it = _M_cached_begin._M_get(_M_base);
7036 __it = _M_find_next(ranges::begin(_M_base));
7037 _M_cached_begin._M_set(_M_base, __it);
7039 return _Iterator(*this, ranges::begin(_M_base), __it);
7045 if constexpr (common_range<_Vp>)
7046 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
7048 return default_sentinel;
7052 template<typename _Range, typename _Pred>
7053 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7055 template<forward_range _Vp,
7056 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7057 requires view<_Vp> && is_object_v<_Pred>
7058 class chunk_by_view<_Vp, _Pred>::_Iterator
7060 chunk_by_view* _M_parent = nullptr;
7061 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7062 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7065 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7066 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7072 if constexpr (bidirectional_range<_Vp>)
7073 return bidirectional_iterator_tag{};
7075 return forward_iterator_tag{};
7078 friend chunk_by_view;
7081 using value_type = subrange<iterator_t<_Vp>>;
7082 using difference_type = range_difference_t<_Vp>;
7083 using iterator_category = input_iterator_tag;
7084 using iterator_concept = decltype(_S_iter_concept());
7086 _Iterator() = default;
7088 constexpr value_type
7091 __glibcxx_assert(_M_current != _M_next);
7092 return ranges::subrange(_M_current, _M_next);
7095 constexpr _Iterator&
7098 __glibcxx_assert(_M_current != _M_next);
7099 _M_current = _M_next;
7100 _M_next = _M_parent->_M_find_next(_M_current);
7112 constexpr _Iterator&
7113 operator--() requires bidirectional_range<_Vp>
7115 _M_next = _M_current;
7116 _M_current = _M_parent->_M_find_prev(_M_next);
7121 operator--(int) requires bidirectional_range<_Vp>
7128 friend constexpr bool
7129 operator==(const _Iterator& __x, const _Iterator& __y)
7130 { return __x._M_current == __y._M_current; }
7132 friend constexpr bool
7133 operator==(const _Iterator& __x, default_sentinel_t)
7134 { return __x._M_current == __x._M_next; }
7141 template<typename _Range, typename _Pred>
7142 concept __can_chunk_by_view
7143 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7146 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7148 template<viewable_range _Range, typename _Pred>
7149 requires __detail::__can_chunk_by_view<_Range, _Pred>
7151 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7152 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7154 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7155 static constexpr int _S_arity = 2;
7156 static constexpr bool _S_has_simple_extra_args = true;
7159 inline constexpr _ChunkBy chunk_by;
7161#endif // __cpp_lib_ranges_chunk_by
7163#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7166 template<typename _Range, typename _Pattern>
7167 concept __compatible_joinable_ranges
7168 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7169 && common_reference_with<range_reference_t<_Range>,
7170 range_reference_t<_Pattern>>
7171 && common_reference_with<range_rvalue_reference_t<_Range>,
7172 range_rvalue_reference_t<_Pattern>>;
7174 template<typename _Range>
7175 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7178 template<input_range _Vp, forward_range _Pattern>
7179 requires view<_Vp> && view<_Pattern>
7180 && input_range<range_reference_t<_Vp>>
7181 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7182 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7184 using _InnerRange = range_reference_t<_Vp>;
7186 _Vp _M_base = _Vp();
7187 [[no_unique_address]]
7188 __detail::__maybe_present_t<!forward_range<_Vp>,
7189 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7190 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7191 _Pattern _M_pattern = _Pattern();
7193 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7194 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7195 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7197 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7198 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7199 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7201 template<bool _Const>
7202 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7204 template<bool _Const>
7208 template<bool _Const>
7209 requires _S_ref_is_glvalue<_Const>
7210 && forward_range<_Base<_Const>>
7211 && forward_range<_InnerBase<_Const>>
7212 struct __iter_cat<_Const>
7218 using _OuterIter = join_with_view::_OuterIter<_Const>;
7219 using _InnerIter = join_with_view::_InnerIter<_Const>;
7220 using _PatternIter = join_with_view::_PatternIter<_Const>;
7221 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7222 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7223 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7224 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7225 // 3798. Rvalue reference and iterator_category
7226 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7227 iter_reference_t<_PatternIter>>>)
7228 return input_iterator_tag{};
7229 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7230 && derived_from<_InnerCat, bidirectional_iterator_tag>
7231 && derived_from<_PatternCat, bidirectional_iterator_tag>
7232 && common_range<_InnerBase<_Const>>
7233 && common_range<_PatternBase<_Const>>)
7234 return bidirectional_iterator_tag{};
7235 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7236 && derived_from<_InnerCat, forward_iterator_tag>
7237 && derived_from<_PatternCat, forward_iterator_tag>)
7238 return forward_iterator_tag{};
7240 return input_iterator_tag{};
7243 using iterator_category = decltype(_S_iter_cat());
7246 template<bool> class _Iterator;
7247 template<bool> class _Sentinel;
7250 join_with_view() requires (default_initializable<_Vp>
7251 && default_initializable<_Pattern>)
7255 join_with_view(_Vp __base, _Pattern __pattern)
7256 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7259 template<input_range _Range>
7260 requires constructible_from<_Vp, views::all_t<_Range>>
7261 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7263 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7264 : _M_base(views::all(std::forward<_Range>(__r))),
7265 _M_pattern(views::single(std::move(__e)))
7269 base() const& requires copy_constructible<_Vp>
7274 { return std::move(_M_base); }
7279 if constexpr (forward_range<_Vp>)
7281 constexpr bool __use_const = is_reference_v<_InnerRange>
7282 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7283 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7287 _M_outer_it = ranges::begin(_M_base);
7288 return _Iterator<false>{*this};
7294 requires forward_range<const _Vp>
7295 && forward_range<const _Pattern>
7296 && is_reference_v<range_reference_t<const _Vp>>
7297 && input_range<range_reference_t<const _Vp>>
7298 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7303 constexpr bool __use_const
7304 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7305 if constexpr (is_reference_v<_InnerRange>
7306 && forward_range<_Vp> && common_range<_Vp>
7307 && forward_range<_InnerRange> && common_range<_InnerRange>)
7308 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7310 return _Sentinel<__use_const>{*this};
7315 requires forward_range<const _Vp>
7316 && forward_range<const _Pattern>
7317 && is_reference_v<range_reference_t<const _Vp>>
7318 && input_range<range_reference_t<const _Vp>>
7320 using _InnerConstRange = range_reference_t<const _Vp>;
7321 if constexpr (forward_range<_InnerConstRange>
7322 && common_range<const _Vp>
7323 && common_range<_InnerConstRange>)
7324 return _Iterator<true>{*this, ranges::end(_M_base)};
7326 return _Sentinel<true>{*this};
7330 template<typename _Range, typename _Pattern>
7331 join_with_view(_Range&&, _Pattern&&)
7332 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7334 template<input_range _Range>
7335 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7336 -> join_with_view<views::all_t<_Range>,
7337 single_view<range_value_t<range_reference_t<_Range>>>>;
7339 template<input_range _Vp, forward_range _Pattern>
7340 requires view<_Vp> && view<_Pattern>
7341 && input_range<range_reference_t<_Vp>>
7342 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7343 template<bool _Const>
7344 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7346 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7347 using _Base = join_with_view::_Base<_Const>;
7348 using _InnerBase = join_with_view::_InnerBase<_Const>;
7349 using _PatternBase = join_with_view::_PatternBase<_Const>;
7351 using _OuterIter = join_with_view::_OuterIter<_Const>;
7352 using _InnerIter = join_with_view::_InnerIter<_Const>;
7353 using _PatternIter = join_with_view::_PatternIter<_Const>;
7355 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7357 _Parent* _M_parent = nullptr;
7358 [[no_unique_address]]
7359 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
7360 = decltype(_M_outer_it)();
7361 variant<_PatternIter, _InnerIter> _M_inner_it;
7363 constexpr _OuterIter&
7366 if constexpr (forward_range<_Base>)
7369 return *_M_parent->_M_outer_it;
7372 constexpr const _OuterIter&
7373 _M_get_outer() const
7375 if constexpr (forward_range<_Base>)
7378 return *_M_parent->_M_outer_it;
7382 _Iterator(_Parent& __parent, _OuterIter __outer)
7383 requires forward_range<_Base>
7384 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7386 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7388 auto&& __inner = _M_update_inner();
7389 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7395 _Iterator(_Parent& __parent)
7396 requires (!forward_range<_Base>)
7397 : _M_parent(std::__addressof(__parent))
7399 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7401 auto&& __inner = _M_update_inner();
7402 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7410 _OuterIter& __outer = _M_get_outer();
7411 if constexpr (_S_ref_is_glvalue)
7412 return __detail::__as_lvalue(*__outer);
7414 return _M_parent->_M_inner._M_emplace_deref(__outer);
7420 if constexpr (_S_ref_is_glvalue)
7421 return __detail::__as_lvalue(*_M_get_outer());
7423 return *_M_parent->_M_inner;
7431 if (_M_inner_it.index() == 0)
7433 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7436 auto&& __inner = _M_update_inner();
7437 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7441 auto&& __inner = _M_get_inner();
7442 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7445 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7447 if constexpr (_S_ref_is_glvalue)
7448 _M_inner_it.template emplace<0>();
7452 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7460 if constexpr (_S_ref_is_glvalue
7461 && bidirectional_range<_Base>
7462 && __detail::__bidirectional_common<_InnerBase>
7463 && __detail::__bidirectional_common<_PatternBase>)
7464 return bidirectional_iterator_tag{};
7465 else if constexpr (_S_ref_is_glvalue
7466 && forward_range<_Base>
7467 && forward_range<_InnerBase>)
7468 return forward_iterator_tag{};
7470 return input_iterator_tag{};
7473 friend join_with_view;
7476 using iterator_concept = decltype(_S_iter_concept());
7477 // iterator_category defined in join_with_view::__iter_cat
7478 using value_type = common_type_t<iter_value_t<_InnerIter>,
7479 iter_value_t<_PatternIter>>;
7480 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7481 iter_difference_t<_InnerIter>,
7482 iter_difference_t<_PatternIter>>;
7484 _Iterator() = default;
7487 _Iterator(_Iterator<!_Const> __i)
7489 && convertible_to<iterator_t<_Vp>, _OuterIter>
7490 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7491 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7492 : _M_parent(__i._M_parent),
7493 _M_outer_it(std::move(__i._M_outer_it))
7495 if (__i._M_inner_it.index() == 0)
7496 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7498 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7501 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7502 iter_reference_t<_PatternIter>>
7505 if (_M_inner_it.index() == 0)
7506 return *std::get<0>(_M_inner_it);
7508 return *std::get<1>(_M_inner_it);
7511 constexpr _Iterator&
7514 if (_M_inner_it.index() == 0)
7515 ++std::get<0>(_M_inner_it);
7517 ++std::get<1>(_M_inner_it);
7528 requires _S_ref_is_glvalue
7529 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7531 _Iterator __tmp = *this;
7536 constexpr _Iterator&
7538 requires _S_ref_is_glvalue
7539 && bidirectional_range<_Base>
7540 && __detail::__bidirectional_common<_InnerBase>
7541 && __detail::__bidirectional_common<_PatternBase>
7543 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7545 auto&& __inner = *--_M_outer_it;
7546 _M_inner_it.template emplace<1>(ranges::end(__inner));
7551 if (_M_inner_it.index() == 0)
7553 auto& __it = std::get<0>(_M_inner_it);
7554 if (__it == ranges::begin(_M_parent->_M_pattern))
7556 auto&& __inner = *--_M_outer_it;
7557 _M_inner_it.template emplace<1>(ranges::end(__inner));
7564 auto& __it = std::get<1>(_M_inner_it);
7565 auto&& __inner = *_M_outer_it;
7566 if (__it == ranges::begin(__inner))
7567 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7573 if (_M_inner_it.index() == 0)
7574 --std::get<0>(_M_inner_it);
7576 --std::get<1>(_M_inner_it);
7582 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7583 && __detail::__bidirectional_common<_InnerBase>
7584 && __detail::__bidirectional_common<_PatternBase>
7586 _Iterator __tmp = *this;
7591 friend constexpr bool
7592 operator==(const _Iterator& __x, const _Iterator& __y)
7593 requires _S_ref_is_glvalue
7594 && forward_range<_Base> && equality_comparable<_InnerIter>
7595 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7597 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7598 iter_rvalue_reference_t<_PatternIter>>
7599 iter_move(const _Iterator& __x)
7601 if (__x._M_inner_it.index() == 0)
7602 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7604 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7607 friend constexpr void
7608 iter_swap(const _Iterator& __x, const _Iterator& __y)
7609 requires indirectly_swappable<_InnerIter, _PatternIter>
7611 if (__x._M_inner_it.index() == 0)
7613 if (__y._M_inner_it.index() == 0)
7614 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7616 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7620 if (__y._M_inner_it.index() == 0)
7621 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7623 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7628 template<input_range _Vp, forward_range _Pattern>
7629 requires view<_Vp> && view<_Pattern>
7630 && input_range<range_reference_t<_Vp>>
7631 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7632 template<bool _Const>
7633 class join_with_view<_Vp, _Pattern>::_Sentinel
7635 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7636 using _Base = join_with_view::_Base<_Const>;
7638 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7641 _Sentinel(_Parent& __parent)
7642 : _M_end(ranges::end(__parent._M_base))
7645 friend join_with_view;
7648 _Sentinel() = default;
7651 _Sentinel(_Sentinel<!_Const> __s)
7652 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7653 : _M_end(std::move(__s._M_end))
7656 template<bool _OtherConst>
7657 requires sentinel_for<sentinel_t<_Base>,
7658 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7659 friend constexpr bool
7660 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7661 { return __x._M_get_outer() == __y._M_end; }
7668 template<typename _Range, typename _Pattern>
7669 concept __can_join_with_view
7670 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7671 } // namespace __detail
7673 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7675 template<viewable_range _Range, typename _Pattern>
7676 requires __detail::__can_join_with_view<_Range, _Pattern>
7678 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7680 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7683 using _RangeAdaptor<_JoinWith>::operator();
7684 static constexpr int _S_arity = 2;
7685 template<typename _Pattern>
7686 static constexpr bool _S_has_simple_extra_args
7687 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7690 inline constexpr _JoinWith join_with;
7691 } // namespace views
7692#endif // __cpp_lib_ranges_join_with
7694#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7695 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7696 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7697 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7698 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7700 __detail::__box<_Tp> _M_value;
7701 [[no_unique_address]] _Bound _M_bound = _Bound();
7705 template<typename _Range>
7706 friend constexpr auto
7707 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7709 template<typename _Range>
7710 friend constexpr auto
7711 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7714 repeat_view() requires default_initializable<_Tp> = default;
7717 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7718 requires copy_constructible<_Tp>
7719 : _M_value(__value), _M_bound(__bound)
7721 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7722 __glibcxx_assert(__bound >= 0);
7726 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7727 : _M_value(std::move(__value)), _M_bound(__bound)
7730 template<typename... _Args, typename... _BoundArgs>
7731 requires constructible_from<_Tp, _Args...>
7732 && constructible_from<_Bound, _BoundArgs...>
7734 repeat_view(piecewise_construct_t,
7735 tuple<_Args...> __args,
7736 tuple<_BoundArgs...> __bound_args = tuple<>{})
7737 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7738 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7743 { return _Iterator(std::__addressof(*_M_value)); }
7746 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7747 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7749 constexpr unreachable_sentinel_t
7750 end() const noexcept
7751 { return unreachable_sentinel; }
7754 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7755 { return __detail::__to_unsigned_like(_M_bound); }
7758 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7759 // 4053. Unary call to std::views::repeat does not decay the argument
7760 template<typename _Tp, typename _Bound = unreachable_sentinel_t>
7761 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7763 template<move_constructible _Tp, semiregular _Bound>
7764 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7765 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7766 class repeat_view<_Tp, _Bound>::_Iterator
7769 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7771 const _Tp* _M_value = nullptr;
7772 __index_type _M_current = __index_type();
7775 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7776 : _M_value(__value), _M_current(__bound)
7778 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7779 __glibcxx_assert(__bound >= 0);
7785 using iterator_concept = random_access_iterator_tag;
7786 using iterator_category = random_access_iterator_tag;
7787 using value_type = _Tp;
7788 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7790 __detail::__iota_diff_t<__index_type>>;
7792 _Iterator() = default;
7794 constexpr const _Tp&
7795 operator*() const noexcept
7796 { return *_M_value; }
7798 constexpr _Iterator&
7813 constexpr _Iterator&
7816 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7817 __glibcxx_assert(_M_current > 0);
7830 constexpr _Iterator&
7831 operator+=(difference_type __n)
7833 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7834 __glibcxx_assert(_M_current + __n >= 0);
7839 constexpr _Iterator&
7840 operator-=(difference_type __n)
7842 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7843 __glibcxx_assert(_M_current - __n >= 0);
7848 constexpr const _Tp&
7849 operator[](difference_type __n) const noexcept
7850 { return *(*this + __n); }
7852 friend constexpr bool
7853 operator==(const _Iterator& __x, const _Iterator& __y)
7854 { return __x._M_current == __y._M_current; }
7856 friend constexpr auto
7857 operator<=>(const _Iterator& __x, const _Iterator& __y)
7858 { return __x._M_current <=> __y._M_current; }
7860 friend constexpr _Iterator
7861 operator+(_Iterator __i, difference_type __n)
7867 friend constexpr _Iterator
7868 operator+(difference_type __n, _Iterator __i)
7869 { return __i + __n; }
7871 friend constexpr _Iterator
7872 operator-(_Iterator __i, difference_type __n)
7878 friend constexpr difference_type
7879 operator-(const _Iterator& __x, const _Iterator& __y)
7881 return (static_cast<difference_type>(__x._M_current)
7882 - static_cast<difference_type>(__y._M_current));
7890 template<typename _Tp, typename _Bound>
7891 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7893 template<typename _Tp>
7894 concept __can_repeat_view
7895 = requires { repeat_view(std::declval<_Tp>()); };
7897 template<typename _Tp, typename _Bound>
7898 concept __can_bounded_repeat_view
7899 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7904 template<typename _Tp>
7905 requires __detail::__can_repeat_view<_Tp>
7907 operator() [[nodiscard]] (_Tp&& __value) const
7909 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7910 // 4054. Repeating a repeat_view should repeat the view
7911 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7914 template<typename _Tp, typename _Bound>
7915 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7917 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7918 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7921 inline constexpr _Repeat repeat;
7925 template<typename _Range>
7927 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7929 using _Tp = remove_cvref_t<_Range>;
7930 static_assert(__is_repeat_view<_Tp>);
7931 if constexpr (sized_range<_Tp>)
7932 return views::repeat(*std::forward<_Range>(__r)._M_value,
7933 std::min(ranges::distance(__r), __n));
7935 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7938 template<typename _Range>
7940 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7942 using _Tp = remove_cvref_t<_Range>;
7943 static_assert(__is_repeat_view<_Tp>);
7944 if constexpr (sized_range<_Tp>)
7946 auto __sz = ranges::distance(__r);
7947 return views::repeat(*std::forward<_Range>(__r)._M_value,
7948 __sz - std::min(__sz, __n));
7955#endif // __cpp_lib_ranges_repeat
7957#ifdef __cpp_lib_ranges_stride // C++ >= 23
7958 template<input_range _Vp>
7960 class stride_view : public view_interface<stride_view<_Vp>>
7963 range_difference_t<_Vp> _M_stride;
7965 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7967 template<bool _Const>
7971 template<bool _Const>
7972 requires forward_range<_Base<_Const>>
7973 struct __iter_cat<_Const>
7979 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7980 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7981 return random_access_iterator_tag{};
7986 using iterator_category = decltype(_S_iter_cat());
7989 template<bool> class _Iterator;
7993 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7994 : _M_base(std::move(__base)), _M_stride(__stride)
7995 { __glibcxx_assert(__stride > 0); }
7998 base() const& requires copy_constructible<_Vp>
8003 { return std::move(_M_base); }
8005 constexpr range_difference_t<_Vp>
8006 stride() const noexcept
8007 { return _M_stride; }
8010 begin() requires (!__detail::__simple_view<_Vp>)
8011 { return _Iterator<false>(this, ranges::begin(_M_base)); }
8014 begin() const requires range<const _Vp>
8015 { return _Iterator<true>(this, ranges::begin(_M_base)); }
8018 end() requires (!__detail::__simple_view<_Vp>)
8020 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8022 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8023 return _Iterator<false>(this, ranges::end(_M_base), __missing);
8025 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8026 return _Iterator<false>(this, ranges::end(_M_base));
8028 return default_sentinel;
8032 end() const requires range<const _Vp>
8034 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8035 && forward_range<const _Vp>)
8037 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8038 return _Iterator<true>(this, ranges::end(_M_base), __missing);
8040 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8041 return _Iterator<true>(this, ranges::end(_M_base));
8043 return default_sentinel;
8047 size() requires sized_range<_Vp>
8049 return __detail::__to_unsigned_like
8050 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8054 size() const requires sized_range<const _Vp>
8056 return __detail::__to_unsigned_like
8057 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8061 template<typename _Range>
8062 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8064 template<typename _Vp>
8065 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8066 = enable_borrowed_range<_Vp>;
8068 template<input_range _Vp>
8070 template<bool _Const>
8071 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8073 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8074 using _Base = stride_view::_Base<_Const>;
8076 iterator_t<_Base> _M_current = iterator_t<_Base>();
8077 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8078 range_difference_t<_Base> _M_stride = 0;
8079 range_difference_t<_Base> _M_missing = 0;
8082 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8083 range_difference_t<_Base> __missing = 0)
8084 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8085 _M_stride(__parent->_M_stride), _M_missing(__missing)
8091 if constexpr (random_access_range<_Base>)
8092 return random_access_iterator_tag{};
8093 else if constexpr (bidirectional_range<_Base>)
8094 return bidirectional_iterator_tag{};
8095 else if constexpr (forward_range<_Base>)
8096 return forward_iterator_tag{};
8098 return input_iterator_tag{};
8104 using difference_type = range_difference_t<_Base>;
8105 using value_type = range_value_t<_Base>;
8106 using iterator_concept = decltype(_S_iter_concept());
8107 // iterator_category defined in stride_view::__iter_cat
8109 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8112 _Iterator(_Iterator<!_Const> __other)
8114 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8115 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8116 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8117 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8120 constexpr iterator_t<_Base>
8122 { return std::move(_M_current); }
8124 constexpr const iterator_t<_Base>&
8125 base() const & noexcept
8126 { return _M_current; }
8128 constexpr decltype(auto)
8130 { return *_M_current; }
8132 constexpr _Iterator&
8135 __glibcxx_assert(_M_current != _M_end);
8136 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8145 operator++(int) requires forward_range<_Base>
8152 constexpr _Iterator&
8153 operator--() requires bidirectional_range<_Base>
8155 ranges::advance(_M_current, _M_missing - _M_stride);
8161 operator--(int) requires bidirectional_range<_Base>
8168 constexpr _Iterator&
8169 operator+=(difference_type __n) requires random_access_range<_Base>
8173 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8174 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8178 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8184 constexpr _Iterator&
8185 operator-=(difference_type __n) requires random_access_range<_Base>
8186 { return *this += -__n; }
8188 constexpr decltype(auto) operator[](difference_type __n) const
8189 requires random_access_range<_Base>
8190 { return *(*this + __n); }
8192 friend constexpr bool
8193 operator==(const _Iterator& __x, default_sentinel_t)
8194 { return __x._M_current == __x._M_end; }
8196 friend constexpr bool
8197 operator==(const _Iterator& __x, const _Iterator& __y)
8198 requires equality_comparable<iterator_t<_Base>>
8199 { return __x._M_current == __y._M_current; }
8201 friend constexpr bool
8202 operator<(const _Iterator& __x, const _Iterator& __y)
8203 requires random_access_range<_Base>
8204 { return __x._M_current < __y._M_current; }
8206 friend constexpr bool
8207 operator>(const _Iterator& __x, const _Iterator& __y)
8208 requires random_access_range<_Base>
8209 { return __y._M_current < __x._M_current; }
8211 friend constexpr bool
8212 operator<=(const _Iterator& __x, const _Iterator& __y)
8213 requires random_access_range<_Base>
8214 { return !(__y._M_current < __x._M_current); }
8216 friend constexpr bool
8217 operator>=(const _Iterator& __x, const _Iterator& __y)
8218 requires random_access_range<_Base>
8219 { return !(__x._M_current < __y._M_current); }
8221 friend constexpr auto
8222 operator<=>(const _Iterator& __x, const _Iterator& __y)
8223 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8224 { return __x._M_current <=> __y._M_current; }
8226 friend constexpr _Iterator
8227 operator+(const _Iterator& __i, difference_type __n)
8228 requires random_access_range<_Base>
8235 friend constexpr _Iterator
8236 operator+(difference_type __n, const _Iterator& __i)
8237 requires random_access_range<_Base>
8238 { return __i + __n; }
8240 friend constexpr _Iterator
8241 operator-(const _Iterator& __i, difference_type __n)
8242 requires random_access_range<_Base>
8249 friend constexpr difference_type
8250 operator-(const _Iterator& __x, const _Iterator& __y)
8251 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8253 auto __n = __x._M_current - __y._M_current;
8254 if constexpr (forward_range<_Base>)
8255 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8257 return -__detail::__div_ceil(-__n, __x._M_stride);
8259 return __detail::__div_ceil(__n, __x._M_stride);
8262 friend constexpr difference_type
8263 operator-(default_sentinel_t, const _Iterator& __x)
8264 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8265 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8267 friend constexpr difference_type
8268 operator-(const _Iterator& __x, default_sentinel_t __y)
8269 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8270 { return -(__y - __x); }
8272 friend constexpr range_rvalue_reference_t<_Base>
8273 iter_move(const _Iterator& __i)
8274 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8275 { return ranges::iter_move(__i._M_current); }
8277 friend constexpr void
8278 iter_swap(const _Iterator& __x, const _Iterator& __y)
8279 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8280 requires indirectly_swappable<iterator_t<_Base>>
8281 { ranges::iter_swap(__x._M_current, __y._M_current); }
8288 template<typename _Range, typename _Dp>
8289 concept __can_stride_view
8290 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8293 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8295 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8296 requires __detail::__can_stride_view<_Range, _Dp>
8298 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8299 { return stride_view(std::forward<_Range>(__r), __n); }
8301 using __adaptor::_RangeAdaptor<_Stride>::operator();
8302 static constexpr int _S_arity = 2;
8303 static constexpr bool _S_has_simple_extra_args = true;
8306 inline constexpr _Stride stride;
8308#endif // __cpp_lib_ranges_stride
8310#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8313 template<bool _Const, typename _First, typename... _Vs>
8314 concept __cartesian_product_is_random_access
8315 = (random_access_range<__maybe_const_t<_Const, _First>>
8317 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8318 && sized_range<__maybe_const_t<_Const, _Vs>>));
8320 template<typename _Range>
8321 concept __cartesian_product_common_arg
8322 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8324 template<bool _Const, typename _First, typename... _Vs>
8325 concept __cartesian_product_is_bidirectional
8326 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8328 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8329 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8331 template<typename _First, typename... _Vs>
8332 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8334 template<typename... _Vs>
8335 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8337 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8338 concept __cartesian_is_sized_sentinel
8339 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8340 iterator_t<__maybe_const_t<_Const, _First>>>
8342 && (sized_range<__maybe_const_t<_Const, _Vs>>
8343 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8344 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8346 template<__cartesian_product_common_arg _Range>
8348 __cartesian_common_arg_end(_Range& __r)
8350 if constexpr (common_range<_Range>)
8351 return ranges::end(__r);
8353 return ranges::begin(__r) + ranges::distance(__r);
8355 } // namespace __detail
8357 template<input_range _First, forward_range... _Vs>
8358 requires (view<_First> && ... && view<_Vs>)
8359 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8361 tuple<_First, _Vs...> _M_bases;
8363 template<bool> class _Iterator;
8366 _S_difference_type()
8368 // TODO: Implement the recommended practice of using the smallest
8369 // sufficiently wide type according to the maximum sizes of the
8370 // underlying ranges?
8371 return common_type_t<ptrdiff_t,
8372 range_difference_t<_First>,
8373 range_difference_t<_Vs>...>{};
8377 cartesian_product_view() = default;
8380 cartesian_product_view(_First __first, _Vs... __rest)
8381 : _M_bases(std::move(__first), std::move(__rest)...)
8384 constexpr _Iterator<false>
8385 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8386 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8388 constexpr _Iterator<true>
8389 begin() const requires (range<const _First> && ... && range<const _Vs>)
8390 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8392 constexpr _Iterator<false>
8393 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8394 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8396 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8397 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8398 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8399 auto& __first = std::get<0>(_M_bases);
8400 return _Ret{(__empty_tail
8401 ? ranges::begin(__first)
8402 : __detail::__cartesian_common_arg_end(__first)),
8403 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8404 }(make_index_sequence<sizeof...(_Vs)>{});
8406 return _Iterator<false>{*this, std::move(__its)};
8409 constexpr _Iterator<true>
8410 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8412 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8413 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8414 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8415 auto& __first = std::get<0>(_M_bases);
8416 return _Ret{(__empty_tail
8417 ? ranges::begin(__first)
8418 : __detail::__cartesian_common_arg_end(__first)),
8419 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8420 }(make_index_sequence<sizeof...(_Vs)>{});
8422 return _Iterator<true>{*this, std::move(__its)};
8425 constexpr default_sentinel_t
8426 end() const noexcept
8427 { return default_sentinel; }
8430 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8432 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8433 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8434 auto __size = static_cast<_ST>(1);
8435#ifdef _GLIBCXX_ASSERTIONS
8436 if constexpr (integral<_ST>)
8439 = (__builtin_mul_overflow(__size,
8440 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8443 __glibcxx_assert(!__overflow);
8447 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8449 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8453 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8455 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8456 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8457 auto __size = static_cast<_ST>(1);
8458#ifdef _GLIBCXX_ASSERTIONS
8459 if constexpr (integral<_ST>)
8462 = (__builtin_mul_overflow(__size,
8463 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8466 __glibcxx_assert(!__overflow);
8470 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8472 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8476 template<typename... _Vs>
8477 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8479 template<input_range _First, forward_range... _Vs>
8480 requires (view<_First> && ... && view<_Vs>)
8481 template<bool _Const>
8482 class cartesian_product_view<_First, _Vs...>::_Iterator
8484 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8485 _Parent* _M_parent = nullptr;
8486 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8487 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8490 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8491 : _M_parent(std::__addressof(__parent)),
8492 _M_current(std::move(__current))
8498 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8499 return random_access_iterator_tag{};
8500 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8501 return bidirectional_iterator_tag{};
8502 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8503 return forward_iterator_tag{};
8505 return input_iterator_tag{};
8508 friend cartesian_product_view;
8511 using iterator_category = input_iterator_tag;
8512 using iterator_concept = decltype(_S_iter_concept());
8514 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8515 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8517 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8518 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8519 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8521 _Iterator() = default;
8524 _Iterator(_Iterator<!_Const> __i)
8526 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8527 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8528 : _M_parent(std::__addressof(__i._M_parent)),
8529 _M_current(std::move(__i._M_current))
8535 auto __f = [](auto& __i) -> decltype(auto) {
8538 return __detail::__tuple_transform(__f, _M_current);
8541 constexpr _Iterator&
8553 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8560 constexpr _Iterator&
8562 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8570 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8577 constexpr _Iterator&
8578 operator+=(difference_type __x)
8579 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8585 constexpr _Iterator&
8586 operator-=(difference_type __x)
8587 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8588 { return *this += -__x; }
8591 operator[](difference_type __n) const
8592 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8593 { return *((*this) + __n); }
8595 friend constexpr bool
8596 operator==(const _Iterator& __x, const _Iterator& __y)
8597 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8598 { return __x._M_current == __y._M_current; }
8600 friend constexpr bool
8601 operator==(const _Iterator& __x, default_sentinel_t)
8603 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8604 return ((std::get<_Is>(__x._M_current)
8605 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8607 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8610 friend constexpr auto
8611 operator<=>(const _Iterator& __x, const _Iterator& __y)
8612 requires __detail::__all_random_access<_Const, _First, _Vs...>
8613 { return __x._M_current <=> __y._M_current; }
8615 friend constexpr _Iterator
8616 operator+(_Iterator __x, difference_type __y)
8617 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8618 { return __x += __y; }
8620 friend constexpr _Iterator
8621 operator+(difference_type __x, _Iterator __y)
8622 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8623 { return __y += __x; }
8625 friend constexpr _Iterator
8626 operator-(_Iterator __x, difference_type __y)
8627 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8628 { return __x -= __y; }
8630 friend constexpr difference_type
8631 operator-(const _Iterator& __x, const _Iterator& __y)
8632 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8633 { return __x._M_distance_from(__y._M_current); }
8635 friend constexpr difference_type
8636 operator-(const _Iterator& __i, default_sentinel_t)
8637 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8639 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8640 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8641 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8642 }(make_index_sequence<sizeof...(_Vs)>{});
8643 return __i._M_distance_from(__end_tuple);
8646 friend constexpr difference_type
8647 operator-(default_sentinel_t, const _Iterator& __i)
8648 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8649 { return -(__i - default_sentinel); }
8651 friend constexpr auto
8652 iter_move(const _Iterator& __i)
8653 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8655 friend constexpr void
8656 iter_swap(const _Iterator& __l, const _Iterator& __r)
8657 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8659 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8661 [&]<size_t... _Is>(index_sequence<_Is...>) {
8662 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8663 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8667 template<size_t _Nm = sizeof...(_Vs)>
8671 auto& __it = std::get<_Nm>(_M_current);
8673 if constexpr (_Nm > 0)
8674 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8676 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8681 template<size_t _Nm = sizeof...(_Vs)>
8685 auto& __it = std::get<_Nm>(_M_current);
8686 if constexpr (_Nm > 0)
8687 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8689 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8695 template<size_t _Nm = sizeof...(_Vs)>
8697 _M_advance(difference_type __x)
8698 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8706 // Constant time iterator advancement.
8707 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8708 auto& __it = std::get<_Nm>(_M_current);
8709 if constexpr (_Nm == 0)
8711#ifdef _GLIBCXX_ASSERTIONS
8712 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8714 auto __size = ranges::ssize(__r);
8715 auto __begin = ranges::begin(__r);
8716 auto __offset = __it - __begin;
8717 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8724 auto __size = ranges::ssize(__r);
8725 auto __begin = ranges::begin(__r);
8726 auto __offset = __it - __begin;
8728 __x = __offset / __size;
8732 __offset = __size + __offset;
8735 __it = __begin + __offset;
8736 _M_advance<_Nm - 1>(__x);
8741 template<typename _Tuple>
8742 constexpr difference_type
8743 _M_distance_from(const _Tuple& __t) const
8745 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8746 auto __sum = static_cast<difference_type>(0);
8747#ifdef _GLIBCXX_ASSERTIONS
8748 if constexpr (integral<difference_type>)
8751 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8753 __glibcxx_assert(!__overflow);
8757 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8759 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8762 template<size_t _Nm, typename _Tuple>
8763 constexpr difference_type
8764 _M_scaled_distance(const _Tuple& __t) const
8766 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8767 - std::get<_Nm>(__t));
8768#ifdef _GLIBCXX_ASSERTIONS
8769 if constexpr (integral<difference_type>)
8771 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8772 __glibcxx_assert(!__overflow);
8776 __dist *= _M_scaled_size<_Nm+1>();
8780 template<size_t _Nm>
8781 constexpr difference_type
8782 _M_scaled_size() const
8784 if constexpr (_Nm <= sizeof...(_Vs))
8786 auto __size = static_cast<difference_type>(ranges::size
8787 (std::get<_Nm>(_M_parent->_M_bases)));
8788#ifdef _GLIBCXX_ASSERTIONS
8789 if constexpr (integral<difference_type>)
8791 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8792 __glibcxx_assert(!__overflow);
8796 __size *= _M_scaled_size<_Nm+1>();
8800 return static_cast<difference_type>(1);
8808 template<typename... _Ts>
8809 concept __can_cartesian_product_view
8810 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8813 struct _CartesianProduct
8815 template<typename... _Ts>
8816 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8818 operator() [[nodiscard]] (_Ts&&... __ts) const
8820 if constexpr (sizeof...(_Ts) == 0)
8821 return views::single(tuple{});
8823 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8827 inline constexpr _CartesianProduct cartesian_product;
8829#endif // __cpp_lib_ranges_cartesian_product
8831#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8832 template<input_range _Vp>
8834 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8836 _Vp _M_base = _Vp();
8839 as_rvalue_view() requires default_initializable<_Vp> = default;
8842 as_rvalue_view(_Vp __base)
8843 : _M_base(std::move(__base))
8847 base() const& requires copy_constructible<_Vp>
8852 { return std::move(_M_base); }
8855 begin() requires (!__detail::__simple_view<_Vp>)
8856 { return move_iterator(ranges::begin(_M_base)); }
8859 begin() const requires range<const _Vp>
8860 { return move_iterator(ranges::begin(_M_base)); }
8863 end() requires (!__detail::__simple_view<_Vp>)
8865 if constexpr (common_range<_Vp>)
8866 return move_iterator(ranges::end(_M_base));
8868 return move_sentinel(ranges::end(_M_base));
8872 end() const requires range<const _Vp>
8874 if constexpr (common_range<const _Vp>)
8875 return move_iterator(ranges::end(_M_base));
8877 return move_sentinel(ranges::end(_M_base));
8881 size() requires sized_range<_Vp>
8882 { return ranges::size(_M_base); }
8885 size() const requires sized_range<const _Vp>
8886 { return ranges::size(_M_base); }
8889 template<typename _Range>
8890 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8892 template<typename _Tp>
8893 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8894 = enable_borrowed_range<_Tp>;
8900 template<typename _Tp>
8901 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8904 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8906 template<viewable_range _Range>
8907 requires __detail::__can_as_rvalue_view<_Range>
8909 operator() [[nodiscard]] (_Range&& __r) const
8911 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8912 range_reference_t<_Range>>)
8913 return views::all(std::forward<_Range>(__r));
8915 return as_rvalue_view(std::forward<_Range>(__r));
8919 inline constexpr _AsRvalue as_rvalue;
8921#endif // __cpp_lib_as_rvalue
8923#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8926 template<typename _Range>
8927 concept __range_with_movable_reference = input_range<_Range>
8928 && move_constructible<range_reference_t<_Range>>
8929 && move_constructible<range_rvalue_reference_t<_Range>>;
8933 requires __detail::__range_with_movable_reference<_Vp>
8934 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8936 _Vp _M_base = _Vp();
8938 template<bool _Const> class _Iterator;
8939 template<bool _Const> class _Sentinel;
8942 enumerate_view() requires default_initializable<_Vp> = default;
8945 enumerate_view(_Vp __base)
8946 : _M_base(std::move(__base))
8950 begin() requires (!__detail::__simple_view<_Vp>)
8951 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8954 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8955 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8958 end() requires (!__detail::__simple_view<_Vp>)
8960 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8961 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8963 return _Sentinel<false>(ranges::end(_M_base));
8967 end() const requires __detail::__range_with_movable_reference<const _Vp>
8969 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8970 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8972 return _Sentinel<true>(ranges::end(_M_base));
8976 size() requires sized_range<_Vp>
8977 { return ranges::size(_M_base); }
8980 size() const requires sized_range<const _Vp>
8981 { return ranges::size(_M_base); }
8984 base() const & requires copy_constructible<_Vp>
8989 { return std::move(_M_base); }
8992 template<typename _Range>
8993 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
8995 template<typename _Tp>
8996 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
8997 = enable_borrowed_range<_Tp>;
9000 requires __detail::__range_with_movable_reference<_Vp>
9001 template<bool _Const>
9002 class enumerate_view<_Vp>::_Iterator
9004 using _Base = __maybe_const_t<_Const, _Vp>;
9009 if constexpr (random_access_range<_Base>)
9010 return random_access_iterator_tag{};
9011 else if constexpr (bidirectional_range<_Base>)
9012 return bidirectional_iterator_tag{};
9013 else if constexpr (forward_range<_Base>)
9014 return forward_iterator_tag{};
9016 return input_iterator_tag{};
9019 friend enumerate_view;
9022 using iterator_category = input_iterator_tag;
9023 using iterator_concept = decltype(_S_iter_concept());
9024 using difference_type = range_difference_t<_Base>;
9025 using value_type = tuple<difference_type, range_value_t<_Base>>;
9028 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9030 iterator_t<_Base> _M_current = iterator_t<_Base>();
9031 difference_type _M_pos = 0;
9034 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9035 : _M_current(std::move(__current)), _M_pos(__pos)
9039 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
9042 _Iterator(_Iterator<!_Const> __i)
9043 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9044 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9047 constexpr const iterator_t<_Base> &
9048 base() const & noexcept
9049 { return _M_current; }
9051 constexpr iterator_t<_Base>
9053 { return std::move(_M_current); }
9055 constexpr difference_type
9056 index() const noexcept
9061 { return __reference_type(_M_pos, *_M_current); }
9063 constexpr _Iterator&
9076 operator++(int) requires forward_range<_Base>
9083 constexpr _Iterator&
9084 operator--() requires bidirectional_range<_Base>
9092 operator--(int) requires bidirectional_range<_Base>
9099 constexpr _Iterator&
9100 operator+=(difference_type __n) requires random_access_range<_Base>
9107 constexpr _Iterator&
9108 operator-=(difference_type __n) requires random_access_range<_Base>
9116 operator[](difference_type __n) const requires random_access_range<_Base>
9117 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9119 friend constexpr bool
9120 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9121 { return __x._M_pos == __y._M_pos; }
9123 friend constexpr strong_ordering
9124 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9125 { return __x._M_pos <=> __y._M_pos; }
9127 friend constexpr _Iterator
9128 operator+(const _Iterator& __x, difference_type __y)
9129 requires random_access_range<_Base>
9130 { return (auto(__x) += __y); }
9132 friend constexpr _Iterator
9133 operator+(difference_type __x, const _Iterator& __y)
9134 requires random_access_range<_Base>
9135 { return auto(__y) += __x; }
9137 friend constexpr _Iterator
9138 operator-(const _Iterator& __x, difference_type __y)
9139 requires random_access_range<_Base>
9140 { return auto(__x) -= __y; }
9142 friend constexpr difference_type
9143 operator-(const _Iterator& __x, const _Iterator& __y) noexcept
9144 { return __x._M_pos - __y._M_pos; }
9146 friend constexpr auto
9147 iter_move(const _Iterator& __i)
9148 noexcept(noexcept(ranges::iter_move(__i._M_current))
9149 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9151 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9152 (__i._M_pos, ranges::iter_move(__i._M_current));
9157 requires __detail::__range_with_movable_reference<_Vp>
9158 template<bool _Const>
9159 class enumerate_view<_Vp>::_Sentinel
9161 using _Base = __maybe_const_t<_Const, _Vp>;
9163 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9166 _Sentinel(sentinel_t<_Base> __end)
9167 : _M_end(std::move(__end))
9170 friend enumerate_view;
9173 _Sentinel() = default;
9176 _Sentinel(_Sentinel<!_Const> __other)
9177 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9178 : _M_end(std::move(__other._M_end))
9181 constexpr sentinel_t<_Base>
9185 template<bool _OtherConst>
9186 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9187 friend constexpr bool
9188 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9189 { return __x._M_current == __y._M_end; }
9191 template<bool _OtherConst>
9192 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9193 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9194 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9195 { return __x._M_current - __y._M_end; }
9197 template<bool _OtherConst>
9198 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9199 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9200 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9201 { return __x._M_end - __y._M_current; }
9208 template<typename _Tp>
9209 concept __can_enumerate_view
9210 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9213 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9215 template<viewable_range _Range>
9216 requires __detail::__can_enumerate_view<_Range>
9218 operator() [[nodiscard]] (_Range&& __r) const
9219 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9222 inline constexpr _Enumerate enumerate;
9224#endif // __cpp_lib_ranges_enumerate
9226#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9228 requires input_range<_Vp>
9229 class as_const_view : public view_interface<as_const_view<_Vp>>
9231 _Vp _M_base = _Vp();
9234 as_const_view() requires default_initializable<_Vp> = default;
9237 as_const_view(_Vp __base)
9238 noexcept(is_nothrow_move_constructible_v<_Vp>)
9239 : _M_base(std::move(__base))
9244 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9245 requires copy_constructible<_Vp>
9250 noexcept(is_nothrow_move_constructible_v<_Vp>)
9251 { return std::move(_M_base); }
9254 begin() requires (!__detail::__simple_view<_Vp>)
9255 { return ranges::cbegin(_M_base); }
9258 begin() const requires range<const _Vp>
9259 { return ranges::cbegin(_M_base); }
9262 end() requires (!__detail::__simple_view<_Vp>)
9263 { return ranges::cend(_M_base); }
9266 end() const requires range<const _Vp>
9267 { return ranges::cend(_M_base); }
9270 size() requires sized_range<_Vp>
9271 { return ranges::size(_M_base); }
9274 size() const requires sized_range<const _Vp>
9275 { return ranges::size(_M_base); }
9278 template<typename _Range>
9279 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9281 template<typename _Tp>
9282 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9283 = enable_borrowed_range<_Tp>;
9289 template<typename _Tp>
9290 inline constexpr bool __is_constable_ref_view = false;
9292 template<typename _Range>
9293 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9294 = constant_range<const _Range>;
9296 template<typename _Range>
9297 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9300 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9302 template<viewable_range _Range>
9304 operator()(_Range&& __r) const
9305 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9306 requires __detail::__can_as_const_view<_Range>
9308 using _Tp = remove_cvref_t<_Range>;
9309 using element_type = remove_reference_t<range_reference_t<_Range>>;
9310 if constexpr (constant_range<views::all_t<_Range>>)
9311 return views::all(std::forward<_Range>(__r));
9312 else if constexpr (__detail::__is_empty_view<_Tp>)
9313 return views::empty<const element_type>;
9314 else if constexpr (std::__detail::__is_span<_Tp>)
9315 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9316 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9317 return ref_view(std::as_const(std::forward<_Range>(__r).base()));
9318 else if constexpr (is_lvalue_reference_v<_Range>
9319 && constant_range<const _Tp>
9321 return ref_view(static_cast<const _Tp&>(__r));
9323 return as_const_view(std::forward<_Range>(__r));
9327 inline constexpr _AsConst as_const;
9329#endif // __cpp_lib_as_const
9330} // namespace ranges
9332 namespace views = ranges::views;
9334#if __cpp_lib_ranges_to_container // C++ >= 23
9337/// @cond undocumented
9340 template<typename _Container>
9341 constexpr bool __reservable_container
9342 = sized_range<_Container>
9343 && requires(_Container& __c, range_size_t<_Container> __n) {
9345 { __c.capacity() } -> same_as<decltype(__n)>;
9346 { __c.max_size() } -> same_as<decltype(__n)>;
9349 template<typename _Cont, typename _Range>
9350 constexpr bool __toable = requires {
9351 requires (!input_range<_Cont>
9352 || convertible_to<range_reference_t<_Range>,
9353 range_value_t<_Cont>>);
9355} // namespace __detail
9358 /// Convert a range to a container.
9360 * @tparam _Cont A container type.
9361 * @param __r A range that models the `input_range` concept.
9362 * @param __args... Arguments to pass to the container constructor.
9365 * This function converts a range to the `_Cont` type.
9367 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9368 * will convert the view to `std::vector<int>`.
9370 * Additional constructor arguments for the container can be supplied after
9371 * the input range argument, e.g.
9372 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9374 template<typename _Cont, input_range _Rg, typename... _Args>
9375 requires (!view<_Cont>)
9377 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9379 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9380 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9382 if constexpr (__detail::__toable<_Cont, _Rg>)
9384 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9385 return _Cont(std::forward<_Rg>(__r),
9386 std::forward<_Args>(__args)...);
9387 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9388 return _Cont(from_range, std::forward<_Rg>(__r),
9389 std::forward<_Args>(__args)...);
9390 else if constexpr (requires { requires common_range<_Rg>;
9391 typename __iter_category_t<iterator_t<_Rg>>;
9392 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9393 input_iterator_tag>;
9394 requires constructible_from<_Cont, iterator_t<_Rg>,
9395 sentinel_t<_Rg>, _Args...>;
9397 return _Cont(ranges::begin(__r), ranges::end(__r),
9398 std::forward<_Args>(__args)...);
9401 static_assert(constructible_from<_Cont, _Args...>);
9402 _Cont __c(std::forward<_Args>(__args)...);
9403 if constexpr (sized_range<_Rg>
9404 && __detail::__reservable_container<_Cont>)
9405 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9406 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9407 // 4016. container-insertable checks do not match what
9408 // container-inserter does
9409 auto __it = ranges::begin(__r);
9410 const auto __sent = ranges::end(__r);
9411 while (__it != __sent)
9413 if constexpr (requires { __c.emplace_back(*__it); })
9414 __c.emplace_back(*__it);
9415 else if constexpr (requires { __c.push_back(*__it); })
9416 __c.push_back(*__it);
9417 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9418 __c.emplace(__c.end(), *__it);
9420 __c.insert(__c.end(), *__it);
9428 static_assert(input_range<range_reference_t<_Rg>>);
9429 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9430 // 3984. ranges::to's recursion branch may be ill-formed
9431 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9432 []<typename _Elt>(_Elt&& __elem) {
9433 using _ValT = range_value_t<_Cont>;
9434 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9435 }), std::forward<_Args>(__args)...);
9439/// @cond undocumented
9442 template<typename _Rg>
9445 using iterator_category = input_iterator_tag;
9446 using value_type = range_value_t<_Rg>;
9447 using difference_type = ptrdiff_t;
9448 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9449 using reference = range_reference_t<_Rg>;
9450 reference operator*() const;
9451 pointer operator->() const;
9452 _InputIter& operator++();
9453 _InputIter operator++(int);
9454 bool operator==(const _InputIter&) const;
9457 template<template<typename...> typename _Cont, input_range _Rg,
9460 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9462 template<template<typename...> typename _Cont, input_range _Rg,
9465 = decltype(_Cont(from_range, std::declval<_Rg>(),
9466 std::declval<_Args>()...));
9468 template<template<typename...> typename _Cont, input_range _Rg,
9471 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9472 std::declval<_InputIter<_Rg>>(),
9473 std::declval<_Args>()...));
9475} // namespace __detail
9478 template<template<typename...> typename _Cont, input_range _Rg,
9481 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9483 using __detail::_DeduceExpr1;
9484 using __detail::_DeduceExpr2;
9485 using __detail::_DeduceExpr3;
9486 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9487 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9488 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9489 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9490 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9491 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9492 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9493 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9494 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9496 static_assert(false); // Cannot deduce container specialization.
9499/// @cond undocumented
9502 template<typename _Cont>
9505 template<typename _Range, typename... _Args>
9506 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9507 std::declval<_Args>()...); }
9509 operator()(_Range&& __r, _Args&&... __args) const
9511 return ranges::to<_Cont>(std::forward<_Range>(__r),
9512 std::forward<_Args>(__args)...);
9515} // namespace __detail
9518 /// ranges::to adaptor for converting a range to a container type
9520 * @tparam _Cont A container type.
9521 * @param __args... Arguments to pass to the container constructor.
9524 * This range adaptor returns a range adaptor closure object that converts
9525 * a range to the `_Cont` type.
9527 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9528 * will convert the view to `std::vector<int>`.
9530 * Additional constructor arguments for the container can be supplied, e.g.
9531 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9533 template<typename _Cont, typename... _Args>
9534 requires (!view<_Cont>)
9536 to [[nodiscard]] (_Args&&... __args)
9538 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9539 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9541 using __detail::_To;
9542 using views::__adaptor::_Partial;
9543 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9546/// @cond undocumented
9549 template<template<typename...> typename _Cont>
9552 template<typename _Range, typename... _Args>
9553 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9554 std::declval<_Args>()...); }
9556 operator()(_Range&& __r, _Args&&... __args) const
9558 return ranges::to<_Cont>(std::forward<_Range>(__r),
9559 std::forward<_Args>(__args)...);
9562} // namespace __detail
9565 /// ranges::to adaptor for converting a range to a deduced container type.
9567 * @tparam _Cont A container template.
9568 * @param __args... Arguments to pass to the container constructor.
9571 * This range adaptor returns a range adaptor closure object that converts
9572 * a range to a specialization of the `_Cont` class template. The specific
9573 * specialization of `_Cont` to be used is deduced automatically.
9575 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9576 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9577 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9579 * Additional constructor arguments for the container can be supplied, e.g.
9580 * `r | std::ranges::to<std::vector>(an_allocator)`.
9582 template<template<typename...> typename _Cont, typename... _Args>
9584 to [[nodiscard]] (_Args&&... __args)
9586 using __detail::_To2;
9587 using views::__adaptor::_Partial;
9588 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9591} // namespace ranges
9592#endif // __cpp_lib_ranges_to_container
9594#if __cpp_lib_ranges_concat // C++ >= C++26
9599 template<typename... _Rs>
9600 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9602 template<typename... _Rs>
9603 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9605 template<typename... _Rs>
9606 using __concat_rvalue_reference_t
9607 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9609 template<typename _Ref, typename _RRef, typename _It>
9610 concept __concat_indirectly_readable_impl = requires(const _It __it) {
9611 { *__it } -> convertible_to<_Ref>;
9612 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9615 template<typename... _Rs>
9616 concept __concat_indirectly_readable
9617 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9618 && common_reference_with<__concat_reference_t<_Rs...>&&,
9619 __concat_rvalue_reference_t<_Rs...>&&>
9620 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9621 __concat_value_t<_Rs...> const&>
9622 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9623 __concat_rvalue_reference_t<_Rs...>,
9627 template<typename... _Rs>
9628 concept __concatable = requires {
9629 typename __concat_reference_t<_Rs...>;
9630 typename __concat_value_t<_Rs...>;
9631 typename __concat_rvalue_reference_t<_Rs...>;
9632 } && __concat_indirectly_readable<_Rs...>;
9634 template<bool _Const, typename _Range, typename... _Rs>
9635 struct __all_but_last_common
9637 static inline constexpr bool value
9638 = requires { requires (common_range<__maybe_const_t<_Const, _Range>>
9639 && __all_but_last_common<_Const, _Rs...>::value); };
9642 template<bool _Const, typename _Range>
9643 struct __all_but_last_common<_Const, _Range>
9644 { static inline constexpr bool value = true; };
9646 template<bool _Const, typename... _Rs>
9647 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9648 && __all_but_last_common<_Const, _Rs...>::value;
9650 template<bool _Const, typename... _Rs>
9651 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9652 && __all_but_last_common<_Const, _Rs...>::value;
9654 template<typename _Range, typename... _Rs>
9655 struct __all_but_first_sized
9656 { static inline constexpr bool value = (sized_range<_Rs> && ...); };
9657 } // namespace __detail
9659 template<input_range... _Vs>
9660 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9661 class concat_view : public view_interface<concat_view<_Vs...>>
9663 tuple<_Vs...> _M_views;
9665 template<bool _Const> class _Iterator;
9668 constexpr concat_view() = default;
9671 concat_view(_Vs... __views)
9672 : _M_views(std::move(__views)...)
9675 constexpr _Iterator<false>
9676 begin() requires (!(__detail::__simple_view<_Vs> && ...))
9678 _Iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9679 __it.template _M_satisfy<0>();
9683 constexpr _Iterator<true>
9684 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9686 _Iterator<true> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9687 __it.template _M_satisfy<0>();
9692 end() requires (!(__detail::__simple_view<_Vs> && ...))
9694 constexpr auto __n = sizeof...(_Vs);
9695 if constexpr (__detail::__all_forward<false, _Vs...>
9696 && common_range<_Vs...[__n - 1]>)
9697 return _Iterator<false>(this, in_place_index<__n - 1>,
9698 ranges::end(std::get<__n - 1>(_M_views)));
9700 return default_sentinel;
9704 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9706 constexpr auto __n = sizeof...(_Vs);
9707 if constexpr (__detail::__all_forward<true, _Vs...>
9708 && common_range<const _Vs...[__n - 1]>)
9709 return _Iterator<true>(this, in_place_index<__n - 1>,
9710 ranges::end(std::get<__n - 1>(_M_views)));
9712 return default_sentinel;
9716 size() requires (sized_range<_Vs>&&...)
9718 return std::apply([](auto... __sizes) {
9719 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9720 return (_CT(__sizes) + ...);
9721 }, __detail::__tuple_transform(ranges::size, _M_views));
9725 size() const requires (sized_range<const _Vs>&&...)
9727 return std::apply([](auto... __sizes) {
9728 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9729 return (_CT(__sizes) + ...);
9730 }, __detail::__tuple_transform(ranges::size, _M_views));
9734 template<typename... _Rs>
9735 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9739 template<bool _Const, typename... _Vs>
9740 struct __concat_view_iter_cat
9743 template<bool _Const, typename... _Vs>
9744 requires __detail::__all_forward<_Const, _Vs...>
9745 struct __concat_view_iter_cat<_Const, _Vs...>
9750 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9751 return input_iterator_tag{};
9753 return []<typename... _Cats>(_Cats... __cats) {
9754 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9755 && __concat_is_random_access<_Const, _Vs...>)
9756 return random_access_iterator_tag{};
9757 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9758 && __concat_is_bidirectional<_Const, _Vs...>)
9759 return bidirectional_iterator_tag{};
9760 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9761 return forward_iterator_tag{};
9763 return input_iterator_tag{};
9764 }(typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9765 ::iterator_category{}...);
9770 template<input_range... _Vs>
9771 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9772 template<bool _Const>
9773 class concat_view<_Vs...>::_Iterator
9774 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9779 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9780 return random_access_iterator_tag{};
9781 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9782 return bidirectional_iterator_tag{};
9783 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9784 return forward_iterator_tag{};
9786 return input_iterator_tag{};
9790 friend _Iterator<!_Const>;
9793 // iterator_category defined in __concat_view_iter_cat
9794 using iterator_concept = decltype(_S_iter_concept());
9795 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9796 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9799 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9801 __maybe_const_t<_Const, concat_view>* _M_parent = nullptr;
9804 template<size_t _Nm>
9808 if constexpr (_Nm < (sizeof...(_Vs) - 1))
9810 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9812 _M_it.template emplace<_Nm + 1>(ranges::begin
9813 (std::get<_Nm + 1>(_M_parent->_M_views)));
9814 _M_satisfy<_Nm + 1>();
9819 template<size_t _Nm>
9823 if constexpr (_Nm == 0)
9824 --std::get<0>(_M_it);
9827 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
9829 _M_it.template emplace<_Nm - 1>(ranges::end
9830 (std::get<_Nm - 1>(_M_parent->_M_views)));
9834 --std::get<_Nm>(_M_it);
9838 template<size_t _Nm>
9840 _M_advance_fwd(difference_type __offset, difference_type __steps)
9842 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9843 if constexpr (_Nm == sizeof...(_Vs) - 1)
9844 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9847 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
9848 if (__offset + __steps < __n_size)
9849 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9852 _M_it.template emplace<_Nm + 1>(ranges::begin
9853 (std::get<_Nm + 1>(_M_parent->_M_views)));
9854 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
9859 template<size_t _Nm>
9861 _M_advance_bwd(difference_type __offset, difference_type __steps)
9863 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9864 if constexpr (_Nm == 0)
9865 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9867 if (__offset >= __steps)
9868 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9871 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
9872 _M_it.template emplace<_Nm - 1>(ranges::end
9873 (std::get<_Nm - 1>(_M_parent->_M_views)));
9874 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
9879 // Invoke the function object __f, which has a call operator with a size_t
9880 // template parameter (corresponding to an index into the pack of views),
9881 // using the runtime value of __index as the template argument.
9882 template<typename _Fp>
9883 static constexpr auto
9884 _S_invoke_with_runtime_index(_Fp&& __f, size_t __index)
9886 return [&__f, __index]<size_t _Idx>(this auto&& __self) {
9887 if (_Idx == __index)
9888 return __f.template operator()<_Idx>();
9889 if constexpr (_Idx + 1 < sizeof...(_Vs))
9890 return __self.template operator()<_Idx + 1>();
9891 __builtin_unreachable();
9892 }.template operator()<0>();
9895 template<typename _Fp>
9897 _M_invoke_with_runtime_index(_Fp&& __f)
9898 { return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); }
9900 template<typename... _Args>
9902 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
9903 requires constructible_from<__base_iter, _Args&&...>
9904 : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...)
9908 _Iterator() = default;
9911 _Iterator(_Iterator<!_Const> __it)
9912 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
9913 : _M_parent(__it._M_parent),
9914 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
9915 return __base_iter(in_place_index<_Idx>,
9916 std::get<_Idx>(std::move(__it._M_it)));
9917 }, __it._M_it.index()))
9920 constexpr decltype(auto)
9923 __glibcxx_assert(!_M_it.valueless_by_exception());
9924 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
9925 return std::visit([](auto&& __it) -> reference { return *__it; }, _M_it);
9928 constexpr _Iterator&
9931 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9932 ++std::get<_Idx>(_M_it);
9944 requires __detail::__all_forward<_Const, _Vs...>
9951 constexpr _Iterator&
9953 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9955 __glibcxx_assert(!_M_it.valueless_by_exception());
9956 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9964 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9971 constexpr _Iterator&
9972 operator+=(difference_type __n)
9973 requires __detail::__concat_is_random_access<_Const, _Vs...>
9975 __glibcxx_assert(!_M_it.valueless_by_exception());
9976 _M_invoke_with_runtime_index([this, __n]<size_t _Idx>() {
9977 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
9979 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
9981 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
9986 constexpr _Iterator&
9987 operator-=(difference_type __n)
9988 requires __detail::__concat_is_random_access<_Const, _Vs...>
9994 constexpr decltype(auto)
9995 operator[](difference_type __n) const
9996 requires __detail::__concat_is_random_access<_Const, _Vs...>
9997 { return *((*this) + __n); }
9999 friend constexpr bool
10000 operator==(const _Iterator& __x, const _Iterator& __y)
10001 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10003 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10004 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10005 return __x._M_it == __y._M_it;
10008 friend constexpr bool
10009 operator==(const _Iterator& __it, default_sentinel_t)
10011 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10012 constexpr auto __last_idx = sizeof...(_Vs) - 1;
10013 return (__it._M_it.index() == __last_idx
10014 && (std::get<__last_idx>(__it._M_it)
10015 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10018 friend constexpr bool
10019 operator<(const _Iterator& __x, const _Iterator& __y)
10020 requires __detail::__all_random_access<_Const, _Vs...>
10021 { return __x._M_it < __y._M_it; }
10023 friend constexpr bool
10024 operator>(const _Iterator& __x, const _Iterator& __y)
10025 requires __detail::__all_random_access<_Const, _Vs...>
10026 { return __x._M_it > __y._M_it; }
10028 friend constexpr bool
10029 operator<=(const _Iterator& __x, const _Iterator& __y)
10030 requires __detail::__all_random_access<_Const, _Vs...>
10031 { return __x._M_it <= __y._M_it; }
10033 friend constexpr bool
10034 operator>=(const _Iterator& __x, const _Iterator& __y)
10035 requires __detail::__all_random_access<_Const, _Vs...>
10036 { return __x._M_it >= __y._M_it; }
10038 friend constexpr auto
10039 operator<=>(const _Iterator& __x, const _Iterator& __y)
10040 requires __detail::__all_random_access<_Const, _Vs...>
10041 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10042 { return __x._M_it <=> __y._M_it; }
10044 friend constexpr _Iterator
10045 operator+(const _Iterator& __it, difference_type __n)
10046 requires __detail::__concat_is_random_access<_Const, _Vs...>
10047 { return auto(__it) += __n; }
10049 friend constexpr _Iterator
10050 operator+(difference_type __n, const _Iterator& __it)
10051 requires __detail::__concat_is_random_access<_Const, _Vs...>
10052 { return __it + __n; }
10054 friend constexpr _Iterator
10055 operator-(const _Iterator& __it, difference_type __n)
10056 requires __detail::__concat_is_random_access<_Const, _Vs...>
10057 { return auto(__it) -= __n; }
10059 friend constexpr difference_type
10060 operator-(const _Iterator& __x, const _Iterator& __y)
10061 requires __detail::__concat_is_random_access<_Const, _Vs...>
10063 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10064 return _S_invoke_with_runtime_index([&]<size_t _Iy>() -> difference_type {
10065 if constexpr (_Ix > _Iy)
10067 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10068 ranges::end(std::get<_Iy>(__y._M_parent
10070 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10072 std::get<_Ix>(__x._M_it));
10073 difference_type __s = 0;
10074 [&]<size_t _Idx = _Iy + 1>(this auto&& __self) {
10075 if constexpr (_Idx < _Ix)
10077 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10078 __self.template operator()<_Idx + 1>();
10081 return __dy + __s + __dx;
10083 else if constexpr (_Ix < _Iy)
10084 return -(__y - __x);
10086 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10087 }, __y._M_it.index());
10088 }, __x._M_it.index());
10091 friend constexpr difference_type
10092 operator-(const _Iterator& __x, default_sentinel_t)
10093 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10094 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10095 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10097 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10098 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10099 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10100 difference_type __s = 0;
10101 [&]<size_t _Idx = _Ix + 1>(this auto&& __self) {
10102 if constexpr (_Idx < sizeof...(_Vs))
10104 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10105 __self.template operator()<_Idx + 1>();
10108 return -(__dx + __s);
10109 }, __x._M_it.index());
10112 friend constexpr difference_type
10113 operator-(default_sentinel_t, const _Iterator& __x)
10114 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10115 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10116 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10117 { return -(__x - default_sentinel); }
10119 friend constexpr decltype(auto)
10120 iter_move(const _Iterator& __it)
10122 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10123 return std::visit([](const auto& __i) -> _Res {
10124 return ranges::iter_move(__i);
10128 friend constexpr void
10129 iter_swap(const _Iterator& __x, const _Iterator& __y)
10130 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10131 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10133 std::visit([&]<typename _Tp, typename _Up>(const _Tp& __it1, const _Up& __it2) {
10134 if constexpr (is_same_v<_Tp, _Up>)
10135 ranges::iter_swap(__it1, __it2);
10137 ranges::swap(*__it1, *__it2);
10138 }, __x._M_it, __y._M_it);
10146 template<typename... _Ts>
10147 concept __can_concat_view = requires { concat_view(std::declval<_Ts>()...); };
10152 template<typename... _Ts>
10153 requires __detail::__can_concat_view<_Ts...>
10155 operator() [[nodiscard]] (_Ts&&... __ts) const
10156 { return concat_view(std::forward<_Ts>(__ts)...); }
10158 template<input_range _Range>
10160 operator() [[nodiscard]] (_Range&& __t) const
10161 { return views::all(std::forward<_Range>(__t)); }
10164 inline constexpr _Concat concat;
10167} // namespace ranges
10168#endif // __cpp_lib_ranges_concat
10170#if __cpp_lib_ranges_cache_latest // C++ >= 26
10173 template<input_range _Vp>
10175 class cache_latest_view : public view_interface<cache_latest_view<_Vp>>
10177 _Vp _M_base = _Vp();
10179 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10180 add_pointer_t<range_reference_t<_Vp>>,
10181 range_reference_t<_Vp>>;
10182 __detail::__non_propagating_cache<__cache_t> _M_cache;
10188 cache_latest_view() requires default_initializable<_Vp> = default;
10191 cache_latest_view(_Vp __base)
10192 : _M_base(std::move(__base))
10196 base() const & requires copy_constructible<_Vp>
10197 { return _M_base; }
10201 { return std::move(_M_base); }
10205 { return _Iterator(*this); }
10209 { return _Sentinel(*this); }
10212 size() requires sized_range<_Vp>
10213 { return ranges::size(_M_base); }
10216 size() const requires sized_range<const _Vp>
10217 { return ranges::size(_M_base); }
10220 template<typename _Range>
10221 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10223 template<input_range _Vp>
10225 class cache_latest_view<_Vp>::_Iterator
10227 cache_latest_view* _M_parent;
10228 iterator_t<_Vp> _M_current;
10231 _Iterator(cache_latest_view& __parent)
10232 : _M_parent(std::__addressof(__parent)),
10233 _M_current(ranges::begin(__parent._M_base))
10236 friend class cache_latest_view;
10239 using difference_type = range_difference_t<_Vp>;
10240 using value_type = range_value_t<_Vp>;
10241 using iterator_concept = input_iterator_tag;
10243 _Iterator(_Iterator&&) = default;
10246 operator=(_Iterator&&) = default;
10248 constexpr iterator_t<_Vp>
10250 { return std::move(_M_current); }
10252 constexpr const iterator_t<_Vp>&
10253 base() const & noexcept
10254 { return _M_current; }
10256 constexpr range_reference_t<_Vp>&
10259 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10261 if (!_M_parent->_M_cache)
10262 _M_parent->_M_cache = std::__addressof(__detail::__as_lvalue(*_M_current));
10263 return **_M_parent->_M_cache;
10267 if (!_M_parent->_M_cache)
10268 _M_parent->_M_cache._M_emplace_deref(_M_current);
10269 return *_M_parent->_M_cache;
10273 constexpr _Iterator&
10276 _M_parent->_M_cache._M_reset();
10285 friend constexpr range_rvalue_reference_t<_Vp>
10286 iter_move(const _Iterator& __i)
10287 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10288 { return ranges::iter_move(__i._M_current); }
10290 friend constexpr void
10291 iter_swap(const _Iterator& __x, const _Iterator& __y)
10292 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10293 requires indirectly_swappable<iterator_t<_Vp>>
10294 { ranges::iter_swap(__x._M_current, __y._M_current); }
10297 template<input_range _Vp>
10299 class cache_latest_view<_Vp>::_Sentinel
10301 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10304 _Sentinel(cache_latest_view& __parent)
10305 : _M_end(ranges::end(__parent._M_base))
10308 friend class cache_latest_view;
10311 _Sentinel() = default;
10313 constexpr sentinel_t<_Vp>
10317 friend constexpr bool
10318 operator==(const _Iterator& __x, const _Sentinel& __y)
10319 { return __x._M_current == __y._M_end; }
10321 friend constexpr range_difference_t<_Vp>
10322 operator-(const _Iterator& __x, const _Sentinel& __y)
10323 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10324 { return __x._M_current - __y._M_end; }
10326 friend constexpr range_difference_t<_Vp>
10327 operator-(const _Sentinel& __x, const _Iterator& __y)
10328 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10329 { return __x._M_end - __y._M_current; }
10336 template<typename _Tp>
10337 concept __can_cache_latest = requires { cache_latest_view(std::declval<_Tp>()); };
10340 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10342 template<viewable_range _Range>
10343 requires __detail::__can_cache_latest<_Range>
10345 operator() [[nodiscard]] (_Range&& __r) const
10346 { return cache_latest_view(std::forward<_Range>(__r)); }
10348 static constexpr bool _S_has_simple_call_op = true;
10351 inline constexpr _CacheLatest cache_latest;
10353} // namespace ranges
10354#endif // __cpp_lib_ranges_cache_latest
10356#if __cpp_lib_ranges_to_input // C++ >= 26
10359 template<input_range _Vp>
10361 class to_input_view : public view_interface<to_input_view<_Vp>>
10363 _Vp _M_base = _Vp();
10365 template<bool _Const>
10369 to_input_view() requires default_initializable<_Vp> = default;
10372 to_input_view(_Vp __base)
10373 : _M_base(std::move(__base))
10377 base() const & requires copy_constructible<_Vp>
10378 { return _M_base; }
10382 { return std::move(_M_base); }
10385 begin() requires (!__detail::__simple_view<_Vp>)
10386 { return _Iterator<false>(ranges::begin(_M_base)); }
10389 begin() const requires range<const _Vp>
10390 { return _Iterator<true>(ranges::begin(_M_base)); }
10393 end() requires (!__detail::__simple_view<_Vp>)
10394 { return ranges::end(_M_base); }
10397 end() const requires range<const _Vp>
10398 { return ranges::end(_M_base); }
10401 size() requires sized_range<_Vp>
10402 { return ranges::size(_M_base); }
10405 size() const requires sized_range<const _Vp>
10406 { return ranges::size(_M_base); }
10409 template<typename _Range>
10410 to_input_view(_Range&&) -> to_input_view<views::all_t<_Range>>;
10412 template<input_range _Vp>
10414 template<bool _Const>
10415 class to_input_view<_Vp>::_Iterator
10417 using _Base = __maybe_const_t<_Const, _Vp>;
10419 iterator_t<_Base> _M_current = iterator_t<_Base>();
10422 _Iterator(iterator_t<_Base> __current)
10423 : _M_current(std::move(__current))
10426 friend to_input_view;
10427 friend _Iterator<!_Const>;
10430 using difference_type = range_difference_t<_Base>;
10431 using value_type = range_value_t<_Base>;
10432 using iterator_concept = input_iterator_tag;
10434 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
10436 _Iterator(_Iterator&&) = default;
10437 _Iterator& operator=(_Iterator&&) = default;
10440 _Iterator(_Iterator<!_Const> __i)
10441 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10442 : _M_current(std::move(__i._M_current))
10445 constexpr iterator_t<_Base>
10447 { return std::move(_M_current); }
10449 constexpr const iterator_t<_Base>&
10450 base() const & noexcept
10451 { return _M_current; }
10453 constexpr decltype(auto)
10455 { return *_M_current; }
10457 constexpr _Iterator&
10468 friend constexpr bool
10469 operator==(const _Iterator& __x, const sentinel_t<_Base>& __y)
10470 { return __x._M_current == __y; }
10472 friend constexpr difference_type
10473 operator-(const sentinel_t<_Base>& __y, const _Iterator& __x)
10474 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10475 { return __y - __x._M_current; }
10477 friend constexpr difference_type
10478 operator-(const _Iterator& __x, const sentinel_t<_Base>& __y)
10479 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10480 { return __x._M_current - __y; }
10482 friend constexpr range_rvalue_reference_t<_Base>
10483 iter_move(const _Iterator& __i)
10484 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10485 { return ranges::iter_move(__i._M_current); }
10487 friend constexpr void
10488 iter_swap(const _Iterator& __x, const _Iterator& __y)
10489 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10490 requires indirectly_swappable<iterator_t<_Base>>
10491 { ranges::iter_swap(__x._M_current, __y._M_current); }
10498 template<typename _Tp>
10499 concept __can_to_input = requires { to_input_view(std::declval<_Tp>()); };
10502 struct _ToInput : __adaptor::_RangeAdaptorClosure<_ToInput>
10504 template<viewable_range _Range>
10505 requires __detail::__can_to_input<_Range>
10507 operator() [[nodiscard]] (_Range&& __r) const
10509 if constexpr (input_range<_Range>
10510 && !common_range<_Range>
10511 && !forward_range<_Range>)
10512 return views::all(std::forward<_Range>(__r));
10514 return to_input_view(std::forward<_Range>(__r));
10517 static constexpr bool _S_has_simple_call_op = true;
10520 inline constexpr _ToInput to_input;
10522} // namespace ranges
10523#endif // __cpp_lib_ranges_to_input
10525_GLIBCXX_END_NAMESPACE_VERSION
10527#endif // library concepts
10529#endif /* _GLIBCXX_RANGES */