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_join_with
69#define __glibcxx_want_ranges_repeat
70#define __glibcxx_want_ranges_slide
71#define __glibcxx_want_ranges_stride
72#define __glibcxx_want_ranges_to_container
73#define __glibcxx_want_ranges_to_input
74#define __glibcxx_want_ranges_zip
75#include <bits/version.h>
77#ifdef __glibcxx_generator // C++ >= 23 && __glibcxx_coroutine
78# include <bits/elements_of.h>
82 * @defgroup ranges Ranges
84 * Components for dealing with ranges of elements.
87namespace std _GLIBCXX_VISIBILITY(default)
89_GLIBCXX_BEGIN_NAMESPACE_VERSION
92 // [range.access] customization point objects
93 // [range.req] range and view concepts
94 // [range.dangling] dangling iterator handling
95 // Defined in <bits/ranges_base.h>
97 // [view.interface] View interface
98 // [range.subrange] Sub-ranges
99 // Defined in <bits/ranges_util.h>
101 // C++20 24.6 [range.factories] Range factories
103 /// A view that contains no elements.
104 template<typename _Tp> requires is_object_v<_Tp>
106 : public view_interface<empty_view<_Tp>>
109 static constexpr _Tp* begin() noexcept { return nullptr; }
110 static constexpr _Tp* end() noexcept { return nullptr; }
111 static constexpr _Tp* data() noexcept { return nullptr; }
112 static constexpr size_t size() noexcept { return 0; }
113 static constexpr bool empty() noexcept { return true; }
116 template<typename _Tp>
117 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
121#if __cpp_lib_ranges >= 202207L // C++ >= 23
122 // P2494R2 Relaxing range adaptors to allow for move only types
123 template<typename _Tp>
124 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
126 template<typename _Tp>
127 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
130 template<__boxable _Tp>
131 struct __box : std::optional<_Tp>
133 using std::optional<_Tp>::optional;
137 noexcept(is_nothrow_default_constructible_v<_Tp>)
138 requires default_initializable<_Tp>
139 : std::optional<_Tp>{std::in_place}
142 __box(const __box&) = default;
143 __box(__box&&) = default;
145 using std::optional<_Tp>::operator=;
147 // _GLIBCXX_RESOLVE_LIB_DEFECTS
148 // 3477. Simplify constraints for semiregular-box
149 // 3572. copyable-box should be fully constexpr
151 operator=(const __box& __that)
152 noexcept(is_nothrow_copy_constructible_v<_Tp>)
153 requires (!copyable<_Tp>) && copy_constructible<_Tp>
155 if (this != std::__addressof(__that))
158 this->emplace(*__that);
166 operator=(__box&& __that)
167 noexcept(is_nothrow_move_constructible_v<_Tp>)
168 requires (!movable<_Tp>)
170 if (this != std::__addressof(__that))
173 this->emplace(std::move(*__that));
181 template<typename _Tp>
182 concept __boxable_copyable
183 = copy_constructible<_Tp>
184 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
185 && is_nothrow_copy_constructible_v<_Tp>));
186 template<typename _Tp>
187 concept __boxable_movable
188 = (!copy_constructible<_Tp>)
189 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
191 // For types which are already copyable (or since C++23, movable)
192 // this specialization of the box wrapper stores the object directly
193 // without going through std::optional. It provides just the subset of
194 // the primary template's API that we currently use.
195 template<__boxable _Tp>
196 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
200 [[no_unique_address]] _Tp _M_value = _Tp();
203 __box() requires default_initializable<_Tp> = default;
206 __box(const _Tp& __t)
207 noexcept(is_nothrow_copy_constructible_v<_Tp>)
208 requires copy_constructible<_Tp>
214 noexcept(is_nothrow_move_constructible_v<_Tp>)
215 : _M_value(std::move(__t))
218 template<typename... _Args>
219 requires constructible_from<_Tp, _Args...>
221 __box(in_place_t, _Args&&... __args)
222 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
223 : _M_value(std::forward<_Args>(__args)...)
226 __box(const __box&) = default;
227 __box(__box&&) = default;
228 __box& operator=(const __box&) requires copyable<_Tp> = default;
229 __box& operator=(__box&&) requires movable<_Tp> = default;
231 // When _Tp is nothrow_copy_constructible but not copy_assignable,
232 // copy assignment is implemented via destroy-then-copy-construct.
234 operator=(const __box& __that) noexcept
235 requires (!copyable<_Tp>) && copy_constructible<_Tp>
237 static_assert(is_nothrow_copy_constructible_v<_Tp>);
238 if (this != std::__addressof(__that))
241 std::construct_at(std::__addressof(_M_value), *__that);
246 // Likewise for move assignment.
248 operator=(__box&& __that) noexcept
249 requires (!movable<_Tp>)
251 static_assert(is_nothrow_move_constructible_v<_Tp>);
252 if (this != std::__addressof(__that))
255 std::construct_at(std::__addressof(_M_value), std::move(*__that));
261 has_value() const noexcept
265 operator*() & noexcept
269 operator*() const & noexcept
273 operator*() && noexcept
274 { return std::move(_M_value); }
276 constexpr const _Tp&&
277 operator*() const && noexcept
278 { return std::move(_M_value); }
281 operator->() noexcept
282 { return std::__addressof(_M_value); }
285 operator->() const noexcept
286 { return std::__addressof(_M_value); }
288 } // namespace __detail
290 /// A view that contains exactly one element.
291#if __cpp_lib_ranges >= 202207L // C++ >= 23
292 template<move_constructible _Tp>
294 template<copy_constructible _Tp>
296 requires is_object_v<_Tp>
297 class single_view : public view_interface<single_view<_Tp>>
300 single_view() requires default_initializable<_Tp> = default;
303 single_view(const _Tp& __t)
304 noexcept(is_nothrow_copy_constructible_v<_Tp>)
305 requires copy_constructible<_Tp>
310 single_view(_Tp&& __t)
311 noexcept(is_nothrow_move_constructible_v<_Tp>)
312 : _M_value(std::move(__t))
315 // _GLIBCXX_RESOLVE_LIB_DEFECTS
316 // 3428. single_view's in place constructor should be explicit
317 template<typename... _Args>
318 requires constructible_from<_Tp, _Args...>
320 single_view(in_place_t, _Args&&... __args)
321 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
322 : _M_value{in_place, std::forward<_Args>(__args)...}
330 begin() const noexcept
335 { return data() + 1; }
339 { return data() + 1; }
341 // _GLIBCXX_RESOLVE_LIB_DEFECTS
342 // 4035. single_view should provide empty
343 static constexpr bool
347 static constexpr size_t
353 { return _M_value.operator->(); }
356 data() const noexcept
357 { return _M_value.operator->(); }
360 [[no_unique_address]] __detail::__box<_Tp> _M_value;
363 template<typename _Tp>
364 single_view(_Tp) -> single_view<_Tp>;
368 template<typename _Wp>
369 constexpr auto __to_signed_like(_Wp __w) noexcept
371 if constexpr (!integral<_Wp>)
372 return iter_difference_t<_Wp>();
373 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
374 return iter_difference_t<_Wp>(__w);
375 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
376 return ptrdiff_t(__w);
377 else if constexpr (sizeof(long long) > sizeof(_Wp))
378 return (long long)(__w);
379#ifdef __SIZEOF_INT128__
380 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
381 return __int128(__w);
384 return __max_diff_type(__w);
387 template<typename _Wp>
388 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
390 template<typename _It>
391 concept __decrementable = incrementable<_It>
394 { --__i } -> same_as<_It&>;
395 { __i-- } -> same_as<_It>;
398 template<typename _It>
399 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
400 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
402 { __i += __n } -> same_as<_It&>;
403 { __i -= __n } -> same_as<_It&>;
407 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
410 template<typename _Winc>
411 struct __iota_view_iter_cat
414 template<incrementable _Winc>
415 struct __iota_view_iter_cat<_Winc>
416 { using iterator_category = input_iterator_tag; };
417 } // namespace __detail
419 template<weakly_incrementable _Winc,
420 semiregular _Bound = unreachable_sentinel_t>
421 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
423 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
428 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
434 using namespace __detail;
435 if constexpr (__advanceable<_Winc>)
436 return random_access_iterator_tag{};
437 else if constexpr (__decrementable<_Winc>)
438 return bidirectional_iterator_tag{};
439 else if constexpr (incrementable<_Winc>)
440 return forward_iterator_tag{};
442 return input_iterator_tag{};
446 using iterator_concept = decltype(_S_iter_concept());
447 // iterator_category defined in __iota_view_iter_cat
448 using value_type = _Winc;
449 using difference_type = __detail::__iota_diff_t<_Winc>;
451 _Iterator() requires default_initializable<_Winc> = default;
454 _Iterator(_Winc __value)
455 : _M_value(__value) { }
458 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
473 operator++(int) requires incrementable<_Winc>
481 operator--() requires __detail::__decrementable<_Winc>
488 operator--(int) requires __detail::__decrementable<_Winc>
496 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
498 using __detail::__is_integer_like;
499 using __detail::__is_signed_integer_like;
500 if constexpr (__is_integer_like<_Winc>
501 && !__is_signed_integer_like<_Winc>)
503 if (__n >= difference_type(0))
504 _M_value += static_cast<_Winc>(__n);
506 _M_value -= static_cast<_Winc>(-__n);
514 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
516 using __detail::__is_integer_like;
517 using __detail::__is_signed_integer_like;
518 if constexpr (__is_integer_like<_Winc>
519 && !__is_signed_integer_like<_Winc>)
521 if (__n >= difference_type(0))
522 _M_value -= static_cast<_Winc>(__n);
524 _M_value += static_cast<_Winc>(-__n);
532 operator[](difference_type __n) const
533 requires __detail::__advanceable<_Winc>
534 { return _Winc(_M_value + __n); }
536 friend constexpr bool
537 operator==(const _Iterator& __x, const _Iterator& __y)
538 requires equality_comparable<_Winc>
539 { return __x._M_value == __y._M_value; }
541 friend constexpr bool
542 operator<(const _Iterator& __x, const _Iterator& __y)
543 requires totally_ordered<_Winc>
544 { return __x._M_value < __y._M_value; }
546 friend constexpr bool
547 operator>(const _Iterator& __x, const _Iterator& __y)
548 requires totally_ordered<_Winc>
549 { return __y < __x; }
551 friend constexpr bool
552 operator<=(const _Iterator& __x, const _Iterator& __y)
553 requires totally_ordered<_Winc>
554 { return !(__y < __x); }
556 friend constexpr bool
557 operator>=(const _Iterator& __x, const _Iterator& __y)
558 requires totally_ordered<_Winc>
559 { return !(__x < __y); }
561#ifdef __cpp_lib_three_way_comparison
562 friend constexpr auto
563 operator<=>(const _Iterator& __x, const _Iterator& __y)
564 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
565 { return __x._M_value <=> __y._M_value; }
568 friend constexpr _Iterator
569 operator+(_Iterator __i, difference_type __n)
570 requires __detail::__advanceable<_Winc>
576 friend constexpr _Iterator
577 operator+(difference_type __n, _Iterator __i)
578 requires __detail::__advanceable<_Winc>
579 { return __i += __n; }
581 friend constexpr _Iterator
582 operator-(_Iterator __i, difference_type __n)
583 requires __detail::__advanceable<_Winc>
589 friend constexpr difference_type
590 operator-(const _Iterator& __x, const _Iterator& __y)
591 requires __detail::__advanceable<_Winc>
593 using __detail::__is_integer_like;
594 using __detail::__is_signed_integer_like;
595 using _Dt = difference_type;
596 if constexpr (__is_integer_like<_Winc>)
598 if constexpr (__is_signed_integer_like<_Winc>)
599 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
601 return (__y._M_value > __x._M_value)
602 ? _Dt(-_Dt(__y._M_value - __x._M_value))
603 : _Dt(__x._M_value - __y._M_value);
606 return __x._M_value - __y._M_value;
610 _Winc _M_value = _Winc();
620 _M_equal(const _Iterator& __x) const
621 { return __x._M_value == _M_bound; }
624 _M_distance_from(const _Iterator& __x) const
625 { return _M_bound - __x._M_value; }
627 _Bound _M_bound = _Bound();
630 _Sentinel() = default;
633 _Sentinel(_Bound __bound)
634 : _M_bound(__bound) { }
636 friend constexpr bool
637 operator==(const _Iterator& __x, const _Sentinel& __y)
638 { return __y._M_equal(__x); }
640 friend constexpr iter_difference_t<_Winc>
641 operator-(const _Iterator& __x, const _Sentinel& __y)
642 requires sized_sentinel_for<_Bound, _Winc>
643 { return -__y._M_distance_from(__x); }
645 friend constexpr iter_difference_t<_Winc>
646 operator-(const _Sentinel& __x, const _Iterator& __y)
647 requires sized_sentinel_for<_Bound, _Winc>
648 { return __x._M_distance_from(__y); }
653 _Winc _M_value = _Winc();
654 [[no_unique_address]] _Bound _M_bound = _Bound();
657 iota_view() requires default_initializable<_Winc> = default;
660 iota_view(_Winc __value)
665 iota_view(type_identity_t<_Winc> __value,
666 type_identity_t<_Bound> __bound)
667 : _M_value(__value), _M_bound(__bound)
669 if constexpr (totally_ordered_with<_Winc, _Bound>)
670 __glibcxx_assert( bool(__value <= __bound) );
674 iota_view(_Iterator __first, _Iterator __last)
675 requires same_as<_Winc, _Bound>
676 : iota_view(__first._M_value, __last._M_value)
680 iota_view(_Iterator __first, unreachable_sentinel_t __last)
681 requires same_as<_Bound, unreachable_sentinel_t>
682 : iota_view(__first._M_value, __last)
686 iota_view(_Iterator __first, _Sentinel __last)
687 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
688 : iota_view(__first._M_value, __last._M_bound)
692 begin() const { return _Iterator{_M_value}; }
697 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
698 return unreachable_sentinel;
700 return _Sentinel{_M_bound};
704 end() const requires same_as<_Winc, _Bound>
705 { return _Iterator{_M_bound}; }
707 // _GLIBCXX_RESOLVE_LIB_DEFECTS
708 // 4001. iota_view should provide empty
711 { return _M_value == _M_bound; }
715 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
716 || (integral<_Winc> && integral<_Bound>)
717 || sized_sentinel_for<_Bound, _Winc>
719 using __detail::__is_integer_like;
720 using __detail::__to_unsigned_like;
721 if constexpr (integral<_Winc> && integral<_Bound>)
723 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
724 return _Up(_M_bound) - _Up(_M_value);
726 else if constexpr (__is_integer_like<_Winc>)
727 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
729 return __to_unsigned_like(_M_bound - _M_value);
733 template<typename _Winc, typename _Bound>
734 requires (!__detail::__is_integer_like<_Winc>
735 || !__detail::__is_integer_like<_Bound>
736 || (__detail::__is_signed_integer_like<_Winc>
737 == __detail::__is_signed_integer_like<_Bound>))
738 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
740 template<typename _Winc, typename _Bound>
741 inline constexpr bool
742 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
746 template<typename _Tp>
747 inline constexpr empty_view<_Tp> empty{};
751 template<typename _Tp>
752 concept __can_single_view
753 = requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
754 } // namespace __detail
758 template<__detail::__can_single_view _Tp>
760 operator() [[nodiscard]] (_Tp&& __e) const
761 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
762 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
765 inline constexpr _Single single{};
769 template<typename... _Args>
770 concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); };
771 } // namespace __detail
775 template<__detail::__can_iota_view _Tp>
777 operator() [[nodiscard]] (_Tp&& __e) const
778 { return iota_view(std::forward<_Tp>(__e)); }
780 template<typename _Tp, typename _Up>
781 requires __detail::__can_iota_view<_Tp, _Up>
783 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const
784 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
787 inline constexpr _Iota iota{};
793 template<typename _Val, typename _CharT, typename _Traits>
794 concept __stream_extractable
795 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
796 } // namespace __detail
798 template<movable _Val, typename _CharT,
799 typename _Traits = char_traits<_CharT>>
800 requires default_initializable<_Val>
801 && __detail::__stream_extractable<_Val, _CharT, _Traits>
802 class basic_istream_view
803 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
807 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
808 : _M_stream(std::__addressof(__stream))
814 *_M_stream >> _M_object;
815 return _Iterator{this};
818 constexpr default_sentinel_t
820 { return default_sentinel; }
823 basic_istream<_CharT, _Traits>* _M_stream;
824 _Val _M_object = _Val();
829 using iterator_concept = input_iterator_tag;
830 using difference_type = ptrdiff_t;
831 using value_type = _Val;
834 _Iterator(basic_istream_view* __parent) noexcept
835 : _M_parent(__parent)
838 _Iterator(const _Iterator&) = delete;
839 _Iterator(_Iterator&&) = default;
840 _Iterator& operator=(const _Iterator&) = delete;
841 _Iterator& operator=(_Iterator&&) = default;
846 *_M_parent->_M_stream >> _M_parent->_M_object;
856 { return _M_parent->_M_object; }
859 operator==(const _Iterator& __x, default_sentinel_t)
860 { return __x._M_at_end(); }
863 basic_istream_view* _M_parent;
867 { return !*_M_parent->_M_stream; }
873 template<typename _Val>
874 using istream_view = basic_istream_view<_Val, char>;
876 template<typename _Val>
877 using wistream_view = basic_istream_view<_Val, wchar_t>;
883 template<typename _Tp, typename _Up>
884 concept __can_istream_view = requires (_Up __e) {
885 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
887 } // namespace __detail
889 template<typename _Tp>
892 template<typename _CharT, typename _Traits>
894 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
895 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
896 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
899 template<typename _Tp>
900 inline constexpr _Istream<_Tp> istream;
904 // C++20 24.7 [range.adaptors] Range adaptors
908 template<typename _Tp, int _Disc>
911 // Alias for a type that is conditionally present
912 // (and is an empty type otherwise).
913 // Data members using this alias should use [[no_unique_address]] so that
914 // they take no space when not needed.
915 // The optional template parameter _Disc is for discriminating two otherwise
916 // equivalent absent types so that even they can overlap.
917 template<bool _Present, typename _Tp, int _Disc = 0>
918 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
920 // Alias for a type that is conditionally const.
921 template<bool _Const, typename _Tp>
922 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
924} // namespace __detail
926// Shorthand for __detail::__maybe_const_t.
927using __detail::__maybe_const_t;
929namespace views::__adaptor
931 // True if the range adaptor _Adaptor can be applied with _Args.
932 template<typename _Adaptor, typename... _Args>
933 concept __adaptor_invocable
934 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
936 // True if the range adaptor non-closure _Adaptor can be partially applied
938 template<typename _Adaptor, typename... _Args>
939 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
940 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
941 && (constructible_from<decay_t<_Args>, _Args> && ...);
943 template<typename _Adaptor, typename... _Args>
946 template<typename _Lhs, typename _Rhs>
949 // The base class of every range adaptor closure.
951 // The derived class should define the optional static data member
952 // _S_has_simple_call_op to true if the behavior of this adaptor is
953 // independent of the constness/value category of the adaptor object.
954 template<typename _Derived>
955 struct _RangeAdaptorClosure;
957 template<typename _Tp, typename _Up>
958 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
959 void __is_range_adaptor_closure_fn
960 (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined
962 template<typename _Tp>
963 concept __is_range_adaptor_closure
964 = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
966#pragma GCC diagnostic push
967#pragma GCC diagnostic ignored "-Wdangling-reference"
968 // range | adaptor is equivalent to adaptor(range).
969 template<typename _Self, typename _Range>
970 requires __is_range_adaptor_closure<_Self>
971 && __adaptor_invocable<_Self, _Range>
973 operator|(_Range&& __r, _Self&& __self)
974 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
976 // Compose the adaptors __lhs and __rhs into a pipeline, returning
977 // another range adaptor closure object.
978 template<typename _Lhs, typename _Rhs>
979 requires __is_range_adaptor_closure<_Lhs>
980 && __is_range_adaptor_closure<_Rhs>
982 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
984 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
985 std::forward<_Rhs>(__rhs)};
987#pragma GCC diagnostic pop
989 template<typename _Derived>
990 struct _RangeAdaptorClosure
992 // In non-modules compilation ADL finds these operators either way and
993 // the friend declarations are redundant. But with the std module these
994 // friend declarations enable ADL to find these operators without having
996 template<typename _Self, typename _Range>
997 requires __is_range_adaptor_closure<_Self>
998 && __adaptor_invocable<_Self, _Range>
999 friend constexpr auto
1000 operator|(_Range&& __r, _Self&& __self);
1002 template<typename _Lhs, typename _Rhs>
1003 requires __is_range_adaptor_closure<_Lhs>
1004 && __is_range_adaptor_closure<_Rhs>
1005 friend constexpr auto
1006 operator|(_Lhs&& __lhs, _Rhs&& __rhs);
1009 // The base class of every range adaptor non-closure.
1011 // The static data member _Derived::_S_arity must contain the total number of
1012 // arguments that the adaptor takes, and the class _Derived must introduce
1013 // _RangeAdaptor::operator() into the class scope via a using-declaration.
1015 // The optional static data member _Derived::_S_has_simple_extra_args should
1016 // be defined to true if the behavior of this adaptor is independent of the
1017 // constness/value category of the extra arguments. This data member could
1018 // also be defined as a variable template parameterized by the types of the
1020 template<typename _Derived>
1021 struct _RangeAdaptor
1023 // Partially apply the arguments __args to the range adaptor _Derived,
1024 // returning a range adaptor closure object.
1025 template<typename... _Args>
1026 requires __adaptor_partial_app_viable<_Derived, _Args...>
1028 operator()(_Args&&... __args) const
1030 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
1034 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
1035 // one that's not overloaded according to constness or value category of the
1037 template<typename _Adaptor>
1038 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1040 // True if the behavior of the range adaptor non-closure _Adaptor is
1041 // independent of the value category of its extra arguments _Args.
1042 template<typename _Adaptor, typename... _Args>
1043 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1044 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1046 // A range adaptor closure that represents partial application of
1047 // the range adaptor _Adaptor with arguments _Args.
1048 template<typename _Adaptor, typename... _Args>
1049 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1051 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1052 [[no_unique_address]] _Binder _M_binder;
1054 // First parameter is to ensure this constructor is never used
1055 // instead of the copy/move constructor.
1056 template<typename... _Ts>
1058 _Partial(int, _Ts&&... __args)
1059 : _M_binder(0, _Adaptor(), std::forward<_Ts>(__args)...)
1062 // Invoke _Adaptor with arguments __r, _M_args... according to the
1063 // value category of this _Partial object.
1064#if __cpp_explicit_this_parameter
1065 template<typename _Self, typename _Range>
1066 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1068 operator()(this _Self&& __self, _Range&& __r)
1070 return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
1071 std::forward<_Range>(__r));
1074 template<typename _Range>
1075 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1077 operator()(_Range&& __r) const &
1078 { return _Binder::_S_call(_M_binder, std::forward<_Range>(__r)); }
1080 template<typename _Range>
1081 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1083 operator()(_Range&& __r) &&
1084 { return _Binder::_S_call(std::move(_M_binder), std::forward<_Range>(__r)); }
1086 template<typename _Range>
1088 operator()(_Range&& __r) const && = delete;
1092 // Partial specialization of the primary template for the case where the extra
1093 // arguments of the adaptor can always be safely and efficiently forwarded by
1094 // const reference. This lets us get away with a single operator() overload,
1095 // which makes overload resolution failure diagnostics more concise.
1096 template<typename _Adaptor, typename... _Args>
1097 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1098 && (is_trivially_copy_constructible_v<_Args> && ...)
1099 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1101 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1102 [[no_unique_address]] _Binder _M_binder;
1104 template<typename... _Ts>
1106 _Partial(int, _Ts&&... __args)
1107 : _M_binder(0, _Adaptor(), std::forward<_Ts>(__args)...)
1110 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1111 // of the value category of this _Partial object.
1112 template<typename _Range>
1113 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1115 operator()(_Range&& __r) const
1116 { return _Binder::_S_call(_M_binder, std::forward<_Range>(__r)); }
1118 static constexpr bool _S_has_simple_call_op = true;
1121 template<typename _Lhs, typename _Rhs, typename _Range>
1122 concept __pipe_invocable
1123 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1125 // A range adaptor closure that represents composition of the range
1126 // adaptor closures _Lhs and _Rhs.
1127 template<typename _Lhs, typename _Rhs>
1128 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1130 [[no_unique_address]] _Lhs _M_lhs;
1131 [[no_unique_address]] _Rhs _M_rhs;
1133 template<typename _Tp, typename _Up>
1135 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1136 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1139 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1140 // range adaptor closure object.
1141#if __cpp_explicit_this_parameter
1142 template<typename _Self, typename _Range>
1143 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1145 operator()(this _Self&& __self, _Range&& __r)
1147 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1148 (__like_t<_Self, _Pipe>(__self)._M_lhs
1149 (std::forward<_Range>(__r))));
1152 template<typename _Range>
1153 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1155 operator()(_Range&& __r) const &
1156 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1158 template<typename _Range>
1159 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1161 operator()(_Range&& __r) &&
1162 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1164 template<typename _Range>
1166 operator()(_Range&& __r) const && = delete;
1170 // A partial specialization of the above primary template for the case where
1171 // both adaptor operands have a simple operator(). This in turn lets us
1172 // implement composition using a single simple operator(), which makes
1173 // overload resolution failure diagnostics more concise.
1174 template<typename _Lhs, typename _Rhs>
1175 requires __closure_has_simple_call_op<_Lhs>
1176 && __closure_has_simple_call_op<_Rhs>
1177 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1179 [[no_unique_address]] _Lhs _M_lhs;
1180 [[no_unique_address]] _Rhs _M_rhs;
1182 template<typename _Tp, typename _Up>
1184 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1185 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1188 template<typename _Range>
1189 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1191 operator()(_Range&& __r) const
1192 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1194 static constexpr bool _S_has_simple_call_op = true;
1196} // namespace views::__adaptor
1198#if __cpp_lib_ranges >= 202202L
1199 // P2387R3 Pipe support for user-defined range adaptors
1200 template<typename _Derived>
1201 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1202 class range_adaptor_closure
1203 : public views::__adaptor::_RangeAdaptorClosure<_Derived>
1207 template<range _Range> requires is_object_v<_Range>
1208 class ref_view : public view_interface<ref_view<_Range>>
1213 static void _S_fun(_Range&); // not defined
1214 static void _S_fun(_Range&&) = delete;
1217 template<__detail::__different_from<ref_view> _Tp>
1218 requires convertible_to<_Tp, _Range&>
1219 && requires { _S_fun(declval<_Tp>()); }
1222 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1223 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1230 constexpr iterator_t<_Range>
1232 { return ranges::begin(*_M_r); }
1234 constexpr sentinel_t<_Range>
1236 { return ranges::end(*_M_r); }
1239 empty() const requires requires { ranges::empty(*_M_r); }
1240 { return ranges::empty(*_M_r); }
1243 size() const requires sized_range<_Range>
1244 { return ranges::size(*_M_r); }
1247 data() const requires contiguous_range<_Range>
1248 { return ranges::data(*_M_r); }
1251 template<typename _Range>
1252 ref_view(_Range&) -> ref_view<_Range>;
1254 template<typename _Tp>
1255 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1257 template<range _Range>
1258 requires movable<_Range>
1259 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1260 class owning_view : public view_interface<owning_view<_Range>>
1263 _Range _M_r = _Range();
1266 owning_view() requires default_initializable<_Range> = default;
1269 owning_view(_Range&& __t)
1270 noexcept(is_nothrow_move_constructible_v<_Range>)
1271 : _M_r(std::move(__t))
1274 owning_view(owning_view&&) = default;
1275 owning_view& operator=(owning_view&&) = default;
1281 constexpr const _Range&
1282 base() const& noexcept
1287 { return std::move(_M_r); }
1289 constexpr const _Range&&
1290 base() const&& noexcept
1291 { return std::move(_M_r); }
1293 constexpr iterator_t<_Range>
1295 { return ranges::begin(_M_r); }
1297 constexpr sentinel_t<_Range>
1299 { return ranges::end(_M_r); }
1302 begin() const requires range<const _Range>
1303 { return ranges::begin(_M_r); }
1306 end() const requires range<const _Range>
1307 { return ranges::end(_M_r); }
1310 empty() requires requires { ranges::empty(_M_r); }
1311 { return ranges::empty(_M_r); }
1314 empty() const requires requires { ranges::empty(_M_r); }
1315 { return ranges::empty(_M_r); }
1318 size() requires sized_range<_Range>
1319 { return ranges::size(_M_r); }
1322 size() const requires sized_range<const _Range>
1323 { return ranges::size(_M_r); }
1326 data() requires contiguous_range<_Range>
1327 { return ranges::data(_M_r); }
1330 data() const requires contiguous_range<const _Range>
1331 { return ranges::data(_M_r); }
1334 template<typename _Tp>
1335 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1336 = enable_borrowed_range<_Tp>;
1342 template<typename _Range>
1343 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1345 template<typename _Range>
1346 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1347 } // namespace __detail
1349 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1351 template<typename _Range>
1352 static constexpr bool
1355 if constexpr (view<decay_t<_Range>>)
1356 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1357 else if constexpr (__detail::__can_ref_view<_Range>)
1360 return noexcept(owning_view{std::declval<_Range>()});
1363 template<viewable_range _Range>
1364 requires view<decay_t<_Range>>
1365 || __detail::__can_ref_view<_Range>
1366 || __detail::__can_owning_view<_Range>
1368 operator() [[nodiscard]] (_Range&& __r) const
1369 noexcept(_S_noexcept<_Range>())
1371 if constexpr (view<decay_t<_Range>>)
1372 return std::forward<_Range>(__r);
1373 else if constexpr (__detail::__can_ref_view<_Range>)
1374 return ref_view{std::forward<_Range>(__r)};
1376 return owning_view{std::forward<_Range>(__r)};
1379 static constexpr bool _S_has_simple_call_op = true;
1382 inline constexpr _All all;
1384 template<viewable_range _Range>
1385 using all_t = decltype(all(std::declval<_Range>()));
1386 } // namespace views
1390 template<typename _Tp>
1391 struct __non_propagating_cache
1393 // When _Tp is not an object type (e.g. is a reference type), we make
1394 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1395 // users can easily conditionally declare data members with this type
1396 // (such as join_view::_M_inner).
1399 template<typename _Tp>
1400 requires is_object_v<_Tp>
1401 struct __non_propagating_cache<_Tp>
1402 : protected _Optional_base<_Tp>
1404 __non_propagating_cache() = default;
1407 __non_propagating_cache(const __non_propagating_cache&) noexcept
1411 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1412 { __other._M_reset(); }
1414 constexpr __non_propagating_cache&
1415 operator=(const __non_propagating_cache& __other) noexcept
1417 if (std::__addressof(__other) != this)
1422 constexpr __non_propagating_cache&
1423 operator=(__non_propagating_cache&& __other) noexcept
1430 constexpr __non_propagating_cache&
1431 operator=(_Tp __val)
1434 this->_M_payload._M_construct(std::move(__val));
1439 operator bool() const noexcept
1440 { return this->_M_is_engaged(); }
1443 operator*() noexcept
1444 { return this->_M_get(); }
1446 constexpr const _Tp&
1447 operator*() const noexcept
1448 { return this->_M_get(); }
1450 template<typename _Iter>
1452 _M_emplace_deref(const _Iter& __i)
1455 auto __f = [] (auto& __x) { return *__x; };
1456 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1457 return this->_M_get();
1460 using _Optional_base<_Tp>::_M_reset;
1463 template<range _Range>
1464 struct _CachedPosition
1467 _M_has_value() const
1470 constexpr iterator_t<_Range>
1471 _M_get(const _Range&) const
1473 __glibcxx_assert(false);
1474 __builtin_unreachable();
1478 _M_set(const _Range&, const iterator_t<_Range>&) const
1482 template<forward_range _Range>
1483 struct _CachedPosition<_Range>
1484 : protected __non_propagating_cache<iterator_t<_Range>>
1487 _M_has_value() const
1488 { return this->_M_is_engaged(); }
1490 constexpr iterator_t<_Range>
1491 _M_get(const _Range&) const
1493 __glibcxx_assert(_M_has_value());
1498 _M_set(const _Range&, const iterator_t<_Range>& __it)
1500 __glibcxx_assert(!_M_has_value());
1501 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1503 this->_M_payload._M_engaged = true;
1507 template<random_access_range _Range>
1508 struct _CachedPosition<_Range>
1511 range_difference_t<_Range> _M_offset = -1;
1514 _CachedPosition() = default;
1517 _CachedPosition(const _CachedPosition&) = default;
1520 _CachedPosition(_CachedPosition&& __other) noexcept
1521 { *this = std::move(__other); }
1523 constexpr _CachedPosition&
1524 operator=(const _CachedPosition&) = default;
1526 constexpr _CachedPosition&
1527 operator=(_CachedPosition&& __other) noexcept
1529 // Propagate the cached offset, but invalidate the source.
1530 _M_offset = __other._M_offset;
1531 __other._M_offset = -1;
1536 _M_has_value() const
1537 { return _M_offset >= 0; }
1539 constexpr iterator_t<_Range>
1540 _M_get(_Range& __r) const
1542 __glibcxx_assert(_M_has_value());
1543 return ranges::begin(__r) + _M_offset;
1547 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1549 __glibcxx_assert(!_M_has_value());
1550 _M_offset = __it - ranges::begin(__r);
1553 } // namespace __detail
1557 template<typename _Base>
1558 struct __filter_view_iter_cat
1561 template<forward_range _Base>
1562 struct __filter_view_iter_cat<_Base>
1568 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1569 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1570 return bidirectional_iterator_tag{};
1571 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1572 return forward_iterator_tag{};
1577 using iterator_category = decltype(_S_iter_cat());
1579 } // namespace __detail
1581 template<input_range _Vp,
1582 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1583 requires view<_Vp> && is_object_v<_Pred>
1584 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1589 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1592 static constexpr auto
1595 if constexpr (bidirectional_range<_Vp>)
1596 return bidirectional_iterator_tag{};
1597 else if constexpr (forward_range<_Vp>)
1598 return forward_iterator_tag{};
1600 return input_iterator_tag{};
1605 using _Vp_iter = iterator_t<_Vp>;
1607 _Vp_iter _M_current = _Vp_iter();
1608 filter_view* _M_parent = nullptr;
1611 using iterator_concept = decltype(_S_iter_concept());
1612 // iterator_category defined in __filter_view_iter_cat
1613 using value_type = range_value_t<_Vp>;
1614 using difference_type = range_difference_t<_Vp>;
1616 _Iterator() requires default_initializable<_Vp_iter> = default;
1619 _Iterator(filter_view* __parent, _Vp_iter __current)
1620 : _M_current(std::move(__current)),
1624 constexpr const _Vp_iter&
1625 base() const & noexcept
1626 { return _M_current; }
1630 { return std::move(_M_current); }
1632 constexpr range_reference_t<_Vp>
1634 { return *_M_current; }
1638 requires __detail::__has_arrow<_Vp_iter>
1639 && copyable<_Vp_iter>
1640 { return _M_current; }
1642 constexpr _Iterator&
1645 _M_current = ranges::find_if(std::move(++_M_current),
1646 ranges::end(_M_parent->_M_base),
1647 std::ref(*_M_parent->_M_pred));
1656 operator++(int) requires forward_range<_Vp>
1663 constexpr _Iterator&
1664 operator--() requires bidirectional_range<_Vp>
1668 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1673 operator--(int) requires bidirectional_range<_Vp>
1680 friend constexpr bool
1681 operator==(const _Iterator& __x, const _Iterator& __y)
1682 requires equality_comparable<_Vp_iter>
1683 { return __x._M_current == __y._M_current; }
1685 friend constexpr range_rvalue_reference_t<_Vp>
1686 iter_move(const _Iterator& __i)
1687 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1688 { return ranges::iter_move(__i._M_current); }
1690 friend constexpr void
1691 iter_swap(const _Iterator& __x, const _Iterator& __y)
1692 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1693 requires indirectly_swappable<_Vp_iter>
1694 { ranges::iter_swap(__x._M_current, __y._M_current); }
1700 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1703 __equal(const _Iterator& __i) const
1704 { return __i._M_current == _M_end; }
1707 _Sentinel() = default;
1710 _Sentinel(filter_view* __parent)
1711 : _M_end(ranges::end(__parent->_M_base))
1714 constexpr sentinel_t<_Vp>
1718 friend constexpr bool
1719 operator==(const _Iterator& __x, const _Sentinel& __y)
1720 { return __y.__equal(__x); }
1723 _Vp _M_base = _Vp();
1724 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1725 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1728 filter_view() requires (default_initializable<_Vp>
1729 && default_initializable<_Pred>)
1733 filter_view(_Vp __base, _Pred __pred)
1734 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1738 base() const& requires copy_constructible<_Vp>
1743 { return std::move(_M_base); }
1745 constexpr const _Pred&
1747 { return *_M_pred; }
1752 if (_M_cached_begin._M_has_value())
1753 return {this, _M_cached_begin._M_get(_M_base)};
1755 __glibcxx_assert(_M_pred.has_value());
1756 auto __it = ranges::find_if(ranges::begin(_M_base),
1757 ranges::end(_M_base),
1758 std::ref(*_M_pred));
1759 _M_cached_begin._M_set(_M_base, __it);
1760 return {this, std::move(__it)};
1766 if constexpr (common_range<_Vp>)
1767 return _Iterator{this, ranges::end(_M_base)};
1769 return _Sentinel{this};
1773 template<typename _Range, typename _Pred>
1774 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1780 template<typename _Range, typename _Pred>
1781 concept __can_filter_view
1782 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1783 } // namespace __detail
1785 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1787 template<viewable_range _Range, typename _Pred>
1788 requires __detail::__can_filter_view<_Range, _Pred>
1790 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1792 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1795 using _RangeAdaptor<_Filter>::operator();
1796 static constexpr int _S_arity = 2;
1797 static constexpr bool _S_has_simple_extra_args = true;
1800 inline constexpr _Filter filter;
1801 } // namespace views
1803#if __cpp_lib_ranges >= 202207L // C++ >= 23
1804 template<input_range _Vp, move_constructible _Fp>
1806 template<input_range _Vp, copy_constructible _Fp>
1808 requires view<_Vp> && is_object_v<_Fp>
1809 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1810 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1811 range_reference_t<_Vp>>>
1812 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1815 template<bool _Const>
1816 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1818 template<bool _Const>
1822 template<bool _Const>
1823 requires forward_range<_Base<_Const>>
1824 struct __iter_cat<_Const>
1830 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1831 // 3564. transform_view::iterator<true>::value_type and
1832 // iterator_category should use const F&
1833 using _Base = transform_view::_Base<_Const>;
1834 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1835 range_reference_t<_Base>>;
1836 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1837 // 3798. Rvalue reference and iterator_category
1838 if constexpr (is_reference_v<_Res>)
1841 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1842 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1843 return random_access_iterator_tag{};
1848 return input_iterator_tag{};
1851 using iterator_category = decltype(_S_iter_cat());
1854 template<bool _Const>
1857 template<bool _Const>
1858 struct _Iterator : __iter_cat<_Const>
1861 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1862 using _Base = transform_view::_Base<_Const>;
1867 if constexpr (random_access_range<_Base>)
1868 return random_access_iterator_tag{};
1869 else if constexpr (bidirectional_range<_Base>)
1870 return bidirectional_iterator_tag{};
1871 else if constexpr (forward_range<_Base>)
1872 return forward_iterator_tag{};
1874 return input_iterator_tag{};
1877 using _Base_iter = iterator_t<_Base>;
1879 _Base_iter _M_current = _Base_iter();
1880 _Parent* _M_parent = nullptr;
1883 using iterator_concept = decltype(_S_iter_concept());
1884 // iterator_category defined in __transform_view_iter_cat
1886 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1887 range_reference_t<_Base>>>;
1888 using difference_type = range_difference_t<_Base>;
1890 _Iterator() requires default_initializable<_Base_iter> = default;
1893 _Iterator(_Parent* __parent, _Base_iter __current)
1894 : _M_current(std::move(__current)),
1899 _Iterator(_Iterator<!_Const> __i)
1901 && convertible_to<iterator_t<_Vp>, _Base_iter>
1902 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1905 constexpr const _Base_iter&
1906 base() const & noexcept
1907 { return _M_current; }
1909 constexpr _Base_iter
1911 { return std::move(_M_current); }
1913 constexpr decltype(auto)
1915 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1916 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1918 constexpr _Iterator&
1930 operator++(int) requires forward_range<_Base>
1937 constexpr _Iterator&
1938 operator--() requires bidirectional_range<_Base>
1945 operator--(int) requires bidirectional_range<_Base>
1952 constexpr _Iterator&
1953 operator+=(difference_type __n) requires random_access_range<_Base>
1959 constexpr _Iterator&
1960 operator-=(difference_type __n) requires random_access_range<_Base>
1966 constexpr decltype(auto)
1967 operator[](difference_type __n) const
1968 requires random_access_range<_Base>
1969 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1971 friend constexpr bool
1972 operator==(const _Iterator& __x, const _Iterator& __y)
1973 requires equality_comparable<_Base_iter>
1974 { return __x._M_current == __y._M_current; }
1976 friend constexpr bool
1977 operator<(const _Iterator& __x, const _Iterator& __y)
1978 requires random_access_range<_Base>
1979 { return __x._M_current < __y._M_current; }
1981 friend constexpr bool
1982 operator>(const _Iterator& __x, const _Iterator& __y)
1983 requires random_access_range<_Base>
1984 { return __y < __x; }
1986 friend constexpr bool
1987 operator<=(const _Iterator& __x, const _Iterator& __y)
1988 requires random_access_range<_Base>
1989 { return !(__y < __x); }
1991 friend constexpr bool
1992 operator>=(const _Iterator& __x, const _Iterator& __y)
1993 requires random_access_range<_Base>
1994 { return !(__x < __y); }
1996#ifdef __cpp_lib_three_way_comparison
1997 friend constexpr auto
1998 operator<=>(const _Iterator& __x, const _Iterator& __y)
1999 requires random_access_range<_Base>
2000 && three_way_comparable<_Base_iter>
2001 { return __x._M_current <=> __y._M_current; }
2004 friend constexpr _Iterator
2005 operator+(_Iterator __i, difference_type __n)
2006 requires random_access_range<_Base>
2007 { return {__i._M_parent, __i._M_current + __n}; }
2009 friend constexpr _Iterator
2010 operator+(difference_type __n, _Iterator __i)
2011 requires random_access_range<_Base>
2012 { return {__i._M_parent, __i._M_current + __n}; }
2014 friend constexpr _Iterator
2015 operator-(_Iterator __i, difference_type __n)
2016 requires random_access_range<_Base>
2017 { return {__i._M_parent, __i._M_current - __n}; }
2019 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2020 // 3483. transform_view::iterator's difference is overconstrained
2021 friend constexpr difference_type
2022 operator-(const _Iterator& __x, const _Iterator& __y)
2023 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2024 { return __x._M_current - __y._M_current; }
2026 friend constexpr decltype(auto)
2027 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
2029 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
2030 return std::move(*__i);
2035 friend _Iterator<!_Const>;
2036 template<bool> friend struct _Sentinel;
2039 template<bool _Const>
2043 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2044 using _Base = transform_view::_Base<_Const>;
2046 template<bool _Const2>
2048 __distance_from(const _Iterator<_Const2>& __i) const
2049 { return _M_end - __i._M_current; }
2051 template<bool _Const2>
2053 __equal(const _Iterator<_Const2>& __i) const
2054 { return __i._M_current == _M_end; }
2056 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2059 _Sentinel() = default;
2062 _Sentinel(sentinel_t<_Base> __end)
2067 _Sentinel(_Sentinel<!_Const> __i)
2069 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2070 : _M_end(std::move(__i._M_end))
2073 constexpr sentinel_t<_Base>
2077 template<bool _Const2>
2078 requires sentinel_for<sentinel_t<_Base>,
2079 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2080 friend constexpr bool
2081 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2082 { return __y.__equal(__x); }
2084 template<bool _Const2,
2085 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2086 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2087 friend constexpr range_difference_t<_Base2>
2088 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2089 { return -__y.__distance_from(__x); }
2091 template<bool _Const2,
2092 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2093 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2094 friend constexpr range_difference_t<_Base2>
2095 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2096 { return __y.__distance_from(__x); }
2098 friend _Sentinel<!_Const>;
2101 _Vp _M_base = _Vp();
2102 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2105 transform_view() requires (default_initializable<_Vp>
2106 && default_initializable<_Fp>)
2110 transform_view(_Vp __base, _Fp __fun)
2111 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2115 base() const& requires copy_constructible<_Vp>
2116 { return _M_base ; }
2120 { return std::move(_M_base); }
2122 constexpr _Iterator<false>
2124 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2126 constexpr _Iterator<true>
2128 requires range<const _Vp>
2129 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2130 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2132 constexpr _Sentinel<false>
2134 { return _Sentinel<false>{ranges::end(_M_base)}; }
2136 constexpr _Iterator<false>
2137 end() requires common_range<_Vp>
2138 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2140 constexpr _Sentinel<true>
2142 requires range<const _Vp>
2143 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2144 { return _Sentinel<true>{ranges::end(_M_base)}; }
2146 constexpr _Iterator<true>
2148 requires common_range<const _Vp>
2149 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2150 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2153 size() requires sized_range<_Vp>
2154 { return ranges::size(_M_base); }
2157 size() const requires sized_range<const _Vp>
2158 { return ranges::size(_M_base); }
2161 template<typename _Range, typename _Fp>
2162 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2168 template<typename _Range, typename _Fp>
2169 concept __can_transform_view
2170 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2171 } // namespace __detail
2173 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2175 template<viewable_range _Range, typename _Fp>
2176 requires __detail::__can_transform_view<_Range, _Fp>
2178 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2180 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2183 using _RangeAdaptor<_Transform>::operator();
2184 static constexpr int _S_arity = 2;
2185 static constexpr bool _S_has_simple_extra_args = true;
2188 inline constexpr _Transform transform;
2189 } // namespace views
2192 class take_view : public view_interface<take_view<_Vp>>
2195 template<bool _Const>
2196 using _CI = counted_iterator<
2197 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2199 template<bool _Const>
2203 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2204 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2207 _Sentinel() = default;
2210 _Sentinel(sentinel_t<_Base> __end)
2215 _Sentinel(_Sentinel<!_Const> __s)
2216 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2217 : _M_end(std::move(__s._M_end))
2220 constexpr sentinel_t<_Base>
2224 friend constexpr bool
2225 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2226 { return __y.count() == 0 || __y.base() == __x._M_end; }
2228 template<bool _OtherConst = !_Const,
2229 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2230 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2231 friend constexpr bool
2232 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2233 { return __y.count() == 0 || __y.base() == __x._M_end; }
2235 friend _Sentinel<!_Const>;
2238 _Vp _M_base = _Vp();
2239 range_difference_t<_Vp> _M_count = 0;
2242 take_view() requires default_initializable<_Vp> = default;
2245 take_view(_Vp __base, range_difference_t<_Vp> __count)
2246 : _M_base(std::move(__base)), _M_count(std::move(__count))
2250 base() const& requires copy_constructible<_Vp>
2255 { return std::move(_M_base); }
2258 begin() requires (!__detail::__simple_view<_Vp>)
2260 if constexpr (sized_range<_Vp>)
2262 if constexpr (random_access_range<_Vp>)
2263 return ranges::begin(_M_base);
2267 return counted_iterator(ranges::begin(_M_base), __sz);
2271 return counted_iterator(ranges::begin(_M_base), _M_count);
2275 begin() const requires range<const _Vp>
2277 if constexpr (sized_range<const _Vp>)
2279 if constexpr (random_access_range<const _Vp>)
2280 return ranges::begin(_M_base);
2284 return counted_iterator(ranges::begin(_M_base), __sz);
2288 return counted_iterator(ranges::begin(_M_base), _M_count);
2292 end() requires (!__detail::__simple_view<_Vp>)
2294 if constexpr (sized_range<_Vp>)
2296 if constexpr (random_access_range<_Vp>)
2297 return ranges::begin(_M_base) + size();
2299 return default_sentinel;
2302 return _Sentinel<false>{ranges::end(_M_base)};
2306 end() const requires range<const _Vp>
2308 if constexpr (sized_range<const _Vp>)
2310 if constexpr (random_access_range<const _Vp>)
2311 return ranges::begin(_M_base) + size();
2313 return default_sentinel;
2316 return _Sentinel<true>{ranges::end(_M_base)};
2320 size() requires sized_range<_Vp>
2322 auto __n = ranges::size(_M_base);
2323 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2327 size() const requires sized_range<const _Vp>
2329 auto __n = ranges::size(_M_base);
2330 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2334 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2335 // 3447. Deduction guides for take_view and drop_view have different
2337 template<typename _Range>
2338 take_view(_Range&&, range_difference_t<_Range>)
2339 -> take_view<views::all_t<_Range>>;
2341 template<typename _Tp>
2342 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2343 = enable_borrowed_range<_Tp>;
2349 template<typename _Range>
2350 inline constexpr bool __is_empty_view = false;
2352 template<typename _Tp>
2353 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2355 template<typename _Range>
2356 inline constexpr bool __is_basic_string_view = false;
2358 template<typename _CharT, typename _Traits>
2359 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2362 using ranges::__detail::__is_subrange;
2364 template<typename _Range>
2365 inline constexpr bool __is_iota_view = false;
2367 template<typename _Winc, typename _Bound>
2368 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2370 template<typename _Range>
2371 inline constexpr bool __is_repeat_view = false;
2373 template<typename _Range>
2375 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2377 template<typename _Range, typename _Dp>
2378 concept __can_take_view
2379 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2380 } // namespace __detail
2382 struct _Take : __adaptor::_RangeAdaptor<_Take>
2384 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2385 requires __detail::__can_take_view<_Range, _Dp>
2387 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2389 using _Tp = remove_cvref_t<_Range>;
2390 if constexpr (__detail::__is_empty_view<_Tp>)
2392 else if constexpr (random_access_range<_Tp>
2394 && (std::__detail::__is_span<_Tp>
2395 || __detail::__is_basic_string_view<_Tp>
2396 || __detail::__is_subrange<_Tp>
2397 || __detail::__is_iota_view<_Tp>))
2399 __n = std::min<_Dp>(ranges::distance(__r), __n);
2400 auto __begin = ranges::begin(__r);
2401 auto __end = __begin + __n;
2402 if constexpr (std::__detail::__is_span<_Tp>)
2403 return span<typename _Tp::element_type>(__begin, __end);
2404 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2405 return _Tp(__begin, __end);
2406 else if constexpr (__detail::__is_subrange<_Tp>)
2407 return subrange<iterator_t<_Tp>>(__begin, __end);
2409 return iota_view(*__begin, *__end);
2411 else if constexpr (__detail::__is_repeat_view<_Tp>)
2412 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2414 return take_view(std::forward<_Range>(__r), __n);
2417 using _RangeAdaptor<_Take>::operator();
2418 static constexpr int _S_arity = 2;
2419 // The count argument of views::take is not always simple -- it can be
2420 // e.g. a move-only class that's implicitly convertible to the difference
2421 // type. But an integer-like count argument is surely simple.
2422 template<typename _Tp>
2423 static constexpr bool _S_has_simple_extra_args
2424 = ranges::__detail::__is_integer_like<_Tp>;
2427 inline constexpr _Take take;
2428 } // namespace views
2430 template<view _Vp, typename _Pred>
2431 requires input_range<_Vp> && is_object_v<_Pred>
2432 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2433 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2435 template<bool _Const>
2439 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2441 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2442 const _Pred* _M_pred = nullptr;
2445 _Sentinel() = default;
2448 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2449 : _M_end(__end), _M_pred(__pred)
2453 _Sentinel(_Sentinel<!_Const> __s)
2454 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2455 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2458 constexpr sentinel_t<_Base>
2459 base() const { return _M_end; }
2461 friend constexpr bool
2462 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2463 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2465 template<bool _OtherConst = !_Const,
2466 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2467 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2468 friend constexpr bool
2469 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2470 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2472 friend _Sentinel<!_Const>;
2475 _Vp _M_base = _Vp();
2476 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2479 take_while_view() requires (default_initializable<_Vp>
2480 && default_initializable<_Pred>)
2484 take_while_view(_Vp __base, _Pred __pred)
2485 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2489 base() const& requires copy_constructible<_Vp>
2494 { return std::move(_M_base); }
2496 constexpr const _Pred&
2498 { return *_M_pred; }
2501 begin() requires (!__detail::__simple_view<_Vp>)
2502 { return ranges::begin(_M_base); }
2505 begin() const requires range<const _Vp>
2506 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2507 { return ranges::begin(_M_base); }
2510 end() requires (!__detail::__simple_view<_Vp>)
2511 { return _Sentinel<false>(ranges::end(_M_base),
2512 std::__addressof(*_M_pred)); }
2515 end() const requires range<const _Vp>
2516 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2517 { return _Sentinel<true>(ranges::end(_M_base),
2518 std::__addressof(*_M_pred)); }
2521 template<typename _Range, typename _Pred>
2522 take_while_view(_Range&&, _Pred)
2523 -> take_while_view<views::all_t<_Range>, _Pred>;
2529 template<typename _Range, typename _Pred>
2530 concept __can_take_while_view
2531 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2532 } // namespace __detail
2534 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2536 template<viewable_range _Range, typename _Pred>
2537 requires __detail::__can_take_while_view<_Range, _Pred>
2539 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2541 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2544 using _RangeAdaptor<_TakeWhile>::operator();
2545 static constexpr int _S_arity = 2;
2546 static constexpr bool _S_has_simple_extra_args = true;
2549 inline constexpr _TakeWhile take_while;
2550 } // namespace views
2553 class drop_view : public view_interface<drop_view<_Vp>>
2556 _Vp _M_base = _Vp();
2557 range_difference_t<_Vp> _M_count = 0;
2559 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2560 // both random_access_range and sized_range. Otherwise, cache its result.
2561 static constexpr bool _S_needs_cached_begin
2562 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2563 [[no_unique_address]]
2564 __detail::__maybe_present_t<_S_needs_cached_begin,
2565 __detail::_CachedPosition<_Vp>>
2569 drop_view() requires default_initializable<_Vp> = default;
2572 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2573 : _M_base(std::move(__base)), _M_count(__count)
2574 { __glibcxx_assert(__count >= 0); }
2577 base() const& requires copy_constructible<_Vp>
2582 { return std::move(_M_base); }
2584 // This overload is disabled for simple views with constant-time begin().
2587 requires (!(__detail::__simple_view<_Vp>
2588 && random_access_range<const _Vp>
2589 && sized_range<const _Vp>))
2591 if constexpr (_S_needs_cached_begin)
2592 if (_M_cached_begin._M_has_value())
2593 return _M_cached_begin._M_get(_M_base);
2595 auto __it = ranges::next(ranges::begin(_M_base),
2596 _M_count, ranges::end(_M_base));
2597 if constexpr (_S_needs_cached_begin)
2598 _M_cached_begin._M_set(_M_base, __it);
2602 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2603 // 3482. drop_view's const begin should additionally require sized_range
2606 requires random_access_range<const _Vp> && sized_range<const _Vp>
2608 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2613 end() requires (!__detail::__simple_view<_Vp>)
2614 { return ranges::end(_M_base); }
2617 end() const requires range<const _Vp>
2618 { return ranges::end(_M_base); }
2621 size() requires sized_range<_Vp>
2623 const auto __s = ranges::size(_M_base);
2624 const auto __c = static_cast<decltype(__s)>(_M_count);
2625 return __s < __c ? 0 : __s - __c;
2629 size() const requires sized_range<const _Vp>
2631 const auto __s = ranges::size(_M_base);
2632 const auto __c = static_cast<decltype(__s)>(_M_count);
2633 return __s < __c ? 0 : __s - __c;
2637 template<typename _Range>
2638 drop_view(_Range&&, range_difference_t<_Range>)
2639 -> drop_view<views::all_t<_Range>>;
2641 template<typename _Tp>
2642 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2643 = enable_borrowed_range<_Tp>;
2649 template<typename _Range>
2651 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2653 template<typename _Range, typename _Dp>
2654 concept __can_drop_view
2655 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2656 } // namespace __detail
2658 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2660 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2661 requires __detail::__can_drop_view<_Range, _Dp>
2663 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2665 using _Tp = remove_cvref_t<_Range>;
2666 if constexpr (__detail::__is_empty_view<_Tp>)
2668 else if constexpr (random_access_range<_Tp>
2670 && (std::__detail::__is_span<_Tp>
2671 || __detail::__is_basic_string_view<_Tp>
2672 || __detail::__is_iota_view<_Tp>
2673 || __detail::__is_subrange<_Tp>))
2675 __n = std::min<_Dp>(ranges::distance(__r), __n);
2676 auto __begin = ranges::begin(__r) + __n;
2677 auto __end = ranges::end(__r);
2678 if constexpr (std::__detail::__is_span<_Tp>)
2679 return span<typename _Tp::element_type>(__begin, __end);
2680 else if constexpr (__detail::__is_subrange<_Tp>)
2682 if constexpr (_Tp::_S_store_size)
2684 using ranges::__detail::__to_unsigned_like;
2685 auto __m = ranges::distance(__r) - __n;
2686 return _Tp(__begin, __end, __to_unsigned_like(__m));
2689 return _Tp(__begin, __end);
2692 return _Tp(__begin, __end);
2694 else if constexpr (__detail::__is_repeat_view<_Tp>)
2695 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2697 return drop_view(std::forward<_Range>(__r), __n);
2700 using _RangeAdaptor<_Drop>::operator();
2701 static constexpr int _S_arity = 2;
2702 template<typename _Tp>
2703 static constexpr bool _S_has_simple_extra_args
2704 = _Take::_S_has_simple_extra_args<_Tp>;
2707 inline constexpr _Drop drop;
2708 } // namespace views
2710 template<view _Vp, typename _Pred>
2711 requires input_range<_Vp> && is_object_v<_Pred>
2712 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2713 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2716 _Vp _M_base = _Vp();
2717 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2718 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2721 drop_while_view() requires (default_initializable<_Vp>
2722 && default_initializable<_Pred>)
2726 drop_while_view(_Vp __base, _Pred __pred)
2727 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2731 base() const& requires copy_constructible<_Vp>
2736 { return std::move(_M_base); }
2738 constexpr const _Pred&
2740 { return *_M_pred; }
2745 if (_M_cached_begin._M_has_value())
2746 return _M_cached_begin._M_get(_M_base);
2748 __glibcxx_assert(_M_pred.has_value());
2749 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2750 ranges::end(_M_base),
2751 std::cref(*_M_pred));
2752 _M_cached_begin._M_set(_M_base, __it);
2758 { return ranges::end(_M_base); }
2761 template<typename _Range, typename _Pred>
2762 drop_while_view(_Range&&, _Pred)
2763 -> drop_while_view<views::all_t<_Range>, _Pred>;
2765 template<typename _Tp, typename _Pred>
2766 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2767 = enable_borrowed_range<_Tp>;
2773 template<typename _Range, typename _Pred>
2774 concept __can_drop_while_view
2775 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2776 } // namespace __detail
2778 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2780 template<viewable_range _Range, typename _Pred>
2781 requires __detail::__can_drop_while_view<_Range, _Pred>
2783 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2785 return drop_while_view(std::forward<_Range>(__r),
2786 std::forward<_Pred>(__p));
2789 using _RangeAdaptor<_DropWhile>::operator();
2790 static constexpr int _S_arity = 2;
2791 static constexpr bool _S_has_simple_extra_args = true;
2794 inline constexpr _DropWhile drop_while;
2795 } // namespace views
2799 template<typename _Tp>
2801 __as_lvalue(_Tp&& __t)
2802 { return static_cast<_Tp&>(__t); }
2803 } // namespace __detail
2805 template<input_range _Vp>
2806 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2807 class join_view : public view_interface<join_view<_Vp>>
2810 using _InnerRange = range_reference_t<_Vp>;
2812 template<bool _Const>
2813 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2815 template<bool _Const>
2816 using _Outer_iter = iterator_t<_Base<_Const>>;
2818 template<bool _Const>
2819 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2821 template<bool _Const>
2822 static constexpr bool _S_ref_is_glvalue
2823 = is_reference_v<range_reference_t<_Base<_Const>>>;
2825 template<bool _Const>
2829 template<bool _Const>
2830 requires _S_ref_is_glvalue<_Const>
2831 && forward_range<_Base<_Const>>
2832 && forward_range<range_reference_t<_Base<_Const>>>
2833 struct __iter_cat<_Const>
2836 static constexpr auto
2839 using _Outer_iter = join_view::_Outer_iter<_Const>;
2840 using _Inner_iter = join_view::_Inner_iter<_Const>;
2841 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2842 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2843 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2844 && derived_from<_InnerCat, bidirectional_iterator_tag>
2845 && common_range<range_reference_t<_Base<_Const>>>)
2846 return bidirectional_iterator_tag{};
2847 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2848 && derived_from<_InnerCat, forward_iterator_tag>)
2849 return forward_iterator_tag{};
2851 return input_iterator_tag{};
2854 using iterator_category = decltype(_S_iter_cat());
2857 template<bool _Const>
2860 template<bool _Const>
2861 struct _Iterator : __iter_cat<_Const>
2864 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2865 using _Base = join_view::_Base<_Const>;
2869 static constexpr bool _S_ref_is_glvalue
2870 = join_view::_S_ref_is_glvalue<_Const>;
2875 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2876 if constexpr (_S_ref_is_glvalue)
2879 return _M_parent->_M_inner._M_emplace_deref(__x);
2882 _Outer_iter& __outer = _M_get_outer();
2883 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2885 auto&& __inner = __update_inner(__outer);
2886 _M_inner = ranges::begin(__inner);
2887 if (_M_inner != ranges::end(__inner))
2891 if constexpr (_S_ref_is_glvalue)
2893 if constexpr (forward_iterator<_Inner_iter>)
2894 _M_inner = _Inner_iter();
2900 static constexpr auto
2903 if constexpr (_S_ref_is_glvalue
2904 && bidirectional_range<_Base>
2905 && bidirectional_range<range_reference_t<_Base>>
2906 && common_range<range_reference_t<_Base>>)
2907 return bidirectional_iterator_tag{};
2908 else if constexpr (_S_ref_is_glvalue
2909 && forward_range<_Base>
2910 && forward_range<range_reference_t<_Base>>)
2911 return forward_iterator_tag{};
2913 return input_iterator_tag{};
2916 using _Outer_iter = join_view::_Outer_iter<_Const>;
2917 using _Inner_iter = join_view::_Inner_iter<_Const>;
2919 constexpr _Outer_iter&
2922 if constexpr (forward_range<_Base>)
2925 return *_M_parent->_M_outer;
2928 constexpr const _Outer_iter&
2929 _M_get_outer() const
2931 if constexpr (forward_range<_Base>)
2934 return *_M_parent->_M_outer;
2937 constexpr _Inner_iter&
2938 _M_get_inner() noexcept
2940 if constexpr (forward_iterator<_Inner_iter>)
2946 constexpr const _Inner_iter&
2947 _M_get_inner() const noexcept
2949 if constexpr (forward_iterator<_Inner_iter>)
2956 _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base>
2957 : _M_outer(std::move(__outer)), _M_parent(__parent)
2961 _Iterator(_Parent* __parent) requires (!forward_range<_Base>)
2962 : _M_parent(__parent)
2965 [[no_unique_address]]
2966 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer
2967 = decltype(_M_outer)();
2968 __conditional_t<forward_iterator<_Inner_iter>,
2969 _Inner_iter, optional<_Inner_iter>> _M_inner
2970 = decltype(_M_inner)();
2971 _Parent* _M_parent = nullptr;
2974 using iterator_concept = decltype(_S_iter_concept());
2975 // iterator_category defined in __join_view_iter_cat
2976 using value_type = range_value_t<range_reference_t<_Base>>;
2977 using difference_type
2978 = common_type_t<range_difference_t<_Base>,
2979 range_difference_t<range_reference_t<_Base>>>;
2981 _Iterator() = default;
2984 _Iterator(_Iterator<!_Const> __i)
2986 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2987 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2988 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
2989 _M_parent(__i._M_parent)
2992 constexpr decltype(auto)
2994 { return *_M_get_inner(); }
2996 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2997 // 3500. join_view::iterator::operator->() is bogus
2998 constexpr _Inner_iter
3000 requires __detail::__has_arrow<_Inner_iter>
3001 && copyable<_Inner_iter>
3002 { return _M_get_inner(); }
3004 constexpr _Iterator&
3007 auto&& __inner_range = [this] () -> auto&& {
3008 if constexpr (_S_ref_is_glvalue)
3009 return *_M_get_outer();
3011 return *_M_parent->_M_inner;
3013 if (++_M_get_inner() == ranges::end(__inner_range))
3027 requires _S_ref_is_glvalue && forward_range<_Base>
3028 && forward_range<range_reference_t<_Base>>
3035 constexpr _Iterator&
3037 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3038 && bidirectional_range<range_reference_t<_Base>>
3039 && common_range<range_reference_t<_Base>>
3041 if (_M_outer == ranges::end(_M_parent->_M_base))
3042 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3043 while (_M_get_inner() == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3044 _M_get_inner() = ranges::end(__detail::__as_lvalue(*--_M_outer));
3051 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3052 && bidirectional_range<range_reference_t<_Base>>
3053 && common_range<range_reference_t<_Base>>
3060 friend constexpr bool
3061 operator==(const _Iterator& __x, const _Iterator& __y)
3062 requires _S_ref_is_glvalue
3063 && forward_range<_Base>
3064 && equality_comparable<_Inner_iter>
3066 return (__x._M_outer == __y._M_outer
3067 && __x._M_inner == __y._M_inner);
3070 friend constexpr decltype(auto)
3071 iter_move(const _Iterator& __i)
3072 noexcept(noexcept(ranges::iter_move(__i._M_get_inner())))
3073 { return ranges::iter_move(__i._M_get_inner()); }
3075 friend constexpr void
3076 iter_swap(const _Iterator& __x, const _Iterator& __y)
3077 noexcept(noexcept(ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner())))
3078 requires indirectly_swappable<_Inner_iter>
3079 { return ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner()); }
3081 friend _Iterator<!_Const>;
3082 template<bool> friend struct _Sentinel;
3085 template<bool _Const>
3089 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3090 using _Base = join_view::_Base<_Const>;
3092 template<bool _Const2>
3094 __equal(const _Iterator<_Const2>& __i) const
3095 { return __i._M_get_outer() == _M_end; }
3097 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3100 _Sentinel() = default;
3103 _Sentinel(_Parent* __parent)
3104 : _M_end(ranges::end(__parent->_M_base))
3108 _Sentinel(_Sentinel<!_Const> __s)
3109 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3110 : _M_end(std::move(__s._M_end))
3113 template<bool _Const2>
3114 requires sentinel_for<sentinel_t<_Base>,
3115 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3116 friend constexpr bool
3117 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3118 { return __y.__equal(__x); }
3120 friend _Sentinel<!_Const>;
3123 _Vp _M_base = _Vp();
3124 [[no_unique_address]]
3125 __detail::__maybe_present_t<!forward_range<_Vp>,
3126 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3127 [[no_unique_address]]
3128 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3131 join_view() requires default_initializable<_Vp> = default;
3134 join_view(_Vp __base)
3135 : _M_base(std::move(__base))
3139 base() const& requires copy_constructible<_Vp>
3144 { return std::move(_M_base); }
3149 if constexpr (forward_range<_Vp>)
3151 constexpr bool __use_const
3152 = (__detail::__simple_view<_Vp>
3153 && is_reference_v<range_reference_t<_Vp>>);
3154 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3158 _M_outer = ranges::begin(_M_base);
3159 return _Iterator<false>{this};
3165 requires forward_range<const _Vp>
3166 && is_reference_v<range_reference_t<const _Vp>>
3167 && input_range<range_reference_t<const _Vp>>
3169 return _Iterator<true>{this, ranges::begin(_M_base)};
3175 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3176 && forward_range<_InnerRange>
3177 && common_range<_Vp> && common_range<_InnerRange>)
3178 return _Iterator<__detail::__simple_view<_Vp>>{this,
3179 ranges::end(_M_base)};
3181 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3186 requires forward_range<const _Vp>
3187 && is_reference_v<range_reference_t<const _Vp>>
3188 && input_range<range_reference_t<const _Vp>>
3190 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3191 && forward_range<range_reference_t<const _Vp>>
3192 && common_range<const _Vp>
3193 && common_range<range_reference_t<const _Vp>>)
3194 return _Iterator<true>{this, ranges::end(_M_base)};
3196 return _Sentinel<true>{this};
3200 template<typename _Range>
3201 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3207 template<typename _Range>
3208 concept __can_join_view
3209 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3210 } // namespace __detail
3212 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3214 template<viewable_range _Range>
3215 requires __detail::__can_join_view<_Range>
3217 operator() [[nodiscard]] (_Range&& __r) const
3219 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3220 // 3474. Nesting join_views is broken because of CTAD
3221 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3224 static constexpr bool _S_has_simple_call_op = true;
3227 inline constexpr _Join join;
3228 } // namespace views
3233 struct __require_constant;
3235 template<typename _Range>
3236 concept __tiny_range = sized_range<_Range>
3238 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3239 && (remove_reference_t<_Range>::size() <= 1);
3241 template<typename _Base>
3242 struct __lazy_split_view_outer_iter_cat
3245 template<forward_range _Base>
3246 struct __lazy_split_view_outer_iter_cat<_Base>
3247 { using iterator_category = input_iterator_tag; };
3249 template<typename _Base>
3250 struct __lazy_split_view_inner_iter_cat
3253 template<forward_range _Base>
3254 struct __lazy_split_view_inner_iter_cat<_Base>
3257 static constexpr auto
3260 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3261 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3262 return forward_iterator_tag{};
3267 using iterator_category = decltype(_S_iter_cat());
3271 template<input_range _Vp, forward_range _Pattern>
3272 requires view<_Vp> && view<_Pattern>
3273 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3275 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3276 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3279 template<bool _Const>
3280 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3282 template<bool _Const>
3285 template<bool _Const>
3287 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3290 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3291 using _Base = lazy_split_view::_Base<_Const>;
3295 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3297 // [range.lazy.split.outer] p1
3298 // Many of the following specifications refer to the notional member
3299 // current of outer-iterator. current is equivalent to current_ if
3300 // V models forward_range, and parent_->current_ otherwise.
3302 __current() noexcept
3304 if constexpr (forward_range<_Vp>)
3307 return *_M_parent->_M_current;
3311 __current() const noexcept
3313 if constexpr (forward_range<_Vp>)
3316 return *_M_parent->_M_current;
3319 _Parent* _M_parent = nullptr;
3321 [[no_unique_address]]
3322 __detail::__maybe_present_t<forward_range<_Vp>,
3323 iterator_t<_Base>> _M_current
3324 = decltype(_M_current)();
3325 bool _M_trailing_empty = false;
3328 using iterator_concept = __conditional_t<forward_range<_Base>,
3329 forward_iterator_tag,
3330 input_iterator_tag>;
3331 // iterator_category defined in __lazy_split_view_outer_iter_cat
3332 using difference_type = range_difference_t<_Base>;
3334 struct value_type : view_interface<value_type>
3337 _OuterIter _M_i = _OuterIter();
3339 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3340 // 4013. lazy_split_view::outer-iterator::value_type should not
3341 // provide default constructor
3343 value_type(_OuterIter __i)
3344 : _M_i(std::move(__i))
3350 constexpr _InnerIter<_Const>
3352 { return _InnerIter<_Const>{_M_i}; }
3354 constexpr default_sentinel_t
3355 end() const noexcept
3356 { return default_sentinel; }
3359 _OuterIter() = default;
3362 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3363 : _M_parent(__parent)
3367 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3368 requires forward_range<_Base>
3369 : _M_parent(__parent),
3370 _M_current(std::move(__current))
3374 _OuterIter(_OuterIter<!_Const> __i)
3376 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3377 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3378 _M_trailing_empty(__i._M_trailing_empty)
3381 constexpr value_type
3383 { return value_type{*this}; }
3385 constexpr _OuterIter&
3388 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3389 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3390 const auto __end = ranges::end(_M_parent->_M_base);
3391 if (__current() == __end)
3393 _M_trailing_empty = false;
3396 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3397 if (__pbegin == __pend)
3399 else if constexpr (__detail::__tiny_range<_Pattern>)
3401 __current() = ranges::find(std::move(__current()), __end,
3403 if (__current() != __end)
3406 if (__current() == __end)
3407 _M_trailing_empty = true;
3414 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3418 if (__current() == __end)
3419 _M_trailing_empty = true;
3422 } while (++__current() != __end);
3426 constexpr decltype(auto)
3429 if constexpr (forward_range<_Base>)
3439 friend constexpr bool
3440 operator==(const _OuterIter& __x, const _OuterIter& __y)
3441 requires forward_range<_Base>
3443 return __x._M_current == __y._M_current
3444 && __x._M_trailing_empty == __y._M_trailing_empty;
3447 friend constexpr bool
3448 operator==(const _OuterIter& __x, default_sentinel_t)
3449 { return __x.__at_end(); };
3451 friend _OuterIter<!_Const>;
3452 friend _InnerIter<_Const>;
3455 template<bool _Const>
3457 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3460 using _Base = lazy_split_view::_Base<_Const>;
3465 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3466 auto __end = ranges::end(_M_i._M_parent->_M_base);
3467 if constexpr (__detail::__tiny_range<_Pattern>)
3469 const auto& __cur = _M_i_current();
3472 if (__pcur == __pend)
3473 return _M_incremented;
3474 return *__cur == *__pcur;
3478 auto __cur = _M_i_current();
3481 if (__pcur == __pend)
3482 return _M_incremented;
3485 if (*__cur != *__pcur)
3487 if (++__pcur == __pend)
3489 } while (++__cur != __end);
3495 _M_i_current() noexcept
3496 { return _M_i.__current(); }
3499 _M_i_current() const noexcept
3500 { return _M_i.__current(); }
3502 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3503 bool _M_incremented = false;
3506 using iterator_concept
3507 = typename _OuterIter<_Const>::iterator_concept;
3508 // iterator_category defined in __lazy_split_view_inner_iter_cat
3509 using value_type = range_value_t<_Base>;
3510 using difference_type = range_difference_t<_Base>;
3512 _InnerIter() = default;
3515 _InnerIter(_OuterIter<_Const> __i)
3516 : _M_i(std::move(__i))
3519 constexpr const iterator_t<_Base>&
3520 base() const& noexcept
3521 { return _M_i_current(); }
3523 constexpr iterator_t<_Base>
3524 base() && requires forward_range<_Vp>
3525 { return std::move(_M_i_current()); }
3527 constexpr decltype(auto)
3529 { return *_M_i_current(); }
3531 constexpr _InnerIter&
3534 _M_incremented = true;
3535 if constexpr (!forward_range<_Base>)
3536 if constexpr (_Pattern::size() == 0)
3542 constexpr decltype(auto)
3545 if constexpr (forward_range<_Base>)
3555 friend constexpr bool
3556 operator==(const _InnerIter& __x, const _InnerIter& __y)
3557 requires forward_range<_Base>
3558 { return __x._M_i == __y._M_i; }
3560 friend constexpr bool
3561 operator==(const _InnerIter& __x, default_sentinel_t)
3562 { return __x.__at_end(); }
3564 friend constexpr decltype(auto)
3565 iter_move(const _InnerIter& __i)
3566 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3567 { return ranges::iter_move(__i._M_i_current()); }
3569 friend constexpr void
3570 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3571 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3572 __y._M_i_current())))
3573 requires indirectly_swappable<iterator_t<_Base>>
3574 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3577 _Vp _M_base = _Vp();
3578 _Pattern _M_pattern = _Pattern();
3579 [[no_unique_address]]
3580 __detail::__maybe_present_t<!forward_range<_Vp>,
3581 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3585 lazy_split_view() requires (default_initializable<_Vp>
3586 && default_initializable<_Pattern>)
3590 lazy_split_view(_Vp __base, _Pattern __pattern)
3591 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3594 template<input_range _Range>
3595 requires constructible_from<_Vp, views::all_t<_Range>>
3596 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3598 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3599 : _M_base(views::all(std::forward<_Range>(__r))),
3600 _M_pattern(views::single(std::move(__e)))
3604 base() const& requires copy_constructible<_Vp>
3609 { return std::move(_M_base); }
3614 if constexpr (forward_range<_Vp>)
3616 constexpr bool __simple
3617 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3618 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3622 _M_current = ranges::begin(_M_base);
3623 return _OuterIter<false>{this};
3628 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3630 return _OuterIter<true>{this, ranges::begin(_M_base)};
3634 end() requires forward_range<_Vp> && common_range<_Vp>
3636 constexpr bool __simple
3637 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3638 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3644 if constexpr (forward_range<_Vp>
3645 && forward_range<const _Vp>
3646 && common_range<const _Vp>)
3647 return _OuterIter<true>{this, ranges::end(_M_base)};
3649 return default_sentinel;
3653 template<typename _Range, typename _Pattern>
3654 lazy_split_view(_Range&&, _Pattern&&)
3655 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3657 template<input_range _Range>
3658 lazy_split_view(_Range&&, range_value_t<_Range>)
3659 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3665 template<typename _Range, typename _Pattern>
3666 concept __can_lazy_split_view
3667 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3668 } // namespace __detail
3670 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3672 template<viewable_range _Range, typename _Pattern>
3673 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3675 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3677 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3680 using _RangeAdaptor<_LazySplit>::operator();
3681 static constexpr int _S_arity = 2;
3682 // The pattern argument of views::lazy_split is not always simple -- it can be
3683 // a non-view range, the value category of which affects whether the call
3684 // is well-formed. But a scalar or a view pattern argument is surely
3686 template<typename _Pattern>
3687 static constexpr bool _S_has_simple_extra_args
3688 = is_scalar_v<_Pattern> || (view<_Pattern>
3689 && copy_constructible<_Pattern>);
3692 inline constexpr _LazySplit lazy_split;
3693 } // namespace views
3695 template<forward_range _Vp, forward_range _Pattern>
3696 requires view<_Vp> && view<_Pattern>
3697 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3699 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3702 _Vp _M_base = _Vp();
3703 _Pattern _M_pattern = _Pattern();
3704 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3710 split_view() requires (default_initializable<_Vp>
3711 && default_initializable<_Pattern>)
3715 split_view(_Vp __base, _Pattern __pattern)
3716 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3719 template<forward_range _Range>
3720 requires constructible_from<_Vp, views::all_t<_Range>>
3721 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3723 split_view(_Range&& __r, range_value_t<_Range> __e)
3724 : _M_base(views::all(std::forward<_Range>(__r))),
3725 _M_pattern(views::single(std::move(__e)))
3729 base() const& requires copy_constructible<_Vp>
3734 { return std::move(_M_base); }
3739 if (!_M_cached_begin)
3740 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3741 return {this, ranges::begin(_M_base), *_M_cached_begin};
3747 if constexpr (common_range<_Vp>)
3748 return _Iterator{this, ranges::end(_M_base), {}};
3750 return _Sentinel{this};
3753 constexpr subrange<iterator_t<_Vp>>
3754 _M_find_next(iterator_t<_Vp> __it)
3756 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3757 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3769 split_view* _M_parent = nullptr;
3770 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3771 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3772 bool _M_trailing_empty = false;
3774 friend struct _Sentinel;
3777 using iterator_concept = forward_iterator_tag;
3778 using iterator_category = input_iterator_tag;
3779 using value_type = subrange<iterator_t<_Vp>>;
3780 using difference_type = range_difference_t<_Vp>;
3782 _Iterator() = default;
3785 _Iterator(split_view* __parent,
3786 iterator_t<_Vp> __current,
3787 subrange<iterator_t<_Vp>> __next)
3788 : _M_parent(__parent),
3789 _M_cur(std::move(__current)),
3790 _M_next(std::move(__next))
3793 constexpr iterator_t<_Vp>
3797 constexpr value_type
3799 { return {_M_cur, _M_next.begin()}; }
3801 constexpr _Iterator&
3804 _M_cur = _M_next.begin();
3805 if (_M_cur != ranges::end(_M_parent->_M_base))
3807 _M_cur = _M_next.end();
3808 if (_M_cur == ranges::end(_M_parent->_M_base))
3810 _M_trailing_empty = true;
3811 _M_next = {_M_cur, _M_cur};
3814 _M_next = _M_parent->_M_find_next(_M_cur);
3817 _M_trailing_empty = false;
3829 friend constexpr bool
3830 operator==(const _Iterator& __x, const _Iterator& __y)
3832 return __x._M_cur == __y._M_cur
3833 && __x._M_trailing_empty == __y._M_trailing_empty;
3840 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3843 _M_equal(const _Iterator& __x) const
3844 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3847 _Sentinel() = default;
3850 _Sentinel(split_view* __parent)
3851 : _M_end(ranges::end(__parent->_M_base))
3854 friend constexpr bool
3855 operator==(const _Iterator& __x, const _Sentinel& __y)
3856 { return __y._M_equal(__x); }
3860 template<typename _Range, typename _Pattern>
3861 split_view(_Range&&, _Pattern&&)
3862 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3864 template<forward_range _Range>
3865 split_view(_Range&&, range_value_t<_Range>)
3866 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3872 template<typename _Range, typename _Pattern>
3873 concept __can_split_view
3874 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3875 } // namespace __detail
3877 struct _Split : __adaptor::_RangeAdaptor<_Split>
3879 template<viewable_range _Range, typename _Pattern>
3880 requires __detail::__can_split_view<_Range, _Pattern>
3882 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3884 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3887 using _RangeAdaptor<_Split>::operator();
3888 static constexpr int _S_arity = 2;
3889 template<typename _Pattern>
3890 static constexpr bool _S_has_simple_extra_args
3891 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3894 inline constexpr _Split split;
3895 } // namespace views
3901 template<input_or_output_iterator _Iter>
3903 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3905 if constexpr (contiguous_iterator<_Iter>)
3906 return span(std::to_address(__i), __n);
3907 else if constexpr (random_access_iterator<_Iter>)
3908 return subrange(__i, __i + __n);
3910 return subrange(counted_iterator(std::move(__i), __n),
3915 inline constexpr _Counted counted{};
3916 } // namespace views
3919 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3920 class common_view : public view_interface<common_view<_Vp>>
3923 _Vp _M_base = _Vp();
3926 common_view() requires default_initializable<_Vp> = default;
3929 common_view(_Vp __r)
3930 : _M_base(std::move(__r))
3934 base() const& requires copy_constructible<_Vp>
3939 { return std::move(_M_base); }
3941 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3942 // 4012. common_view::begin/end are missing the simple-view check
3944 begin() requires (!__detail::__simple_view<_Vp>)
3946 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3947 return ranges::begin(_M_base);
3949 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3950 (ranges::begin(_M_base));
3954 begin() const requires range<const _Vp>
3956 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3957 return ranges::begin(_M_base);
3959 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3960 (ranges::begin(_M_base));
3964 end() requires (!__detail::__simple_view<_Vp>)
3966 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3967 return ranges::begin(_M_base) + ranges::size(_M_base);
3969 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3970 (ranges::end(_M_base));
3974 end() const requires range<const _Vp>
3976 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3977 return ranges::begin(_M_base) + ranges::size(_M_base);
3979 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3980 (ranges::end(_M_base));
3984 size() requires sized_range<_Vp>
3985 { return ranges::size(_M_base); }
3988 size() const requires sized_range<const _Vp>
3989 { return ranges::size(_M_base); }
3992 template<typename _Range>
3993 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3995 template<typename _Tp>
3996 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3997 = enable_borrowed_range<_Tp>;
4003 template<typename _Range>
4004 concept __already_common = common_range<_Range>
4005 && requires { views::all(std::declval<_Range>()); };
4007 template<typename _Range>
4008 concept __can_common_view
4009 = requires { common_view{std::declval<_Range>()}; };
4010 } // namespace __detail
4012 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4014 template<viewable_range _Range>
4015 requires __detail::__already_common<_Range>
4016 || __detail::__can_common_view<_Range>
4018 operator() [[nodiscard]] (_Range&& __r) const
4020 if constexpr (__detail::__already_common<_Range>)
4021 return views::all(std::forward<_Range>(__r));
4023 return common_view{std::forward<_Range>(__r)};
4026 static constexpr bool _S_has_simple_call_op = true;
4029 inline constexpr _Common common;
4030 } // namespace views
4033 requires bidirectional_range<_Vp>
4034 class reverse_view : public view_interface<reverse_view<_Vp>>
4037 static constexpr bool _S_needs_cached_begin
4038 = !common_range<_Vp> && !(random_access_range<_Vp>
4039 && sized_sentinel_for<sentinel_t<_Vp>,
4042 _Vp _M_base = _Vp();
4043 [[no_unique_address]]
4044 __detail::__maybe_present_t<_S_needs_cached_begin,
4045 __detail::_CachedPosition<_Vp>>
4049 reverse_view() requires default_initializable<_Vp> = default;
4052 reverse_view(_Vp __r)
4053 : _M_base(std::move(__r))
4057 base() const& requires copy_constructible<_Vp>
4062 { return std::move(_M_base); }
4064 constexpr reverse_iterator<iterator_t<_Vp>>
4067 if constexpr (_S_needs_cached_begin)
4068 if (_M_cached_begin._M_has_value())
4069 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
4071 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4072 if constexpr (_S_needs_cached_begin)
4073 _M_cached_begin._M_set(_M_base, __it);
4074 return std::make_reverse_iterator(std::move(__it));
4078 begin() requires common_range<_Vp>
4079 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4082 begin() const requires common_range<const _Vp>
4083 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4085 constexpr reverse_iterator<iterator_t<_Vp>>
4087 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4090 end() const requires common_range<const _Vp>
4091 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4094 size() requires sized_range<_Vp>
4095 { return ranges::size(_M_base); }
4098 size() const requires sized_range<const _Vp>
4099 { return ranges::size(_M_base); }
4102 template<typename _Range>
4103 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4105 template<typename _Tp>
4106 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4107 = enable_borrowed_range<_Tp>;
4114 inline constexpr bool __is_reversible_subrange = false;
4116 template<typename _Iter, subrange_kind _Kind>
4117 inline constexpr bool
4118 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4119 reverse_iterator<_Iter>,
4123 inline constexpr bool __is_reverse_view = false;
4125 template<typename _Vp>
4126 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
4128 template<typename _Range>
4129 concept __can_reverse_view
4130 = requires { reverse_view{std::declval<_Range>()}; };
4131 } // namespace __detail
4133 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4135 template<viewable_range _Range>
4136 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4137 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4138 || __detail::__can_reverse_view<_Range>
4140 operator() [[nodiscard]] (_Range&& __r) const
4142 using _Tp = remove_cvref_t<_Range>;
4143 if constexpr (__detail::__is_reverse_view<_Tp>)
4144 return std::forward<_Range>(__r).base();
4145 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4147 using _Iter = decltype(ranges::begin(__r).base());
4148 if constexpr (sized_range<_Tp>)
4149 return subrange<_Iter, _Iter, subrange_kind::sized>
4150 {__r.end().base(), __r.begin().base(), __r.size()};
4152 return subrange<_Iter, _Iter, subrange_kind::unsized>
4153 {__r.end().base(), __r.begin().base()};
4156 return reverse_view{std::forward<_Range>(__r)};
4159 static constexpr bool _S_has_simple_call_op = true;
4162 inline constexpr _Reverse reverse;
4163 } // namespace views
4167#if __cpp_lib_tuple_like // >= C++23
4168 template<typename _Tp, size_t _Nm>
4169 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4171 template<typename _Tp, size_t _Nm>
4172 concept __has_tuple_element = requires(_Tp __t)
4174 typename tuple_size<_Tp>::type;
4175 requires _Nm < tuple_size_v<_Tp>;
4176 typename tuple_element_t<_Nm, _Tp>;
4177 { std::get<_Nm>(__t) }
4178 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4182 template<typename _Tp, size_t _Nm>
4183 concept __returnable_element
4184 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4187 template<input_range _Vp, size_t _Nm>
4189 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4190 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4192 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4193 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4196 elements_view() requires default_initializable<_Vp> = default;
4199 elements_view(_Vp __base)
4200 : _M_base(std::move(__base))
4204 base() const& requires copy_constructible<_Vp>
4209 { return std::move(_M_base); }
4212 begin() requires (!__detail::__simple_view<_Vp>)
4213 { return _Iterator<false>(ranges::begin(_M_base)); }
4216 begin() const requires range<const _Vp>
4217 { return _Iterator<true>(ranges::begin(_M_base)); }
4220 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4221 { return _Sentinel<false>{ranges::end(_M_base)}; }
4224 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4225 { return _Iterator<false>{ranges::end(_M_base)}; }
4228 end() const requires range<const _Vp>
4229 { return _Sentinel<true>{ranges::end(_M_base)}; }
4232 end() const requires common_range<const _Vp>
4233 { return _Iterator<true>{ranges::end(_M_base)}; }
4236 size() requires sized_range<_Vp>
4237 { return ranges::size(_M_base); }
4240 size() const requires sized_range<const _Vp>
4241 { return ranges::size(_M_base); }
4244 template<bool _Const>
4245 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4247 template<bool _Const>
4251 template<bool _Const>
4252 requires forward_range<_Base<_Const>>
4253 struct __iter_cat<_Const>
4256 static auto _S_iter_cat()
4258 using _Base = elements_view::_Base<_Const>;
4259 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4260 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4261 if constexpr (!is_lvalue_reference_v<_Res>)
4262 return input_iterator_tag{};
4263 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4264 return random_access_iterator_tag{};
4269 using iterator_category = decltype(_S_iter_cat());
4272 template<bool _Const>
4275 template<bool _Const>
4276 struct _Iterator : __iter_cat<_Const>
4279 using _Base = elements_view::_Base<_Const>;
4281 iterator_t<_Base> _M_current = iterator_t<_Base>();
4283 static constexpr decltype(auto)
4284 _S_get_element(const iterator_t<_Base>& __i)
4286 if constexpr (is_reference_v<range_reference_t<_Base>>)
4287 return std::get<_Nm>(*__i);
4290 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4291 return static_cast<_Et>(std::get<_Nm>(*__i));
4298 if constexpr (random_access_range<_Base>)
4299 return random_access_iterator_tag{};
4300 else if constexpr (bidirectional_range<_Base>)
4301 return bidirectional_iterator_tag{};
4302 else if constexpr (forward_range<_Base>)
4303 return forward_iterator_tag{};
4305 return input_iterator_tag{};
4308 friend _Iterator<!_Const>;
4311 using iterator_concept = decltype(_S_iter_concept());
4312 // iterator_category defined in elements_view::__iter_cat
4314 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4315 using difference_type = range_difference_t<_Base>;
4317 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4320 _Iterator(iterator_t<_Base> __current)
4321 : _M_current(std::move(__current))
4325 _Iterator(_Iterator<!_Const> __i)
4326 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4327 : _M_current(std::move(__i._M_current))
4330 constexpr const iterator_t<_Base>&
4331 base() const& noexcept
4332 { return _M_current; }
4334 constexpr iterator_t<_Base>
4336 { return std::move(_M_current); }
4338 constexpr decltype(auto)
4340 { return _S_get_element(_M_current); }
4342 constexpr _Iterator&
4354 operator++(int) requires forward_range<_Base>
4361 constexpr _Iterator&
4362 operator--() requires bidirectional_range<_Base>
4369 operator--(int) requires bidirectional_range<_Base>
4376 constexpr _Iterator&
4377 operator+=(difference_type __n)
4378 requires random_access_range<_Base>
4384 constexpr _Iterator&
4385 operator-=(difference_type __n)
4386 requires random_access_range<_Base>
4392 constexpr decltype(auto)
4393 operator[](difference_type __n) const
4394 requires random_access_range<_Base>
4395 { return _S_get_element(_M_current + __n); }
4397 friend constexpr bool
4398 operator==(const _Iterator& __x, const _Iterator& __y)
4399 requires equality_comparable<iterator_t<_Base>>
4400 { return __x._M_current == __y._M_current; }
4402 friend constexpr bool
4403 operator<(const _Iterator& __x, const _Iterator& __y)
4404 requires random_access_range<_Base>
4405 { return __x._M_current < __y._M_current; }
4407 friend constexpr bool
4408 operator>(const _Iterator& __x, const _Iterator& __y)
4409 requires random_access_range<_Base>
4410 { return __y._M_current < __x._M_current; }
4412 friend constexpr bool
4413 operator<=(const _Iterator& __x, const _Iterator& __y)
4414 requires random_access_range<_Base>
4415 { return !(__y._M_current > __x._M_current); }
4417 friend constexpr bool
4418 operator>=(const _Iterator& __x, const _Iterator& __y)
4419 requires random_access_range<_Base>
4420 { return !(__x._M_current > __y._M_current); }
4422#ifdef __cpp_lib_three_way_comparison
4423 friend constexpr auto
4424 operator<=>(const _Iterator& __x, const _Iterator& __y)
4425 requires random_access_range<_Base>
4426 && three_way_comparable<iterator_t<_Base>>
4427 { return __x._M_current <=> __y._M_current; }
4430 friend constexpr _Iterator
4431 operator+(const _Iterator& __x, difference_type __y)
4432 requires random_access_range<_Base>
4433 { return _Iterator{__x} += __y; }
4435 friend constexpr _Iterator
4436 operator+(difference_type __x, const _Iterator& __y)
4437 requires random_access_range<_Base>
4438 { return __y + __x; }
4440 friend constexpr _Iterator
4441 operator-(const _Iterator& __x, difference_type __y)
4442 requires random_access_range<_Base>
4443 { return _Iterator{__x} -= __y; }
4445 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4446 // 3483. transform_view::iterator's difference is overconstrained
4447 friend constexpr difference_type
4448 operator-(const _Iterator& __x, const _Iterator& __y)
4449 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4450 { return __x._M_current - __y._M_current; }
4452 template <bool> friend struct _Sentinel;
4455 template<bool _Const>
4459 template<bool _Const2>
4461 _M_equal(const _Iterator<_Const2>& __x) const
4462 { return __x._M_current == _M_end; }
4464 template<bool _Const2>
4466 _M_distance_from(const _Iterator<_Const2>& __i) const
4467 { return _M_end - __i._M_current; }
4469 using _Base = elements_view::_Base<_Const>;
4470 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4473 _Sentinel() = default;
4476 _Sentinel(sentinel_t<_Base> __end)
4477 : _M_end(std::move(__end))
4481 _Sentinel(_Sentinel<!_Const> __other)
4483 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4484 : _M_end(std::move(__other._M_end))
4487 constexpr sentinel_t<_Base>
4491 template<bool _Const2>
4492 requires sentinel_for<sentinel_t<_Base>,
4493 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4494 friend constexpr bool
4495 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4496 { return __y._M_equal(__x); }
4498 template<bool _Const2,
4499 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4500 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4501 friend constexpr range_difference_t<_Base2>
4502 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4503 { return -__y._M_distance_from(__x); }
4505 template<bool _Const2,
4506 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4507 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4508 friend constexpr range_difference_t<_Base2>
4509 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4510 { return __x._M_distance_from(__y); }
4512 friend _Sentinel<!_Const>;
4515 _Vp _M_base = _Vp();
4518 template<typename _Tp, size_t _Nm>
4519 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4520 = enable_borrowed_range<_Tp>;
4522 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4523 // 3563. keys_view example is broken
4524 template<typename _Range>
4525 using keys_view = elements_view<_Range, 0>;
4527 template<typename _Range>
4528 using values_view = elements_view<_Range, 1>;
4534 template<size_t _Nm, typename _Range>
4535 concept __can_elements_view
4536 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4537 } // namespace __detail
4539 template<size_t _Nm>
4540 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4542 template<viewable_range _Range>
4543 requires __detail::__can_elements_view<_Nm, _Range>
4545 operator() [[nodiscard]] (_Range&& __r) const
4547 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4550 static constexpr bool _S_has_simple_call_op = true;
4553 template<size_t _Nm>
4554 inline constexpr _Elements<_Nm> elements;
4555 inline constexpr auto keys = elements<0>;
4556 inline constexpr auto values = elements<1>;
4557 } // namespace views
4559#ifdef __cpp_lib_ranges_zip // C++ >= 23
4562 template<typename... _Rs>
4563 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4564 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4565 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4567 template<typename _Fp, typename _Tuple>
4569 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4571 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4572 return tuple<invoke_result_t<_Fp&, _Ts>...>
4573 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4574 }, std::forward<_Tuple>(__tuple));
4577 template<typename _Fp, typename _Tuple>
4579 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4581 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4582 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4583 }, std::forward<_Tuple>(__tuple));
4585 } // namespace __detail
4587 template<input_range... _Vs>
4588 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4589 class zip_view : public view_interface<zip_view<_Vs...>>
4591 tuple<_Vs...> _M_views;
4593 template<bool> class _Iterator;
4594 template<bool> class _Sentinel;
4597 zip_view() = default;
4600 zip_view(_Vs... __views)
4601 : _M_views(std::move(__views)...)
4605 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4606 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4609 begin() const requires (range<const _Vs> && ...)
4610 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4613 end() requires (!(__detail::__simple_view<_Vs> && ...))
4615 if constexpr (!__detail::__zip_is_common<_Vs...>)
4616 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4617 else if constexpr ((random_access_range<_Vs> && ...))
4618 return begin() + iter_difference_t<_Iterator<false>>(size());
4620 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4624 end() const requires (range<const _Vs> && ...)
4626 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4627 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4628 else if constexpr ((random_access_range<const _Vs> && ...))
4629 return begin() + iter_difference_t<_Iterator<true>>(size());
4631 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4635 size() requires (sized_range<_Vs> && ...)
4637 return std::apply([](auto... sizes) {
4638 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4639 return ranges::min({_CT(sizes)...});
4640 }, __detail::__tuple_transform(ranges::size, _M_views));
4644 size() const requires (sized_range<const _Vs> && ...)
4646 return std::apply([](auto... sizes) {
4647 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4648 return ranges::min({_CT(sizes)...});
4649 }, __detail::__tuple_transform(ranges::size, _M_views));
4653 template<typename... _Rs>
4654 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4656 template<typename... _Views>
4657 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4658 = (enable_borrowed_range<_Views> && ...);
4662 template<bool _Const, typename... _Vs>
4663 concept __all_random_access
4664 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4666 template<bool _Const, typename... _Vs>
4667 concept __all_bidirectional
4668 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4670 template<bool _Const, typename... _Vs>
4671 concept __all_forward
4672 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4674 template<bool _Const, typename... _Views>
4675 struct __zip_view_iter_cat
4678 template<bool _Const, typename... _Views>
4679 requires __all_forward<_Const, _Views...>
4680 struct __zip_view_iter_cat<_Const, _Views...>
4681 { using iterator_category = input_iterator_tag; };
4682 } // namespace __detail
4684 template<input_range... _Vs>
4685 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4686 template<bool _Const>
4687 class zip_view<_Vs...>::_Iterator
4688 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4690#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
4693 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4696 _Iterator(decltype(_M_current) __current)
4697 : _M_current(std::move(__current))
4703 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4704 return random_access_iterator_tag{};
4705 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4706 return bidirectional_iterator_tag{};
4707 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4708 return forward_iterator_tag{};
4710 return input_iterator_tag{};
4713#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
4714 template<move_constructible _Fp, input_range... _Ws>
4715 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4716 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4717 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4718 friend class zip_transform_view;
4722 // iterator_category defined in __zip_view_iter_cat
4723 using iterator_concept = decltype(_S_iter_concept());
4725 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4726 using difference_type
4727 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4729 _Iterator() = default;
4732 _Iterator(_Iterator<!_Const> __i)
4734 && (convertible_to<iterator_t<_Vs>,
4735 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4736 : _M_current(std::move(__i._M_current))
4742 auto __f = [](auto& __i) -> decltype(auto) {
4745 return __detail::__tuple_transform(__f, _M_current);
4748 constexpr _Iterator&
4751 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4761 requires __detail::__all_forward<_Const, _Vs...>
4768 constexpr _Iterator&
4770 requires __detail::__all_bidirectional<_Const, _Vs...>
4772 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4778 requires __detail::__all_bidirectional<_Const, _Vs...>
4785 constexpr _Iterator&
4786 operator+=(difference_type __x)
4787 requires __detail::__all_random_access<_Const, _Vs...>
4789 auto __f = [&]<typename _It>(_It& __i) {
4790 __i += iter_difference_t<_It>(__x);
4792 __detail::__tuple_for_each(__f, _M_current);
4796 constexpr _Iterator&
4797 operator-=(difference_type __x)
4798 requires __detail::__all_random_access<_Const, _Vs...>
4800 auto __f = [&]<typename _It>(_It& __i) {
4801 __i -= iter_difference_t<_It>(__x);
4803 __detail::__tuple_for_each(__f, _M_current);
4808 operator[](difference_type __n) const
4809 requires __detail::__all_random_access<_Const, _Vs...>
4811 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4812 return __i[iter_difference_t<_It>(__n)];
4814 return __detail::__tuple_transform(__f, _M_current);
4817 friend constexpr bool
4818 operator==(const _Iterator& __x, const _Iterator& __y)
4819 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4821 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4822 return __x._M_current == __y._M_current;
4824 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4825 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4826 }(make_index_sequence<sizeof...(_Vs)>{});
4829 friend constexpr auto
4830 operator<=>(const _Iterator& __x, const _Iterator& __y)
4831 requires __detail::__all_random_access<_Const, _Vs...>
4832 { return __x._M_current <=> __y._M_current; }
4834 friend constexpr _Iterator
4835 operator+(const _Iterator& __i, difference_type __n)
4836 requires __detail::__all_random_access<_Const, _Vs...>
4843 friend constexpr _Iterator
4844 operator+(difference_type __n, const _Iterator& __i)
4845 requires __detail::__all_random_access<_Const, _Vs...>
4852 friend constexpr _Iterator
4853 operator-(const _Iterator& __i, difference_type __n)
4854 requires __detail::__all_random_access<_Const, _Vs...>
4861 friend constexpr difference_type
4862 operator-(const _Iterator& __x, const _Iterator& __y)
4863 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4864 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4866 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4867 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4868 - std::get<_Is>(__y._M_current))...},
4870 [](difference_type __i) {
4871 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4873 }(make_index_sequence<sizeof...(_Vs)>{});
4876 friend constexpr auto
4877 iter_move(const _Iterator& __i)
4878 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4880 friend constexpr void
4881 iter_swap(const _Iterator& __l, const _Iterator& __r)
4882 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4884 [&]<size_t... _Is>(index_sequence<_Is...>) {
4885 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4886 }(make_index_sequence<sizeof...(_Vs)>{});
4889 friend class zip_view;
4892 template<input_range... _Vs>
4893 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4894 template<bool _Const>
4895 class zip_view<_Vs...>::_Sentinel
4897 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4900 _Sentinel(decltype(_M_end) __end)
4904 friend class zip_view;
4907 _Sentinel() = default;
4910 _Sentinel(_Sentinel<!_Const> __i)
4912 && (convertible_to<sentinel_t<_Vs>,
4913 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4914 : _M_end(std::move(__i._M_end))
4917 template<bool _OtherConst>
4918 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4919 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4920 friend constexpr bool
4921 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4923 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4924 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4925 }(make_index_sequence<sizeof...(_Vs)>{});
4928 template<bool _OtherConst>
4929 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4930 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4931 friend constexpr auto
4932 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4935 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4936 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4937 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4940 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4942 }(make_index_sequence<sizeof...(_Vs)>{});
4945 template<bool _OtherConst>
4946 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4947 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4948 friend constexpr auto
4949 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4950 { return -(__x - __y); }
4957 template<typename... _Ts>
4958 concept __can_zip_view
4959 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4964 template<typename... _Ts>
4965 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4967 operator() [[nodiscard]] (_Ts&&... __ts) const
4969 if constexpr (sizeof...(_Ts) == 0)
4970 return views::empty<tuple<>>;
4972 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4976 inline constexpr _Zip zip;
4981 template<typename _Range, bool _Const>
4982 using __range_iter_cat
4983 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
4986 template<move_constructible _Fp, input_range... _Vs>
4987 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4988 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4989 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4990 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
4992 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
4993 zip_view<_Vs...> _M_zip;
4995 using _InnerView = zip_view<_Vs...>;
4997 template<bool _Const>
4998 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5000 template<bool _Const>
5001 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5003 template<bool _Const>
5004 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5006 template<bool _Const>
5010 template<bool _Const>
5011 requires forward_range<_Base<_Const>>
5012 struct __iter_cat<_Const>
5018 using __detail::__maybe_const_t;
5019 using __detail::__range_iter_cat;
5020 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5021 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5022 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5023 // 3798. Rvalue reference and iterator_category
5024 if constexpr (!is_reference_v<_Res>)
5025 return input_iterator_tag{};
5026 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5027 random_access_iterator_tag> && ...))
5028 return random_access_iterator_tag{};
5029 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5030 bidirectional_iterator_tag> && ...))
5031 return bidirectional_iterator_tag{};
5032 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5033 forward_iterator_tag> && ...))
5034 return forward_iterator_tag{};
5036 return input_iterator_tag{};
5039 using iterator_category = decltype(_S_iter_cat());
5042 template<bool> class _Iterator;
5043 template<bool> class _Sentinel;
5046 zip_transform_view() = default;
5049 zip_transform_view(_Fp __fun, _Vs... __views)
5050 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5055 { return _Iterator<false>(*this, _M_zip.begin()); }
5059 requires range<const _InnerView>
5060 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5061 { return _Iterator<true>(*this, _M_zip.begin()); }
5066 if constexpr (common_range<_InnerView>)
5067 return _Iterator<false>(*this, _M_zip.end());
5069 return _Sentinel<false>(_M_zip.end());
5074 requires range<const _InnerView>
5075 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5077 if constexpr (common_range<const _InnerView>)
5078 return _Iterator<true>(*this, _M_zip.end());
5080 return _Sentinel<true>(_M_zip.end());
5084 size() requires sized_range<_InnerView>
5085 { return _M_zip.size(); }
5088 size() const requires sized_range<const _InnerView>
5089 { return _M_zip.size(); }
5092 template<class _Fp, class... Rs>
5093 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5095 template<move_constructible _Fp, input_range... _Vs>
5096 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5097 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5098 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5099 template<bool _Const>
5100 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5102 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5104 _Parent* _M_parent = nullptr;
5105 __ziperator<_Const> _M_inner;
5108 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5109 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5112 friend class zip_transform_view;
5115 // iterator_category defined in zip_transform_view::__iter_cat
5116 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
5118 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5119 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5120 using difference_type = range_difference_t<_Base<_Const>>;
5122 _Iterator() = default;
5125 _Iterator(_Iterator<!_Const> __i)
5126 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5127 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5130 constexpr decltype(auto)
5133 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5134 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5135 }, _M_inner._M_current);
5138 constexpr _Iterator&
5150 operator++(int) requires forward_range<_Base<_Const>>
5157 constexpr _Iterator&
5158 operator--() requires bidirectional_range<_Base<_Const>>
5165 operator--(int) requires bidirectional_range<_Base<_Const>>
5172 constexpr _Iterator&
5173 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5179 constexpr _Iterator&
5180 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5186 constexpr decltype(auto)
5187 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5189 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5190 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5191 }, _M_inner._M_current);
5194 friend constexpr bool
5195 operator==(const _Iterator& __x, const _Iterator& __y)
5196 requires equality_comparable<__ziperator<_Const>>
5197 { return __x._M_inner == __y._M_inner; }
5199 friend constexpr auto
5200 operator<=>(const _Iterator& __x, const _Iterator& __y)
5201 requires random_access_range<_Base<_Const>>
5202 { return __x._M_inner <=> __y._M_inner; }
5204 friend constexpr _Iterator
5205 operator+(const _Iterator& __i, difference_type __n)
5206 requires random_access_range<_Base<_Const>>
5207 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5209 friend constexpr _Iterator
5210 operator+(difference_type __n, const _Iterator& __i)
5211 requires random_access_range<_Base<_Const>>
5212 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5214 friend constexpr _Iterator
5215 operator-(const _Iterator& __i, difference_type __n)
5216 requires random_access_range<_Base<_Const>>
5217 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5219 friend constexpr difference_type
5220 operator-(const _Iterator& __x, const _Iterator& __y)
5221 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5222 { return __x._M_inner - __y._M_inner; }
5225 template<move_constructible _Fp, input_range... _Vs>
5226 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5227 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5228 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5229 template<bool _Const>
5230 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5232 __zentinel<_Const> _M_inner;
5235 _Sentinel(__zentinel<_Const> __inner)
5239 friend class zip_transform_view;
5242 _Sentinel() = default;
5245 _Sentinel(_Sentinel<!_Const> __i)
5246 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5247 : _M_inner(std::move(__i._M_inner))
5250 template<bool _OtherConst>
5251 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5252 friend constexpr bool
5253 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5254 { return __x._M_inner == __y._M_inner; }
5256 template<bool _OtherConst>
5257 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5258 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5259 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5260 { return __x._M_inner - __y._M_inner; }
5262 template<bool _OtherConst>
5263 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5264 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5265 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5266 { return __x._M_inner - __y._M_inner; }
5273 template<typename _Fp, typename... _Ts>
5274 concept __can_zip_transform_view
5275 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5278 struct _ZipTransform
5280 template<typename _Fp>
5281 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
5282 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
5284 operator() [[nodiscard]] (_Fp&&) const
5286 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5289 template<typename _Fp, typename... _Ts>
5290 requires (sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
5292 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5294 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5298 inline constexpr _ZipTransform zip_transform;
5301 template<forward_range _Vp, size_t _Nm>
5302 requires view<_Vp> && (_Nm > 0)
5303 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5305 _Vp _M_base = _Vp();
5307 template<bool> class _Iterator;
5308 template<bool> class _Sentinel;
5310 struct __as_sentinel
5314 adjacent_view() requires default_initializable<_Vp> = default;
5317 adjacent_view(_Vp __base)
5318 : _M_base(std::move(__base))
5321 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5322 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5324 base() const & requires copy_constructible<_Vp>
5329 { return std::move(_M_base); }
5332 begin() requires (!__detail::__simple_view<_Vp>)
5333 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5336 begin() const requires range<const _Vp>
5337 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5340 end() requires (!__detail::__simple_view<_Vp>)
5342 if constexpr (common_range<_Vp>)
5343 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5345 return _Sentinel<false>(ranges::end(_M_base));
5349 end() const requires range<const _Vp>
5351 if constexpr (common_range<const _Vp>)
5352 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5354 return _Sentinel<true>(ranges::end(_M_base));
5358 size() requires sized_range<_Vp>
5360 using _ST = decltype(ranges::size(_M_base));
5361 using _CT = common_type_t<_ST, size_t>;
5362 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5363 __sz -= std::min<_CT>(__sz, _Nm - 1);
5364 return static_cast<_ST>(__sz);
5368 size() const requires sized_range<const _Vp>
5370 using _ST = decltype(ranges::size(_M_base));
5371 using _CT = common_type_t<_ST, size_t>;
5372 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5373 __sz -= std::min<_CT>(__sz, _Nm - 1);
5374 return static_cast<_ST>(__sz);
5378 template<typename _Vp, size_t _Nm>
5379 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5380 = enable_borrowed_range<_Vp>;
5384 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5385 template<typename _Tp, size_t _Nm>
5386 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5388 // For a functor F that is callable with N arguments, the expression
5389 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5390 template<typename _Fp, size_t _Nm>
5393 template<typename... _Ts>
5394 static invoke_result_t<_Fp, _Ts...>
5395 __tuple_apply(const tuple<_Ts...>&); // not defined
5397 template<typename _Tp>
5398 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5399 operator()(_Tp&&); // not defined
5403 template<forward_range _Vp, size_t _Nm>
5404 requires view<_Vp> && (_Nm > 0)
5405 template<bool _Const>
5406 class adjacent_view<_Vp, _Nm>::_Iterator
5408#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
5411 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5412 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5415 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5417 for (auto& __i : _M_current)
5420 ranges::advance(__first, 1, __last);
5425 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5427 if constexpr (!bidirectional_range<_Base>)
5428 for (auto& __it : _M_current)
5431 for (size_t __i = 0; __i < _Nm; ++__i)
5433 _M_current[_Nm - 1 - __i] = __last;
5434 ranges::advance(__last, -1, __first);
5441 if constexpr (random_access_range<_Base>)
5442 return random_access_iterator_tag{};
5443 else if constexpr (bidirectional_range<_Base>)
5444 return bidirectional_iterator_tag{};
5446 return forward_iterator_tag{};
5449 friend class adjacent_view;
5451#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
5452 template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
5453 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5454 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5455 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5456 range_reference_t<_Wp>>>
5457 friend class adjacent_transform_view;
5461 using iterator_category = input_iterator_tag;
5462 using iterator_concept = decltype(_S_iter_concept());
5463 using value_type = conditional_t<_Nm == 2,
5464 pair<range_value_t<_Base>, range_value_t<_Base>>,
5465 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5466 using difference_type = range_difference_t<_Base>;
5468 _Iterator() = default;
5471 _Iterator(_Iterator<!_Const> __i)
5472 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5474 for (size_t __j = 0; __j < _Nm; ++__j)
5475 _M_current[__j] = std::move(__i._M_current[__j]);
5481 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5482 return __detail::__tuple_transform(__f, _M_current);
5485 constexpr _Iterator&
5488 for (auto& __i : _M_current)
5501 constexpr _Iterator&
5502 operator--() requires bidirectional_range<_Base>
5504 for (auto& __i : _M_current)
5510 operator--(int) requires bidirectional_range<_Base>
5517 constexpr _Iterator&
5518 operator+=(difference_type __x)
5519 requires random_access_range<_Base>
5521 for (auto& __i : _M_current)
5526 constexpr _Iterator&
5527 operator-=(difference_type __x)
5528 requires random_access_range<_Base>
5530 for (auto& __i : _M_current)
5536 operator[](difference_type __n) const
5537 requires random_access_range<_Base>
5539 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5540 return __detail::__tuple_transform(__f, _M_current);
5543 friend constexpr bool
5544 operator==(const _Iterator& __x, const _Iterator& __y)
5545 { return __x._M_current.back() == __y._M_current.back(); }
5547 friend constexpr bool
5548 operator<(const _Iterator& __x, const _Iterator& __y)
5549 requires random_access_range<_Base>
5550 { return __x._M_current.back() < __y._M_current.back(); }
5552 friend constexpr bool
5553 operator>(const _Iterator& __x, const _Iterator& __y)
5554 requires random_access_range<_Base>
5555 { return __y < __x; }
5557 friend constexpr bool
5558 operator<=(const _Iterator& __x, const _Iterator& __y)
5559 requires random_access_range<_Base>
5560 { return !(__y < __x); }
5562 friend constexpr bool
5563 operator>=(const _Iterator& __x, const _Iterator& __y)
5564 requires random_access_range<_Base>
5565 { return !(__x < __y); }
5567 friend constexpr auto
5568 operator<=>(const _Iterator& __x, const _Iterator& __y)
5569 requires random_access_range<_Base>
5570 && three_way_comparable<iterator_t<_Base>>
5571 { return __x._M_current.back() <=> __y._M_current.back(); }
5573 friend constexpr _Iterator
5574 operator+(const _Iterator& __i, difference_type __n)
5575 requires random_access_range<_Base>
5582 friend constexpr _Iterator
5583 operator+(difference_type __n, const _Iterator& __i)
5584 requires random_access_range<_Base>
5591 friend constexpr _Iterator
5592 operator-(const _Iterator& __i, difference_type __n)
5593 requires random_access_range<_Base>
5600 friend constexpr difference_type
5601 operator-(const _Iterator& __x, const _Iterator& __y)
5602 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5603 { return __x._M_current.back() - __y._M_current.back(); }
5605 friend constexpr auto
5606 iter_move(const _Iterator& __i)
5607 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5609 friend constexpr void
5610 iter_swap(const _Iterator& __l, const _Iterator& __r)
5611 requires indirectly_swappable<iterator_t<_Base>>
5613 for (size_t __i = 0; __i < _Nm; __i++)
5614 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5618 template<forward_range _Vp, size_t _Nm>
5619 requires view<_Vp> && (_Nm > 0)
5620 template<bool _Const>
5621 class adjacent_view<_Vp, _Nm>::_Sentinel
5623 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5625 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5628 _Sentinel(sentinel_t<_Base> __end)
5632 friend class adjacent_view;
5635 _Sentinel() = default;
5638 _Sentinel(_Sentinel<!_Const> __i)
5639 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5640 : _M_end(std::move(__i._M_end))
5643 template<bool _OtherConst>
5644 requires sentinel_for<sentinel_t<_Base>,
5645 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5646 friend constexpr bool
5647 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5648 { return __x._M_current.back() == __y._M_end; }
5650 template<bool _OtherConst>
5651 requires sized_sentinel_for<sentinel_t<_Base>,
5652 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5653 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5654 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5655 { return __x._M_current.back() - __y._M_end; }
5657 template<bool _OtherConst>
5658 requires sized_sentinel_for<sentinel_t<_Base>,
5659 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5660 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5661 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5662 { return __y._M_end - __x._M_current.back(); }
5669 template<size_t _Nm, typename _Range>
5670 concept __can_adjacent_view
5671 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5674 template<size_t _Nm>
5675 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5677 template<viewable_range _Range>
5678 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5680 operator() [[nodiscard]] (_Range&& __r) const
5682 if constexpr (_Nm == 0)
5683 return views::empty<tuple<>>;
5685 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5689 template<size_t _Nm>
5690 inline constexpr _Adjacent<_Nm> adjacent;
5692 inline constexpr auto pairwise = adjacent<2>;
5695 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5696 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5697 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5698 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5699 range_reference_t<_Vp>>>
5700 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5702 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5703 adjacent_view<_Vp, _Nm> _M_inner;
5705 using _InnerView = adjacent_view<_Vp, _Nm>;
5707 template<bool _Const>
5708 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5710 template<bool _Const>
5711 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5713 template<bool> class _Iterator;
5714 template<bool> class _Sentinel;
5717 adjacent_transform_view() = default;
5720 adjacent_transform_view(_Vp __base, _Fp __fun)
5721 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5724 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5725 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5726 // 3947. Unexpected constraints on adjacent_transform_view::base()
5728 base() const & requires copy_constructible<_Vp>
5729 { return _M_inner.base(); }
5733 { return std::move(_M_inner.base()); }
5737 { return _Iterator<false>(*this, _M_inner.begin()); }
5741 requires range<const _InnerView>
5742 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5743 range_reference_t<const _Vp>>
5744 { return _Iterator<true>(*this, _M_inner.begin()); }
5749 if constexpr (common_range<_InnerView>)
5750 return _Iterator<false>(*this, _M_inner.end());
5752 return _Sentinel<false>(_M_inner.end());
5757 requires range<const _InnerView>
5758 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5759 range_reference_t<const _Vp>>
5761 if constexpr (common_range<const _InnerView>)
5762 return _Iterator<true>(*this, _M_inner.end());
5764 return _Sentinel<true>(_M_inner.end());
5768 size() requires sized_range<_InnerView>
5769 { return _M_inner.size(); }
5772 size() const requires sized_range<const _InnerView>
5773 { return _M_inner.size(); }
5776 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5777 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5778 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5779 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5780 range_reference_t<_Vp>>>
5781 template<bool _Const>
5782 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5784 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5785 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5787 _Parent* _M_parent = nullptr;
5788 _InnerIter<_Const> _M_inner;
5791 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5792 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5798 using __detail::__maybe_const_t;
5799 using __detail::__unarize;
5800 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5801 range_reference_t<_Base>>;
5802 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5803 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5804 // 3798. Rvalue reference and iterator_category
5805 if constexpr (!is_reference_v<_Res>)
5806 return input_iterator_tag{};
5807 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5808 return random_access_iterator_tag{};
5809 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5810 return bidirectional_iterator_tag{};
5811 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5812 return forward_iterator_tag{};
5814 return input_iterator_tag{};
5817 friend class adjacent_transform_view;
5820 using iterator_category = decltype(_S_iter_cat());
5821 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5823 = remove_cvref_t<invoke_result_t
5824 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5825 range_reference_t<_Base>>>;
5826 using difference_type = range_difference_t<_Base>;
5828 _Iterator() = default;
5831 _Iterator(_Iterator<!_Const> __i)
5832 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5833 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5836 constexpr decltype(auto)
5839 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5840 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5841 }, _M_inner._M_current);
5844 constexpr _Iterator&
5859 constexpr _Iterator&
5860 operator--() requires bidirectional_range<_Base>
5867 operator--(int) requires bidirectional_range<_Base>
5874 constexpr _Iterator&
5875 operator+=(difference_type __x) requires random_access_range<_Base>
5881 constexpr _Iterator&
5882 operator-=(difference_type __x) requires random_access_range<_Base>
5888 constexpr decltype(auto)
5889 operator[](difference_type __n) const requires random_access_range<_Base>
5891 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5892 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5893 }, _M_inner._M_current);
5896 friend constexpr bool
5897 operator==(const _Iterator& __x, const _Iterator& __y)
5898 { return __x._M_inner == __y._M_inner; }
5900 friend constexpr bool
5901 operator<(const _Iterator& __x, const _Iterator& __y)
5902 requires random_access_range<_Base>
5903 { return __x._M_inner < __y._M_inner; }
5905 friend constexpr bool
5906 operator>(const _Iterator& __x, const _Iterator& __y)
5907 requires random_access_range<_Base>
5908 { return __x._M_inner > __y._M_inner; }
5910 friend constexpr bool
5911 operator<=(const _Iterator& __x, const _Iterator& __y)
5912 requires random_access_range<_Base>
5913 { return __x._M_inner <= __y._M_inner; }
5915 friend constexpr bool
5916 operator>=(const _Iterator& __x, const _Iterator& __y)
5917 requires random_access_range<_Base>
5918 { return __x._M_inner >= __y._M_inner; }
5920 friend constexpr auto
5921 operator<=>(const _Iterator& __x, const _Iterator& __y)
5922 requires random_access_range<_Base> &&
5923 three_way_comparable<_InnerIter<_Const>>
5924 { return __x._M_inner <=> __y._M_inner; }
5926 friend constexpr _Iterator
5927 operator+(const _Iterator& __i, difference_type __n)
5928 requires random_access_range<_Base>
5929 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5931 friend constexpr _Iterator
5932 operator+(difference_type __n, const _Iterator& __i)
5933 requires random_access_range<_Base>
5934 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5936 friend constexpr _Iterator
5937 operator-(const _Iterator& __i, difference_type __n)
5938 requires random_access_range<_Base>
5939 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5941 friend constexpr difference_type
5942 operator-(const _Iterator& __x, const _Iterator& __y)
5943 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5944 { return __x._M_inner - __y._M_inner; }
5947 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5948 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5949 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5950 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5951 range_reference_t<_Vp>>>
5952 template<bool _Const>
5953 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5955 _InnerSent<_Const> _M_inner;
5958 _Sentinel(_InnerSent<_Const> __inner)
5962 friend class adjacent_transform_view;
5965 _Sentinel() = default;
5968 _Sentinel(_Sentinel<!_Const> __i)
5969 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5970 : _M_inner(std::move(__i._M_inner))
5973 template<bool _OtherConst>
5974 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5975 friend constexpr bool
5976 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5977 { return __x._M_inner == __y._M_inner; }
5979 template<bool _OtherConst>
5980 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5981 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5982 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5983 { return __x._M_inner - __y._M_inner; }
5985 template<bool _OtherConst>
5986 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5987 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5988 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5989 { return __x._M_inner - __y._M_inner; }
5996 template<size_t _Nm, typename _Range, typename _Fp>
5997 concept __can_adjacent_transform_view
5998 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5999 (std::declval<_Range>(), std::declval<_Fp>()); };
6002 template<size_t _Nm>
6003 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6005 template<viewable_range _Range, typename _Fp>
6006 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6008 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
6010 if constexpr (_Nm == 0)
6011 return zip_transform(std::forward<_Fp>(__f));
6013 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6014 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6017 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6018 static constexpr int _S_arity = 2;
6019 static constexpr bool _S_has_simple_extra_args = true;
6022 template<size_t _Nm>
6023 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6025 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6027#endif // __cpp_lib_ranges_zip
6029#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6032 template<typename _Tp>
6033 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6035 _Tp __r = __num / __denom;
6036 if (__num % __denom)
6043 requires input_range<_Vp>
6044 class chunk_view : public view_interface<chunk_view<_Vp>>
6047 range_difference_t<_Vp> _M_n;
6048 range_difference_t<_Vp> _M_remainder = 0;
6049 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6056 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6057 : _M_base(std::move(__base)), _M_n(__n)
6058 { __glibcxx_assert(__n >= 0); }
6061 base() const & requires copy_constructible<_Vp>
6066 { return std::move(_M_base); }
6068 constexpr _OuterIter
6071 _M_current = ranges::begin(_M_base);
6072 _M_remainder = _M_n;
6073 return _OuterIter(*this);
6076 constexpr default_sentinel_t
6077 end() const noexcept
6078 { return default_sentinel; }
6081 size() requires sized_range<_Vp>
6083 return __detail::__to_unsigned_like(__detail::__div_ceil
6084 (ranges::distance(_M_base), _M_n));
6088 size() const requires sized_range<const _Vp>
6090 return __detail::__to_unsigned_like(__detail::__div_ceil
6091 (ranges::distance(_M_base), _M_n));
6095 template<typename _Range>
6096 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6099 requires input_range<_Vp>
6100 class chunk_view<_Vp>::_OuterIter
6102 chunk_view* _M_parent;
6105 _OuterIter(chunk_view& __parent) noexcept
6106 : _M_parent(std::__addressof(__parent))
6112 using iterator_concept = input_iterator_tag;
6113 using difference_type = range_difference_t<_Vp>;
6117 _OuterIter(_OuterIter&&) = default;
6118 _OuterIter& operator=(_OuterIter&&) = default;
6120 constexpr value_type
6123 __glibcxx_assert(*this != default_sentinel);
6124 return value_type(*_M_parent);
6127 constexpr _OuterIter&
6130 __glibcxx_assert(*this != default_sentinel);
6131 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6132 ranges::end(_M_parent->_M_base));
6133 _M_parent->_M_remainder = _M_parent->_M_n;
6141 friend constexpr bool
6142 operator==(const _OuterIter& __x, default_sentinel_t)
6144 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6145 && __x._M_parent->_M_remainder != 0;
6148 friend constexpr difference_type
6149 operator-(default_sentinel_t, const _OuterIter& __x)
6150 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6152 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6154 if (__dist < __x._M_parent->_M_remainder)
6155 return __dist == 0 ? 0 : 1;
6157 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6158 __x._M_parent->_M_n);
6161 friend constexpr difference_type
6162 operator-(const _OuterIter& __x, default_sentinel_t __y)
6163 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6164 { return -(__y - __x); }
6168 requires input_range<_Vp>
6169 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6172 chunk_view* _M_parent;
6175 value_type(chunk_view& __parent) noexcept
6176 : _M_parent(std::__addressof(__parent))
6182 constexpr _InnerIter
6183 begin() const noexcept
6184 { return _InnerIter(*_M_parent); }
6186 constexpr default_sentinel_t
6187 end() const noexcept
6188 { return default_sentinel; }
6192 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6194 return __detail::__to_unsigned_like
6195 (ranges::min(_M_parent->_M_remainder,
6196 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6201 requires input_range<_Vp>
6202 class chunk_view<_Vp>::_InnerIter
6204 chunk_view* _M_parent;
6207 _InnerIter(chunk_view& __parent) noexcept
6208 : _M_parent(std::__addressof(__parent))
6211 friend _OuterIter::value_type;
6214 using iterator_concept = input_iterator_tag;
6215 using difference_type = range_difference_t<_Vp>;
6216 using value_type = range_value_t<_Vp>;
6218 _InnerIter(_InnerIter&&) = default;
6219 _InnerIter& operator=(_InnerIter&&) = default;
6221 constexpr const iterator_t<_Vp>&
6223 { return *_M_parent->_M_current; }
6225 constexpr range_reference_t<_Vp>
6228 __glibcxx_assert(*this != default_sentinel);
6229 return **_M_parent->_M_current;
6232 constexpr _InnerIter&
6235 __glibcxx_assert(*this != default_sentinel);
6236 ++*_M_parent->_M_current;
6237 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6238 _M_parent->_M_remainder = 0;
6240 --_M_parent->_M_remainder;
6248 friend constexpr bool
6249 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6250 { return __x._M_parent->_M_remainder == 0; }
6252 friend constexpr difference_type
6253 operator-(default_sentinel_t, const _InnerIter& __x)
6254 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6256 return ranges::min(__x._M_parent->_M_remainder,
6257 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6260 friend constexpr difference_type
6261 operator-(const _InnerIter& __x, default_sentinel_t __y)
6262 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6263 { return -(__y - __x); }
6265 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6266 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
6267 friend constexpr range_rvalue_reference_t<_Vp>
6268 iter_move(const _InnerIter& __i)
6269 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6270 { return ranges::iter_move(*__i._M_parent->_M_current); }
6272 friend constexpr void
6273 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
6274 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6275 *__x._M_parent->_M_current)))
6276 requires indirectly_swappable<iterator_t<_Vp>>
6277 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6281 requires forward_range<_Vp>
6282 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6285 range_difference_t<_Vp> _M_n;
6286 template<bool> class _Iterator;
6290 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6291 : _M_base(std::move(__base)), _M_n(__n)
6292 { __glibcxx_assert(__n > 0); }
6295 base() const & requires copy_constructible<_Vp>
6300 { return std::move(_M_base); }
6303 begin() requires (!__detail::__simple_view<_Vp>)
6304 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6307 begin() const requires forward_range<const _Vp>
6308 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6311 end() requires (!__detail::__simple_view<_Vp>)
6313 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6315 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6316 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6318 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6319 return _Iterator<false>(this, ranges::end(_M_base));
6321 return default_sentinel;
6325 end() const requires forward_range<const _Vp>
6327 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6329 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6330 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6332 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6333 return _Iterator<true>(this, ranges::end(_M_base));
6335 return default_sentinel;
6339 size() requires sized_range<_Vp>
6341 return __detail::__to_unsigned_like(__detail::__div_ceil
6342 (ranges::distance(_M_base), _M_n));
6346 size() const requires sized_range<const _Vp>
6348 return __detail::__to_unsigned_like(__detail::__div_ceil
6349 (ranges::distance(_M_base), _M_n));
6353 template<typename _Vp>
6354 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6355 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6358 requires forward_range<_Vp>
6359 template<bool _Const>
6360 class chunk_view<_Vp>::_Iterator
6362 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6363 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6365 iterator_t<_Base> _M_current = iterator_t<_Base>();
6366 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6367 range_difference_t<_Base> _M_n = 0;
6368 range_difference_t<_Base> _M_missing = 0;
6371 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6372 range_difference_t<_Base> __missing = 0)
6373 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6374 _M_n(__parent->_M_n), _M_missing(__missing)
6380 if constexpr (random_access_range<_Base>)
6381 return random_access_iterator_tag{};
6382 else if constexpr (bidirectional_range<_Base>)
6383 return bidirectional_iterator_tag{};
6385 return forward_iterator_tag{};
6391 using iterator_category = input_iterator_tag;
6392 using iterator_concept = decltype(_S_iter_cat());
6393 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6394 using difference_type = range_difference_t<_Base>;
6396 _Iterator() = default;
6398 constexpr _Iterator(_Iterator<!_Const> __i)
6400 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6401 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6402 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6403 _M_n(__i._M_n), _M_missing(__i._M_missing)
6406 constexpr iterator_t<_Base>
6408 { return _M_current; }
6410 constexpr value_type
6413 __glibcxx_assert(_M_current != _M_end);
6414 return views::take(subrange(_M_current, _M_end), _M_n);
6417 constexpr _Iterator&
6420 __glibcxx_assert(_M_current != _M_end);
6421 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6433 constexpr _Iterator&
6434 operator--() requires bidirectional_range<_Base>
6436 ranges::advance(_M_current, _M_missing - _M_n);
6442 operator--(int) requires bidirectional_range<_Base>
6449 constexpr _Iterator&
6450 operator+=(difference_type __x)
6451 requires random_access_range<_Base>
6455 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6456 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6460 ranges::advance(_M_current, _M_n * __x + _M_missing);
6466 constexpr _Iterator&
6467 operator-=(difference_type __x)
6468 requires random_access_range<_Base>
6469 { return *this += -__x; }
6471 constexpr value_type
6472 operator[](difference_type __n) const
6473 requires random_access_range<_Base>
6474 { return *(*this + __n); }
6476 friend constexpr bool
6477 operator==(const _Iterator& __x, const _Iterator& __y)
6478 { return __x._M_current == __y._M_current; }
6480 friend constexpr bool
6481 operator==(const _Iterator& __x, default_sentinel_t)
6482 { return __x._M_current == __x._M_end; }
6484 friend constexpr bool
6485 operator<(const _Iterator& __x, const _Iterator& __y)
6486 requires random_access_range<_Base>
6487 { return __x._M_current > __y._M_current; }
6489 friend constexpr bool
6490 operator>(const _Iterator& __x, const _Iterator& __y)
6491 requires random_access_range<_Base>
6492 { return __y < __x; }
6494 friend constexpr bool
6495 operator<=(const _Iterator& __x, const _Iterator& __y)
6496 requires random_access_range<_Base>
6497 { return !(__y < __x); }
6499 friend constexpr bool
6500 operator>=(const _Iterator& __x, const _Iterator& __y)
6501 requires random_access_range<_Base>
6502 { return !(__x < __y); }
6504 friend constexpr auto
6505 operator<=>(const _Iterator& __x, const _Iterator& __y)
6506 requires random_access_range<_Base>
6507 && three_way_comparable<iterator_t<_Base>>
6508 { return __x._M_current <=> __y._M_current; }
6510 friend constexpr _Iterator
6511 operator+(const _Iterator& __i, difference_type __n)
6512 requires random_access_range<_Base>
6519 friend constexpr _Iterator
6520 operator+(difference_type __n, const _Iterator& __i)
6521 requires random_access_range<_Base>
6528 friend constexpr _Iterator
6529 operator-(const _Iterator& __i, difference_type __n)
6530 requires random_access_range<_Base>
6537 friend constexpr difference_type
6538 operator-(const _Iterator& __x, const _Iterator& __y)
6539 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6541 return (__x._M_current - __y._M_current
6542 + __x._M_missing - __y._M_missing) / __x._M_n;
6545 friend constexpr difference_type
6546 operator-(default_sentinel_t, const _Iterator& __x)
6547 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6548 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6550 friend constexpr difference_type
6551 operator-(const _Iterator& __x, default_sentinel_t __y)
6552 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6553 { return -(__y - __x); }
6560 template<typename _Range, typename _Dp>
6561 concept __can_chunk_view
6562 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6565 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6567 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6568 requires __detail::__can_chunk_view<_Range, _Dp>
6570 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6571 { return chunk_view(std::forward<_Range>(__r), __n); }
6573 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6574 static constexpr int _S_arity = 2;
6575 static constexpr bool _S_has_simple_extra_args = true;
6578 inline constexpr _Chunk chunk;
6580#endif // __cpp_lib_ranges_chunk
6582#ifdef __cpp_lib_ranges_slide // C++ >= 23
6585 template<typename _Vp>
6586 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6588 template<typename _Vp>
6589 concept __slide_caches_last
6590 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6592 template<typename _Vp>
6593 concept __slide_caches_first
6594 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6597 template<forward_range _Vp>
6599 class slide_view : public view_interface<slide_view<_Vp>>
6602 range_difference_t<_Vp> _M_n;
6603 [[no_unique_address]]
6604 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6605 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6606 [[no_unique_address]]
6607 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6608 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6610 template<bool> class _Iterator;
6615 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6616 : _M_base(std::move(__base)), _M_n(__n)
6617 { __glibcxx_assert(__n > 0); }
6619 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6620 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
6622 base() const & requires copy_constructible<_Vp>
6627 { return std::move(_M_base); }
6630 begin() requires (!(__detail::__simple_view<_Vp>
6631 && __detail::__slide_caches_nothing<const _Vp>))
6633 if constexpr (__detail::__slide_caches_first<_Vp>)
6635 iterator_t<_Vp> __it;
6636 if (_M_cached_begin._M_has_value())
6637 __it = _M_cached_begin._M_get(_M_base);
6640 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6641 _M_cached_begin._M_set(_M_base, __it);
6643 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6646 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6650 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6651 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6654 end() requires (!(__detail::__simple_view<_Vp>
6655 && __detail::__slide_caches_nothing<const _Vp>))
6657 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6658 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6660 else if constexpr (__detail::__slide_caches_last<_Vp>)
6662 iterator_t<_Vp> __it;
6663 if (_M_cached_end._M_has_value())
6664 __it = _M_cached_end._M_get(_M_base);
6667 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6668 _M_cached_end._M_set(_M_base, __it);
6670 return _Iterator<false>(std::move(__it), _M_n);
6672 else if constexpr (common_range<_Vp>)
6673 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6675 return _Sentinel(ranges::end(_M_base));
6679 end() const requires __detail::__slide_caches_nothing<const _Vp>
6680 { return begin() + range_difference_t<const _Vp>(size()); }
6683 size() requires sized_range<_Vp>
6685 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6688 return __detail::__to_unsigned_like(__sz);
6692 size() const requires sized_range<const _Vp>
6694 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6697 return __detail::__to_unsigned_like(__sz);
6701 template<typename _Range>
6702 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6704 template<typename _Vp>
6705 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6706 = enable_borrowed_range<_Vp>;
6708 template<forward_range _Vp>
6710 template<bool _Const>
6711 class slide_view<_Vp>::_Iterator
6713 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6714 static constexpr bool _S_last_elt_present
6715 = __detail::__slide_caches_first<_Base>;
6717 iterator_t<_Base> _M_current = iterator_t<_Base>();
6718 [[no_unique_address]]
6719 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6720 _M_last_elt = decltype(_M_last_elt)();
6721 range_difference_t<_Base> _M_n = 0;
6724 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6725 requires (!_S_last_elt_present)
6726 : _M_current(__current), _M_n(__n)
6730 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6731 range_difference_t<_Base> __n)
6732 requires _S_last_elt_present
6733 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6739 if constexpr (random_access_range<_Base>)
6740 return random_access_iterator_tag{};
6741 else if constexpr (bidirectional_range<_Base>)
6742 return bidirectional_iterator_tag{};
6744 return forward_iterator_tag{};
6748 friend slide_view::_Sentinel;
6751 using iterator_category = input_iterator_tag;
6752 using iterator_concept = decltype(_S_iter_concept());
6753 using value_type = decltype(views::counted(_M_current, _M_n));
6754 using difference_type = range_difference_t<_Base>;
6756 _Iterator() = default;
6759 _Iterator(_Iterator<!_Const> __i)
6760 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6761 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6766 { return views::counted(_M_current, _M_n); }
6768 constexpr _Iterator&
6772 if constexpr (_S_last_elt_present)
6785 constexpr _Iterator&
6786 operator--() requires bidirectional_range<_Base>
6789 if constexpr (_S_last_elt_present)
6795 operator--(int) requires bidirectional_range<_Base>
6802 constexpr _Iterator&
6803 operator+=(difference_type __x)
6804 requires random_access_range<_Base>
6807 if constexpr (_S_last_elt_present)
6812 constexpr _Iterator&
6813 operator-=(difference_type __x)
6814 requires random_access_range<_Base>
6817 if constexpr (_S_last_elt_present)
6823 operator[](difference_type __n) const
6824 requires random_access_range<_Base>
6825 { return views::counted(_M_current + __n, _M_n); }
6827 friend constexpr bool
6828 operator==(const _Iterator& __x, const _Iterator& __y)
6830 if constexpr (_S_last_elt_present)
6831 return __x._M_last_elt == __y._M_last_elt;
6833 return __x._M_current == __y._M_current;
6836 friend constexpr bool
6837 operator<(const _Iterator& __x, const _Iterator& __y)
6838 requires random_access_range<_Base>
6839 { return __x._M_current < __y._M_current; }
6841 friend constexpr bool
6842 operator>(const _Iterator& __x, const _Iterator& __y)
6843 requires random_access_range<_Base>
6844 { return __y < __x; }
6846 friend constexpr bool
6847 operator<=(const _Iterator& __x, const _Iterator& __y)
6848 requires random_access_range<_Base>
6849 { return !(__y < __x); }
6851 friend constexpr bool
6852 operator>=(const _Iterator& __x, const _Iterator& __y)
6853 requires random_access_range<_Base>
6854 { return !(__x < __y); }
6856 friend constexpr auto
6857 operator<=>(const _Iterator& __x, const _Iterator& __y)
6858 requires random_access_range<_Base>
6859 && three_way_comparable<iterator_t<_Base>>
6860 { return __x._M_current <=> __y._M_current; }
6862 friend constexpr _Iterator
6863 operator+(const _Iterator& __i, difference_type __n)
6864 requires random_access_range<_Base>
6871 friend constexpr _Iterator
6872 operator+(difference_type __n, const _Iterator& __i)
6873 requires random_access_range<_Base>
6880 friend constexpr _Iterator
6881 operator-(const _Iterator& __i, difference_type __n)
6882 requires random_access_range<_Base>
6889 friend constexpr difference_type
6890 operator-(const _Iterator& __x, const _Iterator& __y)
6891 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6893 if constexpr (_S_last_elt_present)
6894 return __x._M_last_elt - __y._M_last_elt;
6896 return __x._M_current - __y._M_current;
6900 template<forward_range _Vp>
6902 class slide_view<_Vp>::_Sentinel
6904 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6907 _Sentinel(sentinel_t<_Vp> __end)
6914 _Sentinel() = default;
6916 friend constexpr bool
6917 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6918 { return __x._M_last_elt == __y._M_end; }
6920 friend constexpr range_difference_t<_Vp>
6921 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6922 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6923 { return __x._M_last_elt - __y._M_end; }
6925 friend constexpr range_difference_t<_Vp>
6926 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6927 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6928 { return __y._M_end -__x._M_last_elt; }
6935 template<typename _Range, typename _Dp>
6936 concept __can_slide_view
6937 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6940 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6942 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6943 requires __detail::__can_slide_view<_Range, _Dp>
6945 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6946 { return slide_view(std::forward<_Range>(__r), __n); }
6948 using __adaptor::_RangeAdaptor<_Slide>::operator();
6949 static constexpr int _S_arity = 2;
6950 static constexpr bool _S_has_simple_extra_args = true;
6953 inline constexpr _Slide slide;
6955#endif // __cpp_lib_ranges_slide
6957#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
6958 template<forward_range _Vp,
6959 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6960 requires view<_Vp> && is_object_v<_Pred>
6961 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6963 _Vp _M_base = _Vp();
6964 __detail::__box<_Pred> _M_pred;
6965 __detail::_CachedPosition<_Vp> _M_cached_begin;
6967 constexpr iterator_t<_Vp>
6968 _M_find_next(iterator_t<_Vp> __current)
6970 __glibcxx_assert(_M_pred.has_value());
6971 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6972 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6974 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6975 return ranges::next(__it, 1, ranges::end(_M_base));
6978 constexpr iterator_t<_Vp>
6979 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
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<_Up>(__y), std::forward<_Tp>(__x)));
6985 auto __rbegin = std::make_reverse_iterator(__current);
6986 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
6987 __glibcxx_assert(__rbegin != __rend);
6988 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
6989 return ranges::prev(__it, 1, ranges::begin(_M_base));
6995 chunk_by_view() requires (default_initializable<_Vp>
6996 && default_initializable<_Pred>)
7000 chunk_by_view(_Vp __base, _Pred __pred)
7001 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
7005 base() const & requires copy_constructible<_Vp>
7010 { return std::move(_M_base); }
7012 constexpr const _Pred&
7014 { return *_M_pred; }
7019 __glibcxx_assert(_M_pred.has_value());
7020 iterator_t<_Vp> __it;
7021 if (_M_cached_begin._M_has_value())
7022 __it = _M_cached_begin._M_get(_M_base);
7025 __it = _M_find_next(ranges::begin(_M_base));
7026 _M_cached_begin._M_set(_M_base, __it);
7028 return _Iterator(*this, ranges::begin(_M_base), __it);
7034 if constexpr (common_range<_Vp>)
7035 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
7037 return default_sentinel;
7041 template<typename _Range, typename _Pred>
7042 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7044 template<forward_range _Vp,
7045 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7046 requires view<_Vp> && is_object_v<_Pred>
7047 class chunk_by_view<_Vp, _Pred>::_Iterator
7049 chunk_by_view* _M_parent = nullptr;
7050 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7051 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7054 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7055 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7061 if constexpr (bidirectional_range<_Vp>)
7062 return bidirectional_iterator_tag{};
7064 return forward_iterator_tag{};
7067 friend chunk_by_view;
7070 using value_type = subrange<iterator_t<_Vp>>;
7071 using difference_type = range_difference_t<_Vp>;
7072 using iterator_category = input_iterator_tag;
7073 using iterator_concept = decltype(_S_iter_concept());
7075 _Iterator() = default;
7077 constexpr value_type
7080 __glibcxx_assert(_M_current != _M_next);
7081 return ranges::subrange(_M_current, _M_next);
7084 constexpr _Iterator&
7087 __glibcxx_assert(_M_current != _M_next);
7088 _M_current = _M_next;
7089 _M_next = _M_parent->_M_find_next(_M_current);
7101 constexpr _Iterator&
7102 operator--() requires bidirectional_range<_Vp>
7104 _M_next = _M_current;
7105 _M_current = _M_parent->_M_find_prev(_M_next);
7110 operator--(int) requires bidirectional_range<_Vp>
7117 friend constexpr bool
7118 operator==(const _Iterator& __x, const _Iterator& __y)
7119 { return __x._M_current == __y._M_current; }
7121 friend constexpr bool
7122 operator==(const _Iterator& __x, default_sentinel_t)
7123 { return __x._M_current == __x._M_next; }
7130 template<typename _Range, typename _Pred>
7131 concept __can_chunk_by_view
7132 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7135 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7137 template<viewable_range _Range, typename _Pred>
7138 requires __detail::__can_chunk_by_view<_Range, _Pred>
7140 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7141 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7143 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7144 static constexpr int _S_arity = 2;
7145 static constexpr bool _S_has_simple_extra_args = true;
7148 inline constexpr _ChunkBy chunk_by;
7150#endif // __cpp_lib_ranges_chunk_by
7152#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7155 template<typename _Range, typename _Pattern>
7156 concept __compatible_joinable_ranges
7157 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7158 && common_reference_with<range_reference_t<_Range>,
7159 range_reference_t<_Pattern>>
7160 && common_reference_with<range_rvalue_reference_t<_Range>,
7161 range_rvalue_reference_t<_Pattern>>;
7163 template<typename _Range>
7164 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7167 template<input_range _Vp, forward_range _Pattern>
7168 requires view<_Vp> && view<_Pattern>
7169 && input_range<range_reference_t<_Vp>>
7170 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7171 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7173 using _InnerRange = range_reference_t<_Vp>;
7175 _Vp _M_base = _Vp();
7176 [[no_unique_address]]
7177 __detail::__maybe_present_t<!forward_range<_Vp>,
7178 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7179 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7180 _Pattern _M_pattern = _Pattern();
7182 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7183 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7184 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7186 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7187 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7188 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7190 template<bool _Const>
7191 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7193 template<bool _Const>
7197 template<bool _Const>
7198 requires _S_ref_is_glvalue<_Const>
7199 && forward_range<_Base<_Const>>
7200 && forward_range<_InnerBase<_Const>>
7201 struct __iter_cat<_Const>
7207 using _OuterIter = join_with_view::_OuterIter<_Const>;
7208 using _InnerIter = join_with_view::_InnerIter<_Const>;
7209 using _PatternIter = join_with_view::_PatternIter<_Const>;
7210 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7211 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7212 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7213 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7214 // 3798. Rvalue reference and iterator_category
7215 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7216 iter_reference_t<_PatternIter>>>)
7217 return input_iterator_tag{};
7218 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7219 && derived_from<_InnerCat, bidirectional_iterator_tag>
7220 && derived_from<_PatternCat, bidirectional_iterator_tag>
7221 && common_range<_InnerBase<_Const>>
7222 && common_range<_PatternBase<_Const>>)
7223 return bidirectional_iterator_tag{};
7224 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7225 && derived_from<_InnerCat, forward_iterator_tag>
7226 && derived_from<_PatternCat, forward_iterator_tag>)
7227 return forward_iterator_tag{};
7229 return input_iterator_tag{};
7232 using iterator_category = decltype(_S_iter_cat());
7235 template<bool> class _Iterator;
7236 template<bool> class _Sentinel;
7239 join_with_view() requires (default_initializable<_Vp>
7240 && default_initializable<_Pattern>)
7244 join_with_view(_Vp __base, _Pattern __pattern)
7245 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7248 template<input_range _Range>
7249 requires constructible_from<_Vp, views::all_t<_Range>>
7250 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7252 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7253 : _M_base(views::all(std::forward<_Range>(__r))),
7254 _M_pattern(views::single(std::move(__e)))
7258 base() const& requires copy_constructible<_Vp>
7263 { return std::move(_M_base); }
7268 if constexpr (forward_range<_Vp>)
7270 constexpr bool __use_const = is_reference_v<_InnerRange>
7271 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7272 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7276 _M_outer_it = ranges::begin(_M_base);
7277 return _Iterator<false>{*this};
7283 requires forward_range<const _Vp>
7284 && forward_range<const _Pattern>
7285 && is_reference_v<range_reference_t<const _Vp>>
7286 && input_range<range_reference_t<const _Vp>>
7287 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7292 constexpr bool __use_const
7293 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7294 if constexpr (is_reference_v<_InnerRange>
7295 && forward_range<_Vp> && common_range<_Vp>
7296 && forward_range<_InnerRange> && common_range<_InnerRange>)
7297 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7299 return _Sentinel<__use_const>{*this};
7304 requires forward_range<const _Vp>
7305 && forward_range<const _Pattern>
7306 && is_reference_v<range_reference_t<const _Vp>>
7307 && input_range<range_reference_t<const _Vp>>
7309 using _InnerConstRange = range_reference_t<const _Vp>;
7310 if constexpr (forward_range<_InnerConstRange>
7311 && common_range<const _Vp>
7312 && common_range<_InnerConstRange>)
7313 return _Iterator<true>{*this, ranges::end(_M_base)};
7315 return _Sentinel<true>{*this};
7319 template<typename _Range, typename _Pattern>
7320 join_with_view(_Range&&, _Pattern&&)
7321 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7323 template<input_range _Range>
7324 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7325 -> join_with_view<views::all_t<_Range>,
7326 single_view<range_value_t<range_reference_t<_Range>>>>;
7328 template<input_range _Vp, forward_range _Pattern>
7329 requires view<_Vp> && view<_Pattern>
7330 && input_range<range_reference_t<_Vp>>
7331 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7332 template<bool _Const>
7333 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7335 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7336 using _Base = join_with_view::_Base<_Const>;
7337 using _InnerBase = join_with_view::_InnerBase<_Const>;
7338 using _PatternBase = join_with_view::_PatternBase<_Const>;
7340 using _OuterIter = join_with_view::_OuterIter<_Const>;
7341 using _InnerIter = join_with_view::_InnerIter<_Const>;
7342 using _PatternIter = join_with_view::_PatternIter<_Const>;
7344 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7346 _Parent* _M_parent = nullptr;
7347 [[no_unique_address]]
7348 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
7349 = decltype(_M_outer_it)();
7350 variant<_PatternIter, _InnerIter> _M_inner_it;
7352 constexpr _OuterIter&
7355 if constexpr (forward_range<_Base>)
7358 return *_M_parent->_M_outer_it;
7361 constexpr const _OuterIter&
7362 _M_get_outer() const
7364 if constexpr (forward_range<_Base>)
7367 return *_M_parent->_M_outer_it;
7371 _Iterator(_Parent& __parent, _OuterIter __outer)
7372 requires forward_range<_Base>
7373 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7375 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7377 auto&& __inner = _M_update_inner();
7378 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7384 _Iterator(_Parent& __parent)
7385 requires (!forward_range<_Base>)
7386 : _M_parent(std::__addressof(__parent))
7388 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7390 auto&& __inner = _M_update_inner();
7391 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7399 _OuterIter& __outer = _M_get_outer();
7400 if constexpr (_S_ref_is_glvalue)
7401 return __detail::__as_lvalue(*__outer);
7403 return _M_parent->_M_inner._M_emplace_deref(__outer);
7409 if constexpr (_S_ref_is_glvalue)
7410 return __detail::__as_lvalue(*_M_get_outer());
7412 return *_M_parent->_M_inner;
7420 if (_M_inner_it.index() == 0)
7422 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7425 auto&& __inner = _M_update_inner();
7426 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7430 auto&& __inner = _M_get_inner();
7431 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7434 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7436 if constexpr (_S_ref_is_glvalue)
7437 _M_inner_it.template emplace<0>();
7441 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7449 if constexpr (_S_ref_is_glvalue
7450 && bidirectional_range<_Base>
7451 && __detail::__bidirectional_common<_InnerBase>
7452 && __detail::__bidirectional_common<_PatternBase>)
7453 return bidirectional_iterator_tag{};
7454 else if constexpr (_S_ref_is_glvalue
7455 && forward_range<_Base>
7456 && forward_range<_InnerBase>)
7457 return forward_iterator_tag{};
7459 return input_iterator_tag{};
7462 friend join_with_view;
7465 using iterator_concept = decltype(_S_iter_concept());
7466 // iterator_category defined in join_with_view::__iter_cat
7467 using value_type = common_type_t<iter_value_t<_InnerIter>,
7468 iter_value_t<_PatternIter>>;
7469 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7470 iter_difference_t<_InnerIter>,
7471 iter_difference_t<_PatternIter>>;
7473 _Iterator() = default;
7476 _Iterator(_Iterator<!_Const> __i)
7478 && convertible_to<iterator_t<_Vp>, _OuterIter>
7479 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7480 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7481 : _M_parent(__i._M_parent),
7482 _M_outer_it(std::move(__i._M_outer_it))
7484 if (__i._M_inner_it.index() == 0)
7485 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7487 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7490 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7491 iter_reference_t<_PatternIter>>
7494 if (_M_inner_it.index() == 0)
7495 return *std::get<0>(_M_inner_it);
7497 return *std::get<1>(_M_inner_it);
7500 constexpr _Iterator&
7503 if (_M_inner_it.index() == 0)
7504 ++std::get<0>(_M_inner_it);
7506 ++std::get<1>(_M_inner_it);
7517 requires _S_ref_is_glvalue
7518 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7520 _Iterator __tmp = *this;
7525 constexpr _Iterator&
7527 requires _S_ref_is_glvalue
7528 && bidirectional_range<_Base>
7529 && __detail::__bidirectional_common<_InnerBase>
7530 && __detail::__bidirectional_common<_PatternBase>
7532 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7534 auto&& __inner = *--_M_outer_it;
7535 _M_inner_it.template emplace<1>(ranges::end(__inner));
7540 if (_M_inner_it.index() == 0)
7542 auto& __it = std::get<0>(_M_inner_it);
7543 if (__it == ranges::begin(_M_parent->_M_pattern))
7545 auto&& __inner = *--_M_outer_it;
7546 _M_inner_it.template emplace<1>(ranges::end(__inner));
7553 auto& __it = std::get<1>(_M_inner_it);
7554 auto&& __inner = *_M_outer_it;
7555 if (__it == ranges::begin(__inner))
7556 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7562 if (_M_inner_it.index() == 0)
7563 --std::get<0>(_M_inner_it);
7565 --std::get<1>(_M_inner_it);
7571 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7572 && __detail::__bidirectional_common<_InnerBase>
7573 && __detail::__bidirectional_common<_PatternBase>
7575 _Iterator __tmp = *this;
7580 friend constexpr bool
7581 operator==(const _Iterator& __x, const _Iterator& __y)
7582 requires _S_ref_is_glvalue
7583 && forward_range<_Base> && equality_comparable<_InnerIter>
7584 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7586 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7587 iter_rvalue_reference_t<_PatternIter>>
7588 iter_move(const _Iterator& __x)
7590 if (__x._M_inner_it.index() == 0)
7591 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7593 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7596 friend constexpr void
7597 iter_swap(const _Iterator& __x, const _Iterator& __y)
7598 requires indirectly_swappable<_InnerIter, _PatternIter>
7600 if (__x._M_inner_it.index() == 0)
7602 if (__y._M_inner_it.index() == 0)
7603 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7605 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7609 if (__y._M_inner_it.index() == 0)
7610 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7612 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7617 template<input_range _Vp, forward_range _Pattern>
7618 requires view<_Vp> && view<_Pattern>
7619 && input_range<range_reference_t<_Vp>>
7620 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7621 template<bool _Const>
7622 class join_with_view<_Vp, _Pattern>::_Sentinel
7624 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7625 using _Base = join_with_view::_Base<_Const>;
7627 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7630 _Sentinel(_Parent& __parent)
7631 : _M_end(ranges::end(__parent._M_base))
7634 friend join_with_view;
7637 _Sentinel() = default;
7640 _Sentinel(_Sentinel<!_Const> __s)
7641 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7642 : _M_end(std::move(__s._M_end))
7645 template<bool _OtherConst>
7646 requires sentinel_for<sentinel_t<_Base>,
7647 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7648 friend constexpr bool
7649 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7650 { return __x._M_get_outer() == __y._M_end; }
7657 template<typename _Range, typename _Pattern>
7658 concept __can_join_with_view
7659 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7660 } // namespace __detail
7662 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7664 template<viewable_range _Range, typename _Pattern>
7665 requires __detail::__can_join_with_view<_Range, _Pattern>
7667 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7669 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7672 using _RangeAdaptor<_JoinWith>::operator();
7673 static constexpr int _S_arity = 2;
7674 template<typename _Pattern>
7675 static constexpr bool _S_has_simple_extra_args
7676 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7679 inline constexpr _JoinWith join_with;
7680 } // namespace views
7681#endif // __cpp_lib_ranges_join_with
7683#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7684 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7685 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7686 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7687 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7689 __detail::__box<_Tp> _M_value;
7690 [[no_unique_address]] _Bound _M_bound = _Bound();
7694 template<typename _Range>
7695 friend constexpr auto
7696 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7698 template<typename _Range>
7699 friend constexpr auto
7700 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7703 repeat_view() requires default_initializable<_Tp> = default;
7706 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7707 requires copy_constructible<_Tp>
7708 : _M_value(__value), _M_bound(__bound)
7710 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7711 __glibcxx_assert(__bound >= 0);
7715 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7716 : _M_value(std::move(__value)), _M_bound(__bound)
7719 template<typename... _Args, typename... _BoundArgs>
7720 requires constructible_from<_Tp, _Args...>
7721 && constructible_from<_Bound, _BoundArgs...>
7723 repeat_view(piecewise_construct_t,
7724 tuple<_Args...> __args,
7725 tuple<_BoundArgs...> __bound_args = tuple<>{})
7726 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7727 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7732 { return _Iterator(std::__addressof(*_M_value)); }
7735 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7736 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7738 constexpr unreachable_sentinel_t
7739 end() const noexcept
7740 { return unreachable_sentinel; }
7743 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7744 { return __detail::__to_unsigned_like(_M_bound); }
7747 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7748 // 4053. Unary call to std::views::repeat does not decay the argument
7749 template<typename _Tp, typename _Bound = unreachable_sentinel_t>
7750 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7752 template<move_constructible _Tp, semiregular _Bound>
7753 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7754 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7755 class repeat_view<_Tp, _Bound>::_Iterator
7758 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7760 const _Tp* _M_value = nullptr;
7761 __index_type _M_current = __index_type();
7764 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7765 : _M_value(__value), _M_current(__bound)
7767 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7768 __glibcxx_assert(__bound >= 0);
7774 using iterator_concept = random_access_iterator_tag;
7775 using iterator_category = random_access_iterator_tag;
7776 using value_type = _Tp;
7777 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7779 __detail::__iota_diff_t<__index_type>>;
7781 _Iterator() = default;
7783 constexpr const _Tp&
7784 operator*() const noexcept
7785 { return *_M_value; }
7787 constexpr _Iterator&
7802 constexpr _Iterator&
7805 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7806 __glibcxx_assert(_M_current > 0);
7819 constexpr _Iterator&
7820 operator+=(difference_type __n)
7822 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7823 __glibcxx_assert(_M_current + __n >= 0);
7828 constexpr _Iterator&
7829 operator-=(difference_type __n)
7831 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7832 __glibcxx_assert(_M_current - __n >= 0);
7837 constexpr const _Tp&
7838 operator[](difference_type __n) const noexcept
7839 { return *(*this + __n); }
7841 friend constexpr bool
7842 operator==(const _Iterator& __x, const _Iterator& __y)
7843 { return __x._M_current == __y._M_current; }
7845 friend constexpr auto
7846 operator<=>(const _Iterator& __x, const _Iterator& __y)
7847 { return __x._M_current <=> __y._M_current; }
7849 friend constexpr _Iterator
7850 operator+(_Iterator __i, difference_type __n)
7856 friend constexpr _Iterator
7857 operator+(difference_type __n, _Iterator __i)
7858 { return __i + __n; }
7860 friend constexpr _Iterator
7861 operator-(_Iterator __i, difference_type __n)
7867 friend constexpr difference_type
7868 operator-(const _Iterator& __x, const _Iterator& __y)
7870 return (static_cast<difference_type>(__x._M_current)
7871 - static_cast<difference_type>(__y._M_current));
7879 template<typename _Tp, typename _Bound>
7880 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7882 template<typename _Tp>
7883 concept __can_repeat_view
7884 = requires { repeat_view(std::declval<_Tp>()); };
7886 template<typename _Tp, typename _Bound>
7887 concept __can_bounded_repeat_view
7888 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7893 template<typename _Tp>
7894 requires __detail::__can_repeat_view<_Tp>
7896 operator() [[nodiscard]] (_Tp&& __value) const
7898 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7899 // 4054. Repeating a repeat_view should repeat the view
7900 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7903 template<typename _Tp, typename _Bound>
7904 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7906 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7907 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7910 inline constexpr _Repeat repeat;
7914 template<typename _Range>
7916 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7918 using _Tp = remove_cvref_t<_Range>;
7919 static_assert(__is_repeat_view<_Tp>);
7920 if constexpr (sized_range<_Tp>)
7921 return views::repeat(*std::forward<_Range>(__r)._M_value,
7922 std::min(ranges::distance(__r), __n));
7924 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7927 template<typename _Range>
7929 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7931 using _Tp = remove_cvref_t<_Range>;
7932 static_assert(__is_repeat_view<_Tp>);
7933 if constexpr (sized_range<_Tp>)
7935 auto __sz = ranges::distance(__r);
7936 return views::repeat(*std::forward<_Range>(__r)._M_value,
7937 __sz - std::min(__sz, __n));
7944#endif // __cpp_lib_ranges_repeat
7946#ifdef __cpp_lib_ranges_stride // C++ >= 23
7947 template<input_range _Vp>
7949 class stride_view : public view_interface<stride_view<_Vp>>
7952 range_difference_t<_Vp> _M_stride;
7954 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7956 template<bool _Const>
7960 template<bool _Const>
7961 requires forward_range<_Base<_Const>>
7962 struct __iter_cat<_Const>
7968 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7969 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7970 return random_access_iterator_tag{};
7975 using iterator_category = decltype(_S_iter_cat());
7978 template<bool> class _Iterator;
7982 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7983 : _M_base(std::move(__base)), _M_stride(__stride)
7984 { __glibcxx_assert(__stride > 0); }
7987 base() const& requires copy_constructible<_Vp>
7992 { return std::move(_M_base); }
7994 constexpr range_difference_t<_Vp>
7995 stride() const noexcept
7996 { return _M_stride; }
7999 begin() requires (!__detail::__simple_view<_Vp>)
8000 { return _Iterator<false>(this, ranges::begin(_M_base)); }
8003 begin() const requires range<const _Vp>
8004 { return _Iterator<true>(this, ranges::begin(_M_base)); }
8007 end() requires (!__detail::__simple_view<_Vp>)
8009 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8011 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8012 return _Iterator<false>(this, ranges::end(_M_base), __missing);
8014 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8015 return _Iterator<false>(this, ranges::end(_M_base));
8017 return default_sentinel;
8021 end() const requires range<const _Vp>
8023 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8024 && forward_range<const _Vp>)
8026 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8027 return _Iterator<true>(this, ranges::end(_M_base), __missing);
8029 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8030 return _Iterator<true>(this, ranges::end(_M_base));
8032 return default_sentinel;
8036 size() requires sized_range<_Vp>
8038 return __detail::__to_unsigned_like
8039 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8043 size() const requires sized_range<const _Vp>
8045 return __detail::__to_unsigned_like
8046 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8050 template<typename _Range>
8051 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8053 template<typename _Vp>
8054 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8055 = enable_borrowed_range<_Vp>;
8057 template<input_range _Vp>
8059 template<bool _Const>
8060 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8062 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8063 using _Base = stride_view::_Base<_Const>;
8065 iterator_t<_Base> _M_current = iterator_t<_Base>();
8066 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8067 range_difference_t<_Base> _M_stride = 0;
8068 range_difference_t<_Base> _M_missing = 0;
8071 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8072 range_difference_t<_Base> __missing = 0)
8073 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8074 _M_stride(__parent->_M_stride), _M_missing(__missing)
8080 if constexpr (random_access_range<_Base>)
8081 return random_access_iterator_tag{};
8082 else if constexpr (bidirectional_range<_Base>)
8083 return bidirectional_iterator_tag{};
8084 else if constexpr (forward_range<_Base>)
8085 return forward_iterator_tag{};
8087 return input_iterator_tag{};
8093 using difference_type = range_difference_t<_Base>;
8094 using value_type = range_value_t<_Base>;
8095 using iterator_concept = decltype(_S_iter_concept());
8096 // iterator_category defined in stride_view::__iter_cat
8098 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8101 _Iterator(_Iterator<!_Const> __other)
8103 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8104 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8105 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8106 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8109 constexpr iterator_t<_Base>
8111 { return std::move(_M_current); }
8113 constexpr const iterator_t<_Base>&
8114 base() const & noexcept
8115 { return _M_current; }
8117 constexpr decltype(auto)
8119 { return *_M_current; }
8121 constexpr _Iterator&
8124 __glibcxx_assert(_M_current != _M_end);
8125 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8134 operator++(int) requires forward_range<_Base>
8141 constexpr _Iterator&
8142 operator--() requires bidirectional_range<_Base>
8144 ranges::advance(_M_current, _M_missing - _M_stride);
8150 operator--(int) requires bidirectional_range<_Base>
8157 constexpr _Iterator&
8158 operator+=(difference_type __n) requires random_access_range<_Base>
8162 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8163 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8167 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8173 constexpr _Iterator&
8174 operator-=(difference_type __n) requires random_access_range<_Base>
8175 { return *this += -__n; }
8177 constexpr decltype(auto) operator[](difference_type __n) const
8178 requires random_access_range<_Base>
8179 { return *(*this + __n); }
8181 friend constexpr bool
8182 operator==(const _Iterator& __x, default_sentinel_t)
8183 { return __x._M_current == __x._M_end; }
8185 friend constexpr bool
8186 operator==(const _Iterator& __x, const _Iterator& __y)
8187 requires equality_comparable<iterator_t<_Base>>
8188 { return __x._M_current == __y._M_current; }
8190 friend constexpr bool
8191 operator<(const _Iterator& __x, const _Iterator& __y)
8192 requires random_access_range<_Base>
8193 { return __x._M_current < __y._M_current; }
8195 friend constexpr bool
8196 operator>(const _Iterator& __x, const _Iterator& __y)
8197 requires random_access_range<_Base>
8198 { return __y._M_current < __x._M_current; }
8200 friend constexpr bool
8201 operator<=(const _Iterator& __x, const _Iterator& __y)
8202 requires random_access_range<_Base>
8203 { return !(__y._M_current < __x._M_current); }
8205 friend constexpr bool
8206 operator>=(const _Iterator& __x, const _Iterator& __y)
8207 requires random_access_range<_Base>
8208 { return !(__x._M_current < __y._M_current); }
8210 friend constexpr auto
8211 operator<=>(const _Iterator& __x, const _Iterator& __y)
8212 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8213 { return __x._M_current <=> __y._M_current; }
8215 friend constexpr _Iterator
8216 operator+(const _Iterator& __i, difference_type __n)
8217 requires random_access_range<_Base>
8224 friend constexpr _Iterator
8225 operator+(difference_type __n, const _Iterator& __i)
8226 requires random_access_range<_Base>
8227 { return __i + __n; }
8229 friend constexpr _Iterator
8230 operator-(const _Iterator& __i, difference_type __n)
8231 requires random_access_range<_Base>
8238 friend constexpr difference_type
8239 operator-(const _Iterator& __x, const _Iterator& __y)
8240 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8242 auto __n = __x._M_current - __y._M_current;
8243 if constexpr (forward_range<_Base>)
8244 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8246 return -__detail::__div_ceil(-__n, __x._M_stride);
8248 return __detail::__div_ceil(__n, __x._M_stride);
8251 friend constexpr difference_type
8252 operator-(default_sentinel_t, const _Iterator& __x)
8253 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8254 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8256 friend constexpr difference_type
8257 operator-(const _Iterator& __x, default_sentinel_t __y)
8258 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8259 { return -(__y - __x); }
8261 friend constexpr range_rvalue_reference_t<_Base>
8262 iter_move(const _Iterator& __i)
8263 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8264 { return ranges::iter_move(__i._M_current); }
8266 friend constexpr void
8267 iter_swap(const _Iterator& __x, const _Iterator& __y)
8268 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8269 requires indirectly_swappable<iterator_t<_Base>>
8270 { ranges::iter_swap(__x._M_current, __y._M_current); }
8277 template<typename _Range, typename _Dp>
8278 concept __can_stride_view
8279 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8282 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8284 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8285 requires __detail::__can_stride_view<_Range, _Dp>
8287 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8288 { return stride_view(std::forward<_Range>(__r), __n); }
8290 using __adaptor::_RangeAdaptor<_Stride>::operator();
8291 static constexpr int _S_arity = 2;
8292 static constexpr bool _S_has_simple_extra_args = true;
8295 inline constexpr _Stride stride;
8297#endif // __cpp_lib_ranges_stride
8299#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8302 template<bool _Const, typename _First, typename... _Vs>
8303 concept __cartesian_product_is_random_access
8304 = (random_access_range<__maybe_const_t<_Const, _First>>
8306 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8307 && sized_range<__maybe_const_t<_Const, _Vs>>));
8309 template<typename _Range>
8310 concept __cartesian_product_common_arg
8311 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8313 template<bool _Const, typename _First, typename... _Vs>
8314 concept __cartesian_product_is_bidirectional
8315 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8317 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8318 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8320 template<typename _First, typename... _Vs>
8321 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8323 template<typename... _Vs>
8324 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8326 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8327 concept __cartesian_is_sized_sentinel
8328 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8329 iterator_t<__maybe_const_t<_Const, _First>>>
8331 && (sized_range<__maybe_const_t<_Const, _Vs>>
8332 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8333 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8335 template<__cartesian_product_common_arg _Range>
8337 __cartesian_common_arg_end(_Range& __r)
8339 if constexpr (common_range<_Range>)
8340 return ranges::end(__r);
8342 return ranges::begin(__r) + ranges::distance(__r);
8344 } // namespace __detail
8346 template<input_range _First, forward_range... _Vs>
8347 requires (view<_First> && ... && view<_Vs>)
8348 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8350 tuple<_First, _Vs...> _M_bases;
8352 template<bool> class _Iterator;
8355 _S_difference_type()
8357 // TODO: Implement the recommended practice of using the smallest
8358 // sufficiently wide type according to the maximum sizes of the
8359 // underlying ranges?
8360 return common_type_t<ptrdiff_t,
8361 range_difference_t<_First>,
8362 range_difference_t<_Vs>...>{};
8366 cartesian_product_view() = default;
8369 cartesian_product_view(_First __first, _Vs... __rest)
8370 : _M_bases(std::move(__first), std::move(__rest)...)
8373 constexpr _Iterator<false>
8374 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8375 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8377 constexpr _Iterator<true>
8378 begin() const requires (range<const _First> && ... && range<const _Vs>)
8379 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8381 constexpr _Iterator<false>
8382 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8383 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8385 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8386 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8387 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8388 auto& __first = std::get<0>(_M_bases);
8389 return _Ret{(__empty_tail
8390 ? ranges::begin(__first)
8391 : __detail::__cartesian_common_arg_end(__first)),
8392 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8393 }(make_index_sequence<sizeof...(_Vs)>{});
8395 return _Iterator<false>{*this, std::move(__its)};
8398 constexpr _Iterator<true>
8399 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8401 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8402 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8403 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8404 auto& __first = std::get<0>(_M_bases);
8405 return _Ret{(__empty_tail
8406 ? ranges::begin(__first)
8407 : __detail::__cartesian_common_arg_end(__first)),
8408 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8409 }(make_index_sequence<sizeof...(_Vs)>{});
8411 return _Iterator<true>{*this, std::move(__its)};
8414 constexpr default_sentinel_t
8415 end() const noexcept
8416 { return default_sentinel; }
8419 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8421 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8422 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8423 auto __size = static_cast<_ST>(1);
8424#ifdef _GLIBCXX_ASSERTIONS
8425 if constexpr (integral<_ST>)
8428 = (__builtin_mul_overflow(__size,
8429 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8432 __glibcxx_assert(!__overflow);
8436 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8438 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8442 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8444 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8445 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8446 auto __size = static_cast<_ST>(1);
8447#ifdef _GLIBCXX_ASSERTIONS
8448 if constexpr (integral<_ST>)
8451 = (__builtin_mul_overflow(__size,
8452 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8455 __glibcxx_assert(!__overflow);
8459 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8461 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8465 template<typename... _Vs>
8466 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8468 template<input_range _First, forward_range... _Vs>
8469 requires (view<_First> && ... && view<_Vs>)
8470 template<bool _Const>
8471 class cartesian_product_view<_First, _Vs...>::_Iterator
8473 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8474 _Parent* _M_parent = nullptr;
8475 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8476 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8479 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8480 : _M_parent(std::__addressof(__parent)),
8481 _M_current(std::move(__current))
8487 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8488 return random_access_iterator_tag{};
8489 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8490 return bidirectional_iterator_tag{};
8491 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8492 return forward_iterator_tag{};
8494 return input_iterator_tag{};
8497 friend cartesian_product_view;
8500 using iterator_category = input_iterator_tag;
8501 using iterator_concept = decltype(_S_iter_concept());
8503 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8504 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8506 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8507 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8508 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8510 _Iterator() = default;
8513 _Iterator(_Iterator<!_Const> __i)
8515 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8516 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8517 : _M_parent(std::__addressof(__i._M_parent)),
8518 _M_current(std::move(__i._M_current))
8524 auto __f = [](auto& __i) -> decltype(auto) {
8527 return __detail::__tuple_transform(__f, _M_current);
8530 constexpr _Iterator&
8542 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8549 constexpr _Iterator&
8551 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8559 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8566 constexpr _Iterator&
8567 operator+=(difference_type __x)
8568 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8574 constexpr _Iterator&
8575 operator-=(difference_type __x)
8576 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8577 { return *this += -__x; }
8580 operator[](difference_type __n) const
8581 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8582 { return *((*this) + __n); }
8584 friend constexpr bool
8585 operator==(const _Iterator& __x, const _Iterator& __y)
8586 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8587 { return __x._M_current == __y._M_current; }
8589 friend constexpr bool
8590 operator==(const _Iterator& __x, default_sentinel_t)
8592 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8593 return ((std::get<_Is>(__x._M_current)
8594 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8596 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8599 friend constexpr auto
8600 operator<=>(const _Iterator& __x, const _Iterator& __y)
8601 requires __detail::__all_random_access<_Const, _First, _Vs...>
8602 { return __x._M_current <=> __y._M_current; }
8604 friend constexpr _Iterator
8605 operator+(_Iterator __x, difference_type __y)
8606 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8607 { return __x += __y; }
8609 friend constexpr _Iterator
8610 operator+(difference_type __x, _Iterator __y)
8611 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8612 { return __y += __x; }
8614 friend constexpr _Iterator
8615 operator-(_Iterator __x, difference_type __y)
8616 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8617 { return __x -= __y; }
8619 friend constexpr difference_type
8620 operator-(const _Iterator& __x, const _Iterator& __y)
8621 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8622 { return __x._M_distance_from(__y._M_current); }
8624 friend constexpr difference_type
8625 operator-(const _Iterator& __i, default_sentinel_t)
8626 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8628 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8629 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8630 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8631 }(make_index_sequence<sizeof...(_Vs)>{});
8632 return __i._M_distance_from(__end_tuple);
8635 friend constexpr difference_type
8636 operator-(default_sentinel_t, const _Iterator& __i)
8637 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8638 { return -(__i - default_sentinel); }
8640 friend constexpr auto
8641 iter_move(const _Iterator& __i)
8642 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8644 friend constexpr void
8645 iter_swap(const _Iterator& __l, const _Iterator& __r)
8646 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8648 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8650 [&]<size_t... _Is>(index_sequence<_Is...>) {
8651 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8652 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8656 template<size_t _Nm = sizeof...(_Vs)>
8660 auto& __it = std::get<_Nm>(_M_current);
8662 if constexpr (_Nm > 0)
8663 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8665 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8670 template<size_t _Nm = sizeof...(_Vs)>
8674 auto& __it = std::get<_Nm>(_M_current);
8675 if constexpr (_Nm > 0)
8676 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8678 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8684 template<size_t _Nm = sizeof...(_Vs)>
8686 _M_advance(difference_type __x)
8687 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8695 // Constant time iterator advancement.
8696 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8697 auto& __it = std::get<_Nm>(_M_current);
8698 if constexpr (_Nm == 0)
8700#ifdef _GLIBCXX_ASSERTIONS
8701 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8703 auto __size = ranges::ssize(__r);
8704 auto __begin = ranges::begin(__r);
8705 auto __offset = __it - __begin;
8706 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8713 auto __size = ranges::ssize(__r);
8714 auto __begin = ranges::begin(__r);
8715 auto __offset = __it - __begin;
8717 __x = __offset / __size;
8721 __offset = __size + __offset;
8724 __it = __begin + __offset;
8725 _M_advance<_Nm - 1>(__x);
8730 template<typename _Tuple>
8731 constexpr difference_type
8732 _M_distance_from(const _Tuple& __t) const
8734 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8735 auto __sum = static_cast<difference_type>(0);
8736#ifdef _GLIBCXX_ASSERTIONS
8737 if constexpr (integral<difference_type>)
8740 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8742 __glibcxx_assert(!__overflow);
8746 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8748 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8751 template<size_t _Nm, typename _Tuple>
8752 constexpr difference_type
8753 _M_scaled_distance(const _Tuple& __t) const
8755 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8756 - std::get<_Nm>(__t));
8757#ifdef _GLIBCXX_ASSERTIONS
8758 if constexpr (integral<difference_type>)
8760 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8761 __glibcxx_assert(!__overflow);
8765 __dist *= _M_scaled_size<_Nm+1>();
8769 template<size_t _Nm>
8770 constexpr difference_type
8771 _M_scaled_size() const
8773 if constexpr (_Nm <= sizeof...(_Vs))
8775 auto __size = static_cast<difference_type>(ranges::size
8776 (std::get<_Nm>(_M_parent->_M_bases)));
8777#ifdef _GLIBCXX_ASSERTIONS
8778 if constexpr (integral<difference_type>)
8780 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8781 __glibcxx_assert(!__overflow);
8785 __size *= _M_scaled_size<_Nm+1>();
8789 return static_cast<difference_type>(1);
8797 template<typename... _Ts>
8798 concept __can_cartesian_product_view
8799 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8802 struct _CartesianProduct
8804 template<typename... _Ts>
8805 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8807 operator() [[nodiscard]] (_Ts&&... __ts) const
8809 if constexpr (sizeof...(_Ts) == 0)
8810 return views::single(tuple{});
8812 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8816 inline constexpr _CartesianProduct cartesian_product;
8818#endif // __cpp_lib_ranges_cartesian_product
8820#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8821 template<input_range _Vp>
8823 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8825 _Vp _M_base = _Vp();
8828 as_rvalue_view() requires default_initializable<_Vp> = default;
8831 as_rvalue_view(_Vp __base)
8832 : _M_base(std::move(__base))
8836 base() const& requires copy_constructible<_Vp>
8841 { return std::move(_M_base); }
8844 begin() requires (!__detail::__simple_view<_Vp>)
8845 { return move_iterator(ranges::begin(_M_base)); }
8848 begin() const requires range<const _Vp>
8849 { return move_iterator(ranges::begin(_M_base)); }
8852 end() requires (!__detail::__simple_view<_Vp>)
8854 if constexpr (common_range<_Vp>)
8855 return move_iterator(ranges::end(_M_base));
8857 return move_sentinel(ranges::end(_M_base));
8861 end() const requires range<const _Vp>
8863 if constexpr (common_range<const _Vp>)
8864 return move_iterator(ranges::end(_M_base));
8866 return move_sentinel(ranges::end(_M_base));
8870 size() requires sized_range<_Vp>
8871 { return ranges::size(_M_base); }
8874 size() const requires sized_range<const _Vp>
8875 { return ranges::size(_M_base); }
8878 template<typename _Range>
8879 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8881 template<typename _Tp>
8882 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8883 = enable_borrowed_range<_Tp>;
8889 template<typename _Tp>
8890 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8893 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8895 template<viewable_range _Range>
8896 requires __detail::__can_as_rvalue_view<_Range>
8898 operator() [[nodiscard]] (_Range&& __r) const
8900 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8901 range_reference_t<_Range>>)
8902 return views::all(std::forward<_Range>(__r));
8904 return as_rvalue_view(std::forward<_Range>(__r));
8908 inline constexpr _AsRvalue as_rvalue;
8910#endif // __cpp_lib_as_rvalue
8912#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8915 template<typename _Range>
8916 concept __range_with_movable_reference = input_range<_Range>
8917 && move_constructible<range_reference_t<_Range>>
8918 && move_constructible<range_rvalue_reference_t<_Range>>;
8922 requires __detail::__range_with_movable_reference<_Vp>
8923 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8925 _Vp _M_base = _Vp();
8927 template<bool _Const> class _Iterator;
8928 template<bool _Const> class _Sentinel;
8931 enumerate_view() requires default_initializable<_Vp> = default;
8934 enumerate_view(_Vp __base)
8935 : _M_base(std::move(__base))
8939 begin() requires (!__detail::__simple_view<_Vp>)
8940 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8943 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8944 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8947 end() requires (!__detail::__simple_view<_Vp>)
8949 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8950 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8952 return _Sentinel<false>(ranges::end(_M_base));
8956 end() const requires __detail::__range_with_movable_reference<const _Vp>
8958 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8959 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8961 return _Sentinel<true>(ranges::end(_M_base));
8965 size() requires sized_range<_Vp>
8966 { return ranges::size(_M_base); }
8969 size() const requires sized_range<const _Vp>
8970 { return ranges::size(_M_base); }
8973 base() const & requires copy_constructible<_Vp>
8978 { return std::move(_M_base); }
8981 template<typename _Range>
8982 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
8984 template<typename _Tp>
8985 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
8986 = enable_borrowed_range<_Tp>;
8989 requires __detail::__range_with_movable_reference<_Vp>
8990 template<bool _Const>
8991 class enumerate_view<_Vp>::_Iterator
8993 using _Base = __maybe_const_t<_Const, _Vp>;
8998 if constexpr (random_access_range<_Base>)
8999 return random_access_iterator_tag{};
9000 else if constexpr (bidirectional_range<_Base>)
9001 return bidirectional_iterator_tag{};
9002 else if constexpr (forward_range<_Base>)
9003 return forward_iterator_tag{};
9005 return input_iterator_tag{};
9008 friend enumerate_view;
9011 using iterator_category = input_iterator_tag;
9012 using iterator_concept = decltype(_S_iter_concept());
9013 using difference_type = range_difference_t<_Base>;
9014 using value_type = tuple<difference_type, range_value_t<_Base>>;
9017 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9019 iterator_t<_Base> _M_current = iterator_t<_Base>();
9020 difference_type _M_pos = 0;
9023 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9024 : _M_current(std::move(__current)), _M_pos(__pos)
9028 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
9031 _Iterator(_Iterator<!_Const> __i)
9032 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9033 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9036 constexpr const iterator_t<_Base> &
9037 base() const & noexcept
9038 { return _M_current; }
9040 constexpr iterator_t<_Base>
9042 { return std::move(_M_current); }
9044 constexpr difference_type
9045 index() const noexcept
9050 { return __reference_type(_M_pos, *_M_current); }
9052 constexpr _Iterator&
9065 operator++(int) requires forward_range<_Base>
9072 constexpr _Iterator&
9073 operator--() requires bidirectional_range<_Base>
9081 operator--(int) requires bidirectional_range<_Base>
9088 constexpr _Iterator&
9089 operator+=(difference_type __n) requires random_access_range<_Base>
9096 constexpr _Iterator&
9097 operator-=(difference_type __n) requires random_access_range<_Base>
9105 operator[](difference_type __n) const requires random_access_range<_Base>
9106 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9108 friend constexpr bool
9109 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9110 { return __x._M_pos == __y._M_pos; }
9112 friend constexpr strong_ordering
9113 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9114 { return __x._M_pos <=> __y._M_pos; }
9116 friend constexpr _Iterator
9117 operator+(const _Iterator& __x, difference_type __y)
9118 requires random_access_range<_Base>
9119 { return (auto(__x) += __y); }
9121 friend constexpr _Iterator
9122 operator+(difference_type __x, const _Iterator& __y)
9123 requires random_access_range<_Base>
9124 { return auto(__y) += __x; }
9126 friend constexpr _Iterator
9127 operator-(const _Iterator& __x, difference_type __y)
9128 requires random_access_range<_Base>
9129 { return auto(__x) -= __y; }
9131 friend constexpr difference_type
9132 operator-(const _Iterator& __x, const _Iterator& __y) noexcept
9133 { return __x._M_pos - __y._M_pos; }
9135 friend constexpr auto
9136 iter_move(const _Iterator& __i)
9137 noexcept(noexcept(ranges::iter_move(__i._M_current))
9138 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9140 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9141 (__i._M_pos, ranges::iter_move(__i._M_current));
9146 requires __detail::__range_with_movable_reference<_Vp>
9147 template<bool _Const>
9148 class enumerate_view<_Vp>::_Sentinel
9150 using _Base = __maybe_const_t<_Const, _Vp>;
9152 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9155 _Sentinel(sentinel_t<_Base> __end)
9156 : _M_end(std::move(__end))
9159 friend enumerate_view;
9162 _Sentinel() = default;
9165 _Sentinel(_Sentinel<!_Const> __other)
9166 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9167 : _M_end(std::move(__other._M_end))
9170 constexpr sentinel_t<_Base>
9174 template<bool _OtherConst>
9175 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9176 friend constexpr bool
9177 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9178 { return __x._M_current == __y._M_end; }
9180 template<bool _OtherConst>
9181 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9182 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9183 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9184 { return __x._M_current - __y._M_end; }
9186 template<bool _OtherConst>
9187 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9188 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9189 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9190 { return __x._M_end - __y._M_current; }
9197 template<typename _Tp>
9198 concept __can_enumerate_view
9199 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9202 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9204 template<viewable_range _Range>
9205 requires __detail::__can_enumerate_view<_Range>
9207 operator() [[nodiscard]] (_Range&& __r) const
9208 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9211 inline constexpr _Enumerate enumerate;
9213#endif // __cpp_lib_ranges_enumerate
9215#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9217 requires input_range<_Vp>
9218 class as_const_view : public view_interface<as_const_view<_Vp>>
9220 _Vp _M_base = _Vp();
9223 as_const_view() requires default_initializable<_Vp> = default;
9226 as_const_view(_Vp __base)
9227 noexcept(is_nothrow_move_constructible_v<_Vp>)
9228 : _M_base(std::move(__base))
9233 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9234 requires copy_constructible<_Vp>
9239 noexcept(is_nothrow_move_constructible_v<_Vp>)
9240 { return std::move(_M_base); }
9243 begin() requires (!__detail::__simple_view<_Vp>)
9244 { return ranges::cbegin(_M_base); }
9247 begin() const requires range<const _Vp>
9248 { return ranges::cbegin(_M_base); }
9251 end() requires (!__detail::__simple_view<_Vp>)
9252 { return ranges::cend(_M_base); }
9255 end() const requires range<const _Vp>
9256 { return ranges::cend(_M_base); }
9259 size() requires sized_range<_Vp>
9260 { return ranges::size(_M_base); }
9263 size() const requires sized_range<const _Vp>
9264 { return ranges::size(_M_base); }
9267 template<typename _Range>
9268 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9270 template<typename _Tp>
9271 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9272 = enable_borrowed_range<_Tp>;
9278 template<typename _Tp>
9279 inline constexpr bool __is_constable_ref_view = false;
9281 template<typename _Range>
9282 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9283 = constant_range<const _Range>;
9285 template<typename _Range>
9286 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9289 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9291 template<viewable_range _Range>
9293 operator()(_Range&& __r) const
9294 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9295 requires __detail::__can_as_const_view<_Range>
9297 using _Tp = remove_cvref_t<_Range>;
9298 using element_type = remove_reference_t<range_reference_t<_Range>>;
9299 if constexpr (constant_range<views::all_t<_Range>>)
9300 return views::all(std::forward<_Range>(__r));
9301 else if constexpr (__detail::__is_empty_view<_Tp>)
9302 return views::empty<const element_type>;
9303 else if constexpr (std::__detail::__is_span<_Tp>)
9304 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9305 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9306 return ref_view(std::as_const(std::forward<_Range>(__r).base()));
9307 else if constexpr (is_lvalue_reference_v<_Range>
9308 && constant_range<const _Tp>
9310 return ref_view(static_cast<const _Tp&>(__r));
9312 return as_const_view(std::forward<_Range>(__r));
9316 inline constexpr _AsConst as_const;
9318#endif // __cpp_lib_as_const
9319} // namespace ranges
9321 namespace views = ranges::views;
9323#if __cpp_lib_ranges_to_container // C++ >= 23
9326/// @cond undocumented
9329 template<typename _Container>
9330 constexpr bool __reservable_container
9331 = sized_range<_Container>
9332 && requires(_Container& __c, range_size_t<_Container> __n) {
9334 { __c.capacity() } -> same_as<decltype(__n)>;
9335 { __c.max_size() } -> same_as<decltype(__n)>;
9338 template<typename _Cont, typename _Range>
9339 constexpr bool __toable = requires {
9340 requires (!input_range<_Cont>
9341 || convertible_to<range_reference_t<_Range>,
9342 range_value_t<_Cont>>);
9344} // namespace __detail
9347 /// Convert a range to a container.
9349 * @tparam _Cont A container type.
9350 * @param __r A range that models the `input_range` concept.
9351 * @param __args... Arguments to pass to the container constructor.
9354 * This function converts a range to the `_Cont` type.
9356 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9357 * will convert the view to `std::vector<int>`.
9359 * Additional constructor arguments for the container can be supplied after
9360 * the input range argument, e.g.
9361 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9363 template<typename _Cont, input_range _Rg, typename... _Args>
9364 requires (!view<_Cont>)
9366 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9368 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9369 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9371 if constexpr (__detail::__toable<_Cont, _Rg>)
9373 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9374 return _Cont(std::forward<_Rg>(__r),
9375 std::forward<_Args>(__args)...);
9376 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9377 return _Cont(from_range, std::forward<_Rg>(__r),
9378 std::forward<_Args>(__args)...);
9379 else if constexpr (requires { requires common_range<_Rg>;
9380 typename __iter_category_t<iterator_t<_Rg>>;
9381 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9382 input_iterator_tag>;
9383 requires constructible_from<_Cont, iterator_t<_Rg>,
9384 sentinel_t<_Rg>, _Args...>;
9386 return _Cont(ranges::begin(__r), ranges::end(__r),
9387 std::forward<_Args>(__args)...);
9390 static_assert(constructible_from<_Cont, _Args...>);
9391 _Cont __c(std::forward<_Args>(__args)...);
9392 if constexpr (sized_range<_Rg>
9393 && __detail::__reservable_container<_Cont>)
9394 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9395 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9396 // 4016. container-insertable checks do not match what
9397 // container-inserter does
9398 auto __it = ranges::begin(__r);
9399 const auto __sent = ranges::end(__r);
9400 while (__it != __sent)
9402 if constexpr (requires { __c.emplace_back(*__it); })
9403 __c.emplace_back(*__it);
9404 else if constexpr (requires { __c.push_back(*__it); })
9405 __c.push_back(*__it);
9406 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9407 __c.emplace(__c.end(), *__it);
9409 __c.insert(__c.end(), *__it);
9417 static_assert(input_range<range_reference_t<_Rg>>);
9418 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9419 // 3984. ranges::to's recursion branch may be ill-formed
9420 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9421 []<typename _Elt>(_Elt&& __elem) {
9422 using _ValT = range_value_t<_Cont>;
9423 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9424 }), std::forward<_Args>(__args)...);
9428/// @cond undocumented
9431 template<typename _Rg>
9434 using iterator_category = input_iterator_tag;
9435 using value_type = range_value_t<_Rg>;
9436 using difference_type = ptrdiff_t;
9437 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9438 using reference = range_reference_t<_Rg>;
9439 reference operator*() const;
9440 pointer operator->() const;
9441 _InputIter& operator++();
9442 _InputIter operator++(int);
9443 bool operator==(const _InputIter&) const;
9446 template<template<typename...> typename _Cont, input_range _Rg,
9449 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9451 template<template<typename...> typename _Cont, input_range _Rg,
9454 = decltype(_Cont(from_range, std::declval<_Rg>(),
9455 std::declval<_Args>()...));
9457 template<template<typename...> typename _Cont, input_range _Rg,
9460 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9461 std::declval<_InputIter<_Rg>>(),
9462 std::declval<_Args>()...));
9464} // namespace __detail
9467 template<template<typename...> typename _Cont, input_range _Rg,
9470 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9472 using __detail::_DeduceExpr1;
9473 using __detail::_DeduceExpr2;
9474 using __detail::_DeduceExpr3;
9475 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9476 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9477 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9478 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9479 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9480 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9481 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9482 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9483 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9485 static_assert(false); // Cannot deduce container specialization.
9488/// @cond undocumented
9491 template<typename _Cont>
9494 template<typename _Range, typename... _Args>
9495 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9496 std::declval<_Args>()...); }
9498 operator()(_Range&& __r, _Args&&... __args) const
9500 return ranges::to<_Cont>(std::forward<_Range>(__r),
9501 std::forward<_Args>(__args)...);
9504} // namespace __detail
9507 /// ranges::to adaptor for converting a range to a container type
9509 * @tparam _Cont A container type.
9510 * @param __args... Arguments to pass to the container constructor.
9513 * This range adaptor returns a range adaptor closure object that converts
9514 * a range to the `_Cont` type.
9516 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9517 * will convert the view to `std::vector<int>`.
9519 * Additional constructor arguments for the container can be supplied, e.g.
9520 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9522 template<typename _Cont, typename... _Args>
9523 requires (!view<_Cont>)
9525 to [[nodiscard]] (_Args&&... __args)
9527 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9528 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9530 using __detail::_To;
9531 using views::__adaptor::_Partial;
9532 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9535/// @cond undocumented
9538 template<template<typename...> typename _Cont>
9541 template<typename _Range, typename... _Args>
9542 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9543 std::declval<_Args>()...); }
9545 operator()(_Range&& __r, _Args&&... __args) const
9547 return ranges::to<_Cont>(std::forward<_Range>(__r),
9548 std::forward<_Args>(__args)...);
9551} // namespace __detail
9554 /// ranges::to adaptor for converting a range to a deduced container type.
9556 * @tparam _Cont A container template.
9557 * @param __args... Arguments to pass to the container constructor.
9560 * This range adaptor returns a range adaptor closure object that converts
9561 * a range to a specialization of the `_Cont` class template. The specific
9562 * specialization of `_Cont` to be used is deduced automatically.
9564 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9565 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9566 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9568 * Additional constructor arguments for the container can be supplied, e.g.
9569 * `r | std::ranges::to<std::vector>(an_allocator)`.
9571 template<template<typename...> typename _Cont, typename... _Args>
9573 to [[nodiscard]] (_Args&&... __args)
9575 using __detail::_To2;
9576 using views::__adaptor::_Partial;
9577 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9580} // namespace ranges
9581#endif // __cpp_lib_ranges_to_container
9583#if __cpp_lib_ranges_concat // C++ >= C++26
9588 template<typename... _Rs>
9589 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9591 template<typename... _Rs>
9592 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9594 template<typename... _Rs>
9595 using __concat_rvalue_reference_t
9596 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9598 template<typename _Ref, typename _RRef, typename _It>
9599 concept __concat_indirectly_readable_impl = requires(const _It __it) {
9600 { *__it } -> convertible_to<_Ref>;
9601 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9604 template<typename... _Rs>
9605 concept __concat_indirectly_readable
9606 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9607 && common_reference_with<__concat_reference_t<_Rs...>&&,
9608 __concat_rvalue_reference_t<_Rs...>&&>
9609 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9610 __concat_value_t<_Rs...> const&>
9611 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9612 __concat_rvalue_reference_t<_Rs...>,
9616 template<typename... _Rs>
9617 concept __concatable = requires {
9618 typename __concat_reference_t<_Rs...>;
9619 typename __concat_value_t<_Rs...>;
9620 typename __concat_rvalue_reference_t<_Rs...>;
9621 } && __concat_indirectly_readable<_Rs...>;
9623 template<bool _Const, typename _Range, typename... _Rs>
9624 struct __all_but_last_common
9626 static inline constexpr bool value
9627 = requires { requires (common_range<__maybe_const_t<_Const, _Range>>
9628 && __all_but_last_common<_Const, _Rs...>::value); };
9631 template<bool _Const, typename _Range>
9632 struct __all_but_last_common<_Const, _Range>
9633 { static inline constexpr bool value = true; };
9635 template<bool _Const, typename... _Rs>
9636 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9637 && __all_but_last_common<_Const, _Rs...>::value;
9639 template<bool _Const, typename... _Rs>
9640 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9641 && __all_but_last_common<_Const, _Rs...>::value;
9643 template<typename _Range, typename... _Rs>
9644 struct __all_but_first_sized
9645 { static inline constexpr bool value = (sized_range<_Rs> && ...); };
9646 } // namespace __detail
9648 template<input_range... _Vs>
9649 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9650 class concat_view : public view_interface<concat_view<_Vs...>>
9652 tuple<_Vs...> _M_views;
9654 template<bool _Const> class _Iterator;
9657 constexpr concat_view() = default;
9660 concat_view(_Vs... __views)
9661 : _M_views(std::move(__views)...)
9664 constexpr _Iterator<false>
9665 begin() requires (!(__detail::__simple_view<_Vs> && ...))
9667 _Iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9668 __it.template _M_satisfy<0>();
9672 constexpr _Iterator<true>
9673 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9675 _Iterator<true> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9676 __it.template _M_satisfy<0>();
9681 end() requires (!(__detail::__simple_view<_Vs> && ...))
9683 constexpr auto __n = sizeof...(_Vs);
9684 if constexpr (__detail::__all_forward<false, _Vs...>
9685 && common_range<_Vs...[__n - 1]>)
9686 return _Iterator<false>(this, in_place_index<__n - 1>,
9687 ranges::end(std::get<__n - 1>(_M_views)));
9689 return default_sentinel;
9693 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9695 constexpr auto __n = sizeof...(_Vs);
9696 if constexpr (__detail::__all_forward<true, _Vs...>
9697 && common_range<const _Vs...[__n - 1]>)
9698 return _Iterator<true>(this, in_place_index<__n - 1>,
9699 ranges::end(std::get<__n - 1>(_M_views)));
9701 return default_sentinel;
9705 size() requires (sized_range<_Vs>&&...)
9707 return std::apply([](auto... __sizes) {
9708 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9709 return (_CT(__sizes) + ...);
9710 }, __detail::__tuple_transform(ranges::size, _M_views));
9714 size() const requires (sized_range<const _Vs>&&...)
9716 return std::apply([](auto... __sizes) {
9717 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9718 return (_CT(__sizes) + ...);
9719 }, __detail::__tuple_transform(ranges::size, _M_views));
9723 template<typename... _Rs>
9724 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9728 template<bool _Const, typename... _Vs>
9729 struct __concat_view_iter_cat
9732 template<bool _Const, typename... _Vs>
9733 requires __detail::__all_forward<_Const, _Vs...>
9734 struct __concat_view_iter_cat<_Const, _Vs...>
9739 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9740 return input_iterator_tag{};
9742 return []<typename... _Cats>(_Cats... __cats) {
9743 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9744 && __concat_is_random_access<_Const, _Vs...>)
9745 return random_access_iterator_tag{};
9746 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9747 && __concat_is_bidirectional<_Const, _Vs...>)
9748 return bidirectional_iterator_tag{};
9749 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9750 return forward_iterator_tag{};
9752 return input_iterator_tag{};
9753 }(typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9754 ::iterator_category{}...);
9759 template<input_range... _Vs>
9760 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9761 template<bool _Const>
9762 class concat_view<_Vs...>::_Iterator
9763 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9768 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9769 return random_access_iterator_tag{};
9770 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9771 return bidirectional_iterator_tag{};
9772 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9773 return forward_iterator_tag{};
9775 return input_iterator_tag{};
9779 friend _Iterator<!_Const>;
9782 // iterator_category defined in __concat_view_iter_cat
9783 using iterator_concept = decltype(_S_iter_concept());
9784 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9785 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9788 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9790 __maybe_const_t<_Const, concat_view>* _M_parent = nullptr;
9793 template<size_t _Nm>
9797 if constexpr (_Nm < (sizeof...(_Vs) - 1))
9799 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9801 _M_it.template emplace<_Nm + 1>(ranges::begin
9802 (std::get<_Nm + 1>(_M_parent->_M_views)));
9803 _M_satisfy<_Nm + 1>();
9808 template<size_t _Nm>
9812 if constexpr (_Nm == 0)
9813 --std::get<0>(_M_it);
9816 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
9818 _M_it.template emplace<_Nm - 1>(ranges::end
9819 (std::get<_Nm - 1>(_M_parent->_M_views)));
9823 --std::get<_Nm>(_M_it);
9827 template<size_t _Nm>
9829 _M_advance_fwd(difference_type __offset, difference_type __steps)
9831 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9832 if constexpr (_Nm == sizeof...(_Vs) - 1)
9833 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9836 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
9837 if (__offset + __steps < __n_size)
9838 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9841 _M_it.template emplace<_Nm + 1>(ranges::begin
9842 (std::get<_Nm + 1>(_M_parent->_M_views)));
9843 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
9848 template<size_t _Nm>
9850 _M_advance_bwd(difference_type __offset, difference_type __steps)
9852 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9853 if constexpr (_Nm == 0)
9854 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9856 if (__offset >= __steps)
9857 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9860 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
9861 _M_it.template emplace<_Nm - 1>(ranges::end
9862 (std::get<_Nm - 1>(_M_parent->_M_views)));
9863 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
9868 // Invoke the function object __f, which has a call operator with a size_t
9869 // template parameter (corresponding to an index into the pack of views),
9870 // using the runtime value of __index as the template argument.
9871 template<typename _Fp>
9872 static constexpr auto
9873 _S_invoke_with_runtime_index(_Fp&& __f, size_t __index)
9875 return [&__f, __index]<size_t _Idx>(this auto&& __self) {
9876 if (_Idx == __index)
9877 return __f.template operator()<_Idx>();
9878 if constexpr (_Idx + 1 < sizeof...(_Vs))
9879 return __self.template operator()<_Idx + 1>();
9880 __builtin_unreachable();
9881 }.template operator()<0>();
9884 template<typename _Fp>
9886 _M_invoke_with_runtime_index(_Fp&& __f)
9887 { return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); }
9889 template<typename... _Args>
9891 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
9892 requires constructible_from<__base_iter, _Args&&...>
9893 : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...)
9897 _Iterator() = default;
9900 _Iterator(_Iterator<!_Const> __it)
9901 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
9902 : _M_parent(__it._M_parent),
9903 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
9904 return __base_iter(in_place_index<_Idx>,
9905 std::get<_Idx>(std::move(__it._M_it)));
9906 }, __it._M_it.index()))
9909 constexpr decltype(auto)
9912 __glibcxx_assert(!_M_it.valueless_by_exception());
9913 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
9914 return std::visit([](auto&& __it) -> reference { return *__it; }, _M_it);
9917 constexpr _Iterator&
9920 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9921 ++std::get<_Idx>(_M_it);
9933 requires __detail::__all_forward<_Const, _Vs...>
9940 constexpr _Iterator&
9942 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9944 __glibcxx_assert(!_M_it.valueless_by_exception());
9945 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9953 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9960 constexpr _Iterator&
9961 operator+=(difference_type __n)
9962 requires __detail::__concat_is_random_access<_Const, _Vs...>
9964 __glibcxx_assert(!_M_it.valueless_by_exception());
9965 _M_invoke_with_runtime_index([this, __n]<size_t _Idx>() {
9966 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
9968 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
9970 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
9975 constexpr _Iterator&
9976 operator-=(difference_type __n)
9977 requires __detail::__concat_is_random_access<_Const, _Vs...>
9983 constexpr decltype(auto)
9984 operator[](difference_type __n) const
9985 requires __detail::__concat_is_random_access<_Const, _Vs...>
9986 { return *((*this) + __n); }
9988 friend constexpr bool
9989 operator==(const _Iterator& __x, const _Iterator& __y)
9990 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
9992 __glibcxx_assert(!__x._M_it.valueless_by_exception());
9993 __glibcxx_assert(!__y._M_it.valueless_by_exception());
9994 return __x._M_it == __y._M_it;
9997 friend constexpr bool
9998 operator==(const _Iterator& __it, default_sentinel_t)
10000 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10001 constexpr auto __last_idx = sizeof...(_Vs) - 1;
10002 return (__it._M_it.index() == __last_idx
10003 && (std::get<__last_idx>(__it._M_it)
10004 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10007 friend constexpr bool
10008 operator<(const _Iterator& __x, const _Iterator& __y)
10009 requires __detail::__all_random_access<_Const, _Vs...>
10010 { return __x._M_it < __y._M_it; }
10012 friend constexpr bool
10013 operator>(const _Iterator& __x, const _Iterator& __y)
10014 requires __detail::__all_random_access<_Const, _Vs...>
10015 { return __x._M_it > __y._M_it; }
10017 friend constexpr bool
10018 operator<=(const _Iterator& __x, const _Iterator& __y)
10019 requires __detail::__all_random_access<_Const, _Vs...>
10020 { return __x._M_it <= __y._M_it; }
10022 friend constexpr bool
10023 operator>=(const _Iterator& __x, const _Iterator& __y)
10024 requires __detail::__all_random_access<_Const, _Vs...>
10025 { return __x._M_it >= __y._M_it; }
10027 friend constexpr auto
10028 operator<=>(const _Iterator& __x, const _Iterator& __y)
10029 requires __detail::__all_random_access<_Const, _Vs...>
10030 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10031 { return __x._M_it <=> __y._M_it; }
10033 friend constexpr _Iterator
10034 operator+(const _Iterator& __it, difference_type __n)
10035 requires __detail::__concat_is_random_access<_Const, _Vs...>
10036 { return auto(__it) += __n; }
10038 friend constexpr _Iterator
10039 operator+(difference_type __n, const _Iterator& __it)
10040 requires __detail::__concat_is_random_access<_Const, _Vs...>
10041 { return __it + __n; }
10043 friend constexpr _Iterator
10044 operator-(const _Iterator& __it, difference_type __n)
10045 requires __detail::__concat_is_random_access<_Const, _Vs...>
10046 { return auto(__it) -= __n; }
10048 friend constexpr difference_type
10049 operator-(const _Iterator& __x, const _Iterator& __y)
10050 requires __detail::__concat_is_random_access<_Const, _Vs...>
10052 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10053 return _S_invoke_with_runtime_index([&]<size_t _Iy>() -> difference_type {
10054 if constexpr (_Ix > _Iy)
10056 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10057 ranges::end(std::get<_Iy>(__y._M_parent
10059 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10061 std::get<_Ix>(__x._M_it));
10062 difference_type __s = 0;
10063 [&]<size_t _Idx = _Iy + 1>(this auto&& __self) {
10064 if constexpr (_Idx < _Ix)
10066 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10067 __self.template operator()<_Idx + 1>();
10070 return __dy + __s + __dx;
10072 else if constexpr (_Ix < _Iy)
10073 return -(__y - __x);
10075 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10076 }, __y._M_it.index());
10077 }, __x._M_it.index());
10080 friend constexpr difference_type
10081 operator-(const _Iterator& __x, default_sentinel_t)
10082 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10083 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10084 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10086 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10087 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10088 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10089 difference_type __s = 0;
10090 [&]<size_t _Idx = _Ix + 1>(this auto&& __self) {
10091 if constexpr (_Idx < sizeof...(_Vs))
10093 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10094 __self.template operator()<_Idx + 1>();
10097 return -(__dx + __s);
10098 }, __x._M_it.index());
10101 friend constexpr difference_type
10102 operator-(default_sentinel_t, const _Iterator& __x)
10103 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10104 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10105 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10106 { return -(__x - default_sentinel); }
10108 friend constexpr decltype(auto)
10109 iter_move(const _Iterator& __it)
10111 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10112 return std::visit([](const auto& __i) -> _Res {
10113 return ranges::iter_move(__i);
10117 friend constexpr void
10118 iter_swap(const _Iterator& __x, const _Iterator& __y)
10119 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10120 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10122 std::visit([&]<typename _Tp, typename _Up>(const _Tp& __it1, const _Up& __it2) {
10123 if constexpr (is_same_v<_Tp, _Up>)
10124 ranges::iter_swap(__it1, __it2);
10126 ranges::swap(*__it1, *__it2);
10127 }, __x._M_it, __y._M_it);
10135 template<typename... _Ts>
10136 concept __can_concat_view = requires { concat_view(std::declval<_Ts>()...); };
10141 template<typename... _Ts>
10142 requires __detail::__can_concat_view<_Ts...>
10144 operator() [[nodiscard]] (_Ts&&... __ts) const
10145 { return concat_view(std::forward<_Ts>(__ts)...); }
10147 template<input_range _Range>
10149 operator() [[nodiscard]] (_Range&& __t) const
10150 { return views::all(std::forward<_Range>(__t)); }
10153 inline constexpr _Concat concat;
10156} // namespace ranges
10157#endif // __cpp_lib_ranges_concat
10159#if __cpp_lib_ranges_cache_latest // C++ >= 26
10162 template<input_range _Vp>
10164 class cache_latest_view : public view_interface<cache_latest_view<_Vp>>
10166 _Vp _M_base = _Vp();
10168 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10169 add_pointer_t<range_reference_t<_Vp>>,
10170 range_reference_t<_Vp>>;
10171 __detail::__non_propagating_cache<__cache_t> _M_cache;
10177 cache_latest_view() requires default_initializable<_Vp> = default;
10180 cache_latest_view(_Vp __base)
10181 : _M_base(std::move(__base))
10185 base() const & requires copy_constructible<_Vp>
10186 { return _M_base; }
10190 { return std::move(_M_base); }
10194 { return _Iterator(*this); }
10198 { return _Sentinel(*this); }
10201 size() requires sized_range<_Vp>
10202 { return ranges::size(_M_base); }
10205 size() const requires sized_range<const _Vp>
10206 { return ranges::size(_M_base); }
10209 template<typename _Range>
10210 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10212 template<input_range _Vp>
10214 class cache_latest_view<_Vp>::_Iterator
10216 cache_latest_view* _M_parent;
10217 iterator_t<_Vp> _M_current;
10220 _Iterator(cache_latest_view& __parent)
10221 : _M_parent(std::__addressof(__parent)),
10222 _M_current(ranges::begin(__parent._M_base))
10225 friend class cache_latest_view;
10228 using difference_type = range_difference_t<_Vp>;
10229 using value_type = range_value_t<_Vp>;
10230 using iterator_concept = input_iterator_tag;
10232 _Iterator(_Iterator&&) = default;
10235 operator=(_Iterator&&) = default;
10237 constexpr iterator_t<_Vp>
10239 { return std::move(_M_current); }
10241 constexpr const iterator_t<_Vp>&
10242 base() const & noexcept
10243 { return _M_current; }
10245 constexpr range_reference_t<_Vp>&
10248 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10250 if (!_M_parent->_M_cache)
10251 _M_parent->_M_cache = std::__addressof(__detail::__as_lvalue(*_M_current));
10252 return **_M_parent->_M_cache;
10256 if (!_M_parent->_M_cache)
10257 _M_parent->_M_cache._M_emplace_deref(_M_current);
10258 return *_M_parent->_M_cache;
10262 constexpr _Iterator&
10265 _M_parent->_M_cache._M_reset();
10274 friend constexpr range_rvalue_reference_t<_Vp>
10275 iter_move(const _Iterator& __i)
10276 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10277 { return ranges::iter_move(__i._M_current); }
10279 friend constexpr void
10280 iter_swap(const _Iterator& __x, const _Iterator& __y)
10281 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10282 requires indirectly_swappable<iterator_t<_Vp>>
10283 { ranges::iter_swap(__x._M_current, __y._M_current); }
10286 template<input_range _Vp>
10288 class cache_latest_view<_Vp>::_Sentinel
10290 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10293 _Sentinel(cache_latest_view& __parent)
10294 : _M_end(ranges::end(__parent._M_base))
10297 friend class cache_latest_view;
10300 _Sentinel() = default;
10302 constexpr sentinel_t<_Vp>
10306 friend constexpr bool
10307 operator==(const _Iterator& __x, const _Sentinel& __y)
10308 { return __x._M_current == __y._M_end; }
10310 friend constexpr range_difference_t<_Vp>
10311 operator-(const _Iterator& __x, const _Sentinel& __y)
10312 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10313 { return __x._M_current - __y._M_end; }
10315 friend constexpr range_difference_t<_Vp>
10316 operator-(const _Sentinel& __x, const _Iterator& __y)
10317 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10318 { return __x._M_end - __y._M_current; }
10325 template<typename _Tp>
10326 concept __can_cache_latest = requires { cache_latest_view(std::declval<_Tp>()); };
10329 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10331 template<viewable_range _Range>
10332 requires __detail::__can_cache_latest<_Range>
10334 operator() [[nodiscard]] (_Range&& __r) const
10335 { return cache_latest_view(std::forward<_Range>(__r)); }
10337 static constexpr bool _S_has_simple_call_op = true;
10340 inline constexpr _CacheLatest cache_latest;
10342} // namespace ranges
10343#endif // __cpp_lib_ranges_cache_latest
10345#if __cpp_lib_ranges_to_input // C++ >= 26
10348 template<input_range _Vp>
10350 class to_input_view : public view_interface<to_input_view<_Vp>>
10352 _Vp _M_base = _Vp();
10354 template<bool _Const>
10358 to_input_view() requires default_initializable<_Vp> = default;
10361 to_input_view(_Vp __base)
10362 : _M_base(std::move(__base))
10366 base() const & requires copy_constructible<_Vp>
10367 { return _M_base; }
10371 { return std::move(_M_base); }
10374 begin() requires (!__detail::__simple_view<_Vp>)
10375 { return _Iterator<false>(ranges::begin(_M_base)); }
10378 begin() const requires range<const _Vp>
10379 { return _Iterator<true>(ranges::begin(_M_base)); }
10382 end() requires (!__detail::__simple_view<_Vp>)
10383 { return ranges::end(_M_base); }
10386 end() const requires range<const _Vp>
10387 { return ranges::end(_M_base); }
10390 size() requires sized_range<_Vp>
10391 { return ranges::size(_M_base); }
10394 size() const requires sized_range<const _Vp>
10395 { return ranges::size(_M_base); }
10398 template<typename _Range>
10399 to_input_view(_Range&&) -> to_input_view<views::all_t<_Range>>;
10401 template<input_range _Vp>
10403 template<bool _Const>
10404 class to_input_view<_Vp>::_Iterator
10406 using _Base = __maybe_const_t<_Const, _Vp>;
10408 iterator_t<_Base> _M_current = iterator_t<_Base>();
10411 _Iterator(iterator_t<_Base> __current)
10412 : _M_current(std::move(__current))
10415 friend to_input_view;
10416 friend _Iterator<!_Const>;
10419 using difference_type = range_difference_t<_Base>;
10420 using value_type = range_value_t<_Base>;
10421 using iterator_concept = input_iterator_tag;
10423 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
10425 _Iterator(_Iterator&&) = default;
10426 _Iterator& operator=(_Iterator&&) = default;
10429 _Iterator(_Iterator<!_Const> __i)
10430 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10431 : _M_current(std::move(__i._M_current))
10434 constexpr iterator_t<_Base>
10436 { return std::move(_M_current); }
10438 constexpr const iterator_t<_Base>&
10439 base() const & noexcept
10440 { return _M_current; }
10442 constexpr decltype(auto)
10444 { return *_M_current; }
10446 constexpr _Iterator&
10457 friend constexpr bool
10458 operator==(const _Iterator& __x, const sentinel_t<_Base>& __y)
10459 { return __x._M_current == __y; }
10461 friend constexpr difference_type
10462 operator-(const sentinel_t<_Base>& __y, const _Iterator& __x)
10463 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10464 { return __y - __x._M_current; }
10466 friend constexpr difference_type
10467 operator-(const _Iterator& __x, const sentinel_t<_Base>& __y)
10468 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10469 { return __x._M_current - __y; }
10471 friend constexpr range_rvalue_reference_t<_Base>
10472 iter_move(const _Iterator& __i)
10473 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10474 { return ranges::iter_move(__i._M_current); }
10476 friend constexpr void
10477 iter_swap(const _Iterator& __x, const _Iterator& __y)
10478 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10479 requires indirectly_swappable<iterator_t<_Base>>
10480 { ranges::iter_swap(__x._M_current, __y._M_current); }
10487 template<typename _Tp>
10488 concept __can_to_input = requires { to_input_view(std::declval<_Tp>()); };
10491 struct _ToInput : __adaptor::_RangeAdaptorClosure<_ToInput>
10493 template<viewable_range _Range>
10494 requires __detail::__can_to_input<_Range>
10496 operator() [[nodiscard]] (_Range&& __r) const
10498 if constexpr (input_range<_Range>
10499 && !common_range<_Range>
10500 && !forward_range<_Range>)
10501 return views::all(std::forward<_Range>(__r));
10503 return to_input_view(std::forward<_Range>(__r));
10506 static constexpr bool _S_has_simple_call_op = true;
10509 inline constexpr _ToInput to_input;
10511} // namespace ranges
10512#endif // __cpp_lib_ranges_to_input
10514_GLIBCXX_END_NAMESPACE_VERSION
10516#endif // library concepts
10518#endif /* _GLIBCXX_RANGES */