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 = typename __make_tuple<array<_Tp, _Nm>>::__type;
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 = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
5464 using difference_type = range_difference_t<_Base>;
5466 _Iterator() = default;
5469 _Iterator(_Iterator<!_Const> __i)
5470 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5472 for (size_t __j = 0; __j < _Nm; ++__j)
5473 _M_current[__j] = std::move(__i._M_current[__j]);
5479 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5480 return __detail::__tuple_transform(__f, _M_current);
5483 constexpr _Iterator&
5486 for (auto& __i : _M_current)
5499 constexpr _Iterator&
5500 operator--() requires bidirectional_range<_Base>
5502 for (auto& __i : _M_current)
5508 operator--(int) requires bidirectional_range<_Base>
5515 constexpr _Iterator&
5516 operator+=(difference_type __x)
5517 requires random_access_range<_Base>
5519 for (auto& __i : _M_current)
5524 constexpr _Iterator&
5525 operator-=(difference_type __x)
5526 requires random_access_range<_Base>
5528 for (auto& __i : _M_current)
5534 operator[](difference_type __n) const
5535 requires random_access_range<_Base>
5537 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5538 return __detail::__tuple_transform(__f, _M_current);
5541 friend constexpr bool
5542 operator==(const _Iterator& __x, const _Iterator& __y)
5543 { return __x._M_current.back() == __y._M_current.back(); }
5545 friend constexpr bool
5546 operator<(const _Iterator& __x, const _Iterator& __y)
5547 requires random_access_range<_Base>
5548 { return __x._M_current.back() < __y._M_current.back(); }
5550 friend constexpr bool
5551 operator>(const _Iterator& __x, const _Iterator& __y)
5552 requires random_access_range<_Base>
5553 { return __y < __x; }
5555 friend constexpr bool
5556 operator<=(const _Iterator& __x, const _Iterator& __y)
5557 requires random_access_range<_Base>
5558 { return !(__y < __x); }
5560 friend constexpr bool
5561 operator>=(const _Iterator& __x, const _Iterator& __y)
5562 requires random_access_range<_Base>
5563 { return !(__x < __y); }
5565 friend constexpr auto
5566 operator<=>(const _Iterator& __x, const _Iterator& __y)
5567 requires random_access_range<_Base>
5568 && three_way_comparable<iterator_t<_Base>>
5569 { return __x._M_current.back() <=> __y._M_current.back(); }
5571 friend constexpr _Iterator
5572 operator+(const _Iterator& __i, difference_type __n)
5573 requires random_access_range<_Base>
5580 friend constexpr _Iterator
5581 operator+(difference_type __n, const _Iterator& __i)
5582 requires random_access_range<_Base>
5589 friend constexpr _Iterator
5590 operator-(const _Iterator& __i, difference_type __n)
5591 requires random_access_range<_Base>
5598 friend constexpr difference_type
5599 operator-(const _Iterator& __x, const _Iterator& __y)
5600 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5601 { return __x._M_current.back() - __y._M_current.back(); }
5603 friend constexpr auto
5604 iter_move(const _Iterator& __i)
5605 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5607 friend constexpr void
5608 iter_swap(const _Iterator& __l, const _Iterator& __r)
5609 requires indirectly_swappable<iterator_t<_Base>>
5611 for (size_t __i = 0; __i < _Nm; __i++)
5612 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5616 template<forward_range _Vp, size_t _Nm>
5617 requires view<_Vp> && (_Nm > 0)
5618 template<bool _Const>
5619 class adjacent_view<_Vp, _Nm>::_Sentinel
5621 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5623 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5626 _Sentinel(sentinel_t<_Base> __end)
5630 friend class adjacent_view;
5633 _Sentinel() = default;
5636 _Sentinel(_Sentinel<!_Const> __i)
5637 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5638 : _M_end(std::move(__i._M_end))
5641 template<bool _OtherConst>
5642 requires sentinel_for<sentinel_t<_Base>,
5643 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5644 friend constexpr bool
5645 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5646 { return __x._M_current.back() == __y._M_end; }
5648 template<bool _OtherConst>
5649 requires sized_sentinel_for<sentinel_t<_Base>,
5650 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5651 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5652 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5653 { return __x._M_current.back() - __y._M_end; }
5655 template<bool _OtherConst>
5656 requires sized_sentinel_for<sentinel_t<_Base>,
5657 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5658 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5659 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5660 { return __y._M_end - __x._M_current.back(); }
5667 template<size_t _Nm, typename _Range>
5668 concept __can_adjacent_view
5669 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5672 template<size_t _Nm>
5673 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5675 template<viewable_range _Range>
5676 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5678 operator() [[nodiscard]] (_Range&& __r) const
5680 if constexpr (_Nm == 0)
5681 return views::empty<tuple<>>;
5683 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5687 template<size_t _Nm>
5688 inline constexpr _Adjacent<_Nm> adjacent;
5690 inline constexpr auto pairwise = adjacent<2>;
5693 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5694 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5695 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5696 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5697 range_reference_t<_Vp>>>
5698 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5700 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5701 adjacent_view<_Vp, _Nm> _M_inner;
5703 using _InnerView = adjacent_view<_Vp, _Nm>;
5705 template<bool _Const>
5706 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5708 template<bool _Const>
5709 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5711 template<bool> class _Iterator;
5712 template<bool> class _Sentinel;
5715 adjacent_transform_view() = default;
5718 adjacent_transform_view(_Vp __base, _Fp __fun)
5719 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5722 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5723 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5724 // 3947. Unexpected constraints on adjacent_transform_view::base()
5726 base() const & requires copy_constructible<_Vp>
5727 { return _M_inner.base(); }
5731 { return std::move(_M_inner.base()); }
5735 { return _Iterator<false>(*this, _M_inner.begin()); }
5739 requires range<const _InnerView>
5740 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5741 range_reference_t<const _Vp>>
5742 { return _Iterator<true>(*this, _M_inner.begin()); }
5747 if constexpr (common_range<_InnerView>)
5748 return _Iterator<false>(*this, _M_inner.end());
5750 return _Sentinel<false>(_M_inner.end());
5755 requires range<const _InnerView>
5756 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5757 range_reference_t<const _Vp>>
5759 if constexpr (common_range<const _InnerView>)
5760 return _Iterator<true>(*this, _M_inner.end());
5762 return _Sentinel<true>(_M_inner.end());
5766 size() requires sized_range<_InnerView>
5767 { return _M_inner.size(); }
5770 size() const requires sized_range<const _InnerView>
5771 { return _M_inner.size(); }
5774 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5775 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5776 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5777 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5778 range_reference_t<_Vp>>>
5779 template<bool _Const>
5780 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5782 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5783 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5785 _Parent* _M_parent = nullptr;
5786 _InnerIter<_Const> _M_inner;
5789 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5790 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5796 using __detail::__maybe_const_t;
5797 using __detail::__unarize;
5798 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5799 range_reference_t<_Base>>;
5800 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5801 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5802 // 3798. Rvalue reference and iterator_category
5803 if constexpr (!is_reference_v<_Res>)
5804 return input_iterator_tag{};
5805 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5806 return random_access_iterator_tag{};
5807 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5808 return bidirectional_iterator_tag{};
5809 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5810 return forward_iterator_tag{};
5812 return input_iterator_tag{};
5815 friend class adjacent_transform_view;
5818 using iterator_category = decltype(_S_iter_cat());
5819 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5821 = remove_cvref_t<invoke_result_t
5822 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5823 range_reference_t<_Base>>>;
5824 using difference_type = range_difference_t<_Base>;
5826 _Iterator() = default;
5829 _Iterator(_Iterator<!_Const> __i)
5830 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5831 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5834 constexpr decltype(auto)
5837 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5838 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5839 }, _M_inner._M_current);
5842 constexpr _Iterator&
5857 constexpr _Iterator&
5858 operator--() requires bidirectional_range<_Base>
5865 operator--(int) requires bidirectional_range<_Base>
5872 constexpr _Iterator&
5873 operator+=(difference_type __x) requires random_access_range<_Base>
5879 constexpr _Iterator&
5880 operator-=(difference_type __x) requires random_access_range<_Base>
5886 constexpr decltype(auto)
5887 operator[](difference_type __n) const requires random_access_range<_Base>
5889 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5890 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5891 }, _M_inner._M_current);
5894 friend constexpr bool
5895 operator==(const _Iterator& __x, const _Iterator& __y)
5896 { return __x._M_inner == __y._M_inner; }
5898 friend constexpr bool
5899 operator<(const _Iterator& __x, const _Iterator& __y)
5900 requires random_access_range<_Base>
5901 { return __x._M_inner < __y._M_inner; }
5903 friend constexpr bool
5904 operator>(const _Iterator& __x, const _Iterator& __y)
5905 requires random_access_range<_Base>
5906 { return __x._M_inner > __y._M_inner; }
5908 friend constexpr bool
5909 operator<=(const _Iterator& __x, const _Iterator& __y)
5910 requires random_access_range<_Base>
5911 { return __x._M_inner <= __y._M_inner; }
5913 friend constexpr bool
5914 operator>=(const _Iterator& __x, const _Iterator& __y)
5915 requires random_access_range<_Base>
5916 { return __x._M_inner >= __y._M_inner; }
5918 friend constexpr auto
5919 operator<=>(const _Iterator& __x, const _Iterator& __y)
5920 requires random_access_range<_Base> &&
5921 three_way_comparable<_InnerIter<_Const>>
5922 { return __x._M_inner <=> __y._M_inner; }
5924 friend constexpr _Iterator
5925 operator+(const _Iterator& __i, difference_type __n)
5926 requires random_access_range<_Base>
5927 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5929 friend constexpr _Iterator
5930 operator+(difference_type __n, const _Iterator& __i)
5931 requires random_access_range<_Base>
5932 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5934 friend constexpr _Iterator
5935 operator-(const _Iterator& __i, difference_type __n)
5936 requires random_access_range<_Base>
5937 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5939 friend constexpr difference_type
5940 operator-(const _Iterator& __x, const _Iterator& __y)
5941 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5942 { return __x._M_inner - __y._M_inner; }
5945 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5946 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5947 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5948 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5949 range_reference_t<_Vp>>>
5950 template<bool _Const>
5951 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5953 _InnerSent<_Const> _M_inner;
5956 _Sentinel(_InnerSent<_Const> __inner)
5960 friend class adjacent_transform_view;
5963 _Sentinel() = default;
5966 _Sentinel(_Sentinel<!_Const> __i)
5967 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5968 : _M_inner(std::move(__i._M_inner))
5971 template<bool _OtherConst>
5972 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5973 friend constexpr bool
5974 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5975 { return __x._M_inner == __y._M_inner; }
5977 template<bool _OtherConst>
5978 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5979 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5980 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5981 { return __x._M_inner - __y._M_inner; }
5983 template<bool _OtherConst>
5984 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5985 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5986 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5987 { return __x._M_inner - __y._M_inner; }
5994 template<size_t _Nm, typename _Range, typename _Fp>
5995 concept __can_adjacent_transform_view
5996 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5997 (std::declval<_Range>(), std::declval<_Fp>()); };
6000 template<size_t _Nm>
6001 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6003 template<viewable_range _Range, typename _Fp>
6004 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6006 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
6008 if constexpr (_Nm == 0)
6009 return zip_transform(std::forward<_Fp>(__f));
6011 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6012 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6015 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6016 static constexpr int _S_arity = 2;
6017 static constexpr bool _S_has_simple_extra_args = true;
6020 template<size_t _Nm>
6021 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6023 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6025#endif // __cpp_lib_ranges_zip
6027#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6030 template<typename _Tp>
6031 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6033 _Tp __r = __num / __denom;
6034 if (__num % __denom)
6041 requires input_range<_Vp>
6042 class chunk_view : public view_interface<chunk_view<_Vp>>
6045 range_difference_t<_Vp> _M_n;
6046 range_difference_t<_Vp> _M_remainder = 0;
6047 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6054 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6055 : _M_base(std::move(__base)), _M_n(__n)
6056 { __glibcxx_assert(__n >= 0); }
6059 base() const & requires copy_constructible<_Vp>
6064 { return std::move(_M_base); }
6066 constexpr _OuterIter
6069 _M_current = ranges::begin(_M_base);
6070 _M_remainder = _M_n;
6071 return _OuterIter(*this);
6074 constexpr default_sentinel_t
6075 end() const noexcept
6076 { return default_sentinel; }
6079 size() requires sized_range<_Vp>
6081 return __detail::__to_unsigned_like(__detail::__div_ceil
6082 (ranges::distance(_M_base), _M_n));
6086 size() const requires sized_range<const _Vp>
6088 return __detail::__to_unsigned_like(__detail::__div_ceil
6089 (ranges::distance(_M_base), _M_n));
6093 template<typename _Range>
6094 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6097 requires input_range<_Vp>
6098 class chunk_view<_Vp>::_OuterIter
6100 chunk_view* _M_parent;
6103 _OuterIter(chunk_view& __parent) noexcept
6104 : _M_parent(std::__addressof(__parent))
6110 using iterator_concept = input_iterator_tag;
6111 using difference_type = range_difference_t<_Vp>;
6115 _OuterIter(_OuterIter&&) = default;
6116 _OuterIter& operator=(_OuterIter&&) = default;
6118 constexpr value_type
6121 __glibcxx_assert(*this != default_sentinel);
6122 return value_type(*_M_parent);
6125 constexpr _OuterIter&
6128 __glibcxx_assert(*this != default_sentinel);
6129 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6130 ranges::end(_M_parent->_M_base));
6131 _M_parent->_M_remainder = _M_parent->_M_n;
6139 friend constexpr bool
6140 operator==(const _OuterIter& __x, default_sentinel_t)
6142 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6143 && __x._M_parent->_M_remainder != 0;
6146 friend constexpr difference_type
6147 operator-(default_sentinel_t, const _OuterIter& __x)
6148 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6150 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6152 if (__dist < __x._M_parent->_M_remainder)
6153 return __dist == 0 ? 0 : 1;
6155 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6156 __x._M_parent->_M_n);
6159 friend constexpr difference_type
6160 operator-(const _OuterIter& __x, default_sentinel_t __y)
6161 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6162 { return -(__y - __x); }
6166 requires input_range<_Vp>
6167 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6170 chunk_view* _M_parent;
6173 value_type(chunk_view& __parent) noexcept
6174 : _M_parent(std::__addressof(__parent))
6180 constexpr _InnerIter
6181 begin() const noexcept
6182 { return _InnerIter(*_M_parent); }
6184 constexpr default_sentinel_t
6185 end() const noexcept
6186 { return default_sentinel; }
6190 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6192 return __detail::__to_unsigned_like
6193 (ranges::min(_M_parent->_M_remainder,
6194 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6199 requires input_range<_Vp>
6200 class chunk_view<_Vp>::_InnerIter
6202 chunk_view* _M_parent;
6205 _InnerIter(chunk_view& __parent) noexcept
6206 : _M_parent(std::__addressof(__parent))
6209 friend _OuterIter::value_type;
6212 using iterator_concept = input_iterator_tag;
6213 using difference_type = range_difference_t<_Vp>;
6214 using value_type = range_value_t<_Vp>;
6216 _InnerIter(_InnerIter&&) = default;
6217 _InnerIter& operator=(_InnerIter&&) = default;
6219 constexpr const iterator_t<_Vp>&
6221 { return *_M_parent->_M_current; }
6223 constexpr range_reference_t<_Vp>
6226 __glibcxx_assert(*this != default_sentinel);
6227 return **_M_parent->_M_current;
6230 constexpr _InnerIter&
6233 __glibcxx_assert(*this != default_sentinel);
6234 ++*_M_parent->_M_current;
6235 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6236 _M_parent->_M_remainder = 0;
6238 --_M_parent->_M_remainder;
6246 friend constexpr bool
6247 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6248 { return __x._M_parent->_M_remainder == 0; }
6250 friend constexpr difference_type
6251 operator-(default_sentinel_t, const _InnerIter& __x)
6252 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6254 return ranges::min(__x._M_parent->_M_remainder,
6255 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6258 friend constexpr difference_type
6259 operator-(const _InnerIter& __x, default_sentinel_t __y)
6260 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6261 { return -(__y - __x); }
6263 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6264 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
6265 friend constexpr range_rvalue_reference_t<_Vp>
6266 iter_move(const _InnerIter& __i)
6267 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6268 { return ranges::iter_move(*__i._M_parent->_M_current); }
6270 friend constexpr void
6271 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
6272 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6273 *__x._M_parent->_M_current)))
6274 requires indirectly_swappable<iterator_t<_Vp>>
6275 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6279 requires forward_range<_Vp>
6280 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6283 range_difference_t<_Vp> _M_n;
6284 template<bool> class _Iterator;
6288 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6289 : _M_base(std::move(__base)), _M_n(__n)
6290 { __glibcxx_assert(__n > 0); }
6293 base() const & requires copy_constructible<_Vp>
6298 { return std::move(_M_base); }
6301 begin() requires (!__detail::__simple_view<_Vp>)
6302 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6305 begin() const requires forward_range<const _Vp>
6306 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6309 end() requires (!__detail::__simple_view<_Vp>)
6311 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6313 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6314 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6316 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6317 return _Iterator<false>(this, ranges::end(_M_base));
6319 return default_sentinel;
6323 end() const requires forward_range<const _Vp>
6325 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6327 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6328 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6330 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6331 return _Iterator<true>(this, ranges::end(_M_base));
6333 return default_sentinel;
6337 size() requires sized_range<_Vp>
6339 return __detail::__to_unsigned_like(__detail::__div_ceil
6340 (ranges::distance(_M_base), _M_n));
6344 size() const requires sized_range<const _Vp>
6346 return __detail::__to_unsigned_like(__detail::__div_ceil
6347 (ranges::distance(_M_base), _M_n));
6351 template<typename _Vp>
6352 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6353 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6356 requires forward_range<_Vp>
6357 template<bool _Const>
6358 class chunk_view<_Vp>::_Iterator
6360 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6361 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6363 iterator_t<_Base> _M_current = iterator_t<_Base>();
6364 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6365 range_difference_t<_Base> _M_n = 0;
6366 range_difference_t<_Base> _M_missing = 0;
6369 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6370 range_difference_t<_Base> __missing = 0)
6371 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6372 _M_n(__parent->_M_n), _M_missing(__missing)
6378 if constexpr (random_access_range<_Base>)
6379 return random_access_iterator_tag{};
6380 else if constexpr (bidirectional_range<_Base>)
6381 return bidirectional_iterator_tag{};
6383 return forward_iterator_tag{};
6389 using iterator_category = input_iterator_tag;
6390 using iterator_concept = decltype(_S_iter_cat());
6391 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6392 using difference_type = range_difference_t<_Base>;
6394 _Iterator() = default;
6396 constexpr _Iterator(_Iterator<!_Const> __i)
6398 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6399 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6400 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6401 _M_n(__i._M_n), _M_missing(__i._M_missing)
6404 constexpr iterator_t<_Base>
6406 { return _M_current; }
6408 constexpr value_type
6411 __glibcxx_assert(_M_current != _M_end);
6412 return views::take(subrange(_M_current, _M_end), _M_n);
6415 constexpr _Iterator&
6418 __glibcxx_assert(_M_current != _M_end);
6419 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6431 constexpr _Iterator&
6432 operator--() requires bidirectional_range<_Base>
6434 ranges::advance(_M_current, _M_missing - _M_n);
6440 operator--(int) requires bidirectional_range<_Base>
6447 constexpr _Iterator&
6448 operator+=(difference_type __x)
6449 requires random_access_range<_Base>
6453 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6454 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6458 ranges::advance(_M_current, _M_n * __x + _M_missing);
6464 constexpr _Iterator&
6465 operator-=(difference_type __x)
6466 requires random_access_range<_Base>
6467 { return *this += -__x; }
6469 constexpr value_type
6470 operator[](difference_type __n) const
6471 requires random_access_range<_Base>
6472 { return *(*this + __n); }
6474 friend constexpr bool
6475 operator==(const _Iterator& __x, const _Iterator& __y)
6476 { return __x._M_current == __y._M_current; }
6478 friend constexpr bool
6479 operator==(const _Iterator& __x, default_sentinel_t)
6480 { return __x._M_current == __x._M_end; }
6482 friend constexpr bool
6483 operator<(const _Iterator& __x, const _Iterator& __y)
6484 requires random_access_range<_Base>
6485 { return __x._M_current > __y._M_current; }
6487 friend constexpr bool
6488 operator>(const _Iterator& __x, const _Iterator& __y)
6489 requires random_access_range<_Base>
6490 { return __y < __x; }
6492 friend constexpr bool
6493 operator<=(const _Iterator& __x, const _Iterator& __y)
6494 requires random_access_range<_Base>
6495 { return !(__y < __x); }
6497 friend constexpr bool
6498 operator>=(const _Iterator& __x, const _Iterator& __y)
6499 requires random_access_range<_Base>
6500 { return !(__x < __y); }
6502 friend constexpr auto
6503 operator<=>(const _Iterator& __x, const _Iterator& __y)
6504 requires random_access_range<_Base>
6505 && three_way_comparable<iterator_t<_Base>>
6506 { return __x._M_current <=> __y._M_current; }
6508 friend constexpr _Iterator
6509 operator+(const _Iterator& __i, difference_type __n)
6510 requires random_access_range<_Base>
6517 friend constexpr _Iterator
6518 operator+(difference_type __n, const _Iterator& __i)
6519 requires random_access_range<_Base>
6526 friend constexpr _Iterator
6527 operator-(const _Iterator& __i, difference_type __n)
6528 requires random_access_range<_Base>
6535 friend constexpr difference_type
6536 operator-(const _Iterator& __x, const _Iterator& __y)
6537 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6539 return (__x._M_current - __y._M_current
6540 + __x._M_missing - __y._M_missing) / __x._M_n;
6543 friend constexpr difference_type
6544 operator-(default_sentinel_t, const _Iterator& __x)
6545 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6546 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6548 friend constexpr difference_type
6549 operator-(const _Iterator& __x, default_sentinel_t __y)
6550 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6551 { return -(__y - __x); }
6558 template<typename _Range, typename _Dp>
6559 concept __can_chunk_view
6560 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6563 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6565 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6566 requires __detail::__can_chunk_view<_Range, _Dp>
6568 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6569 { return chunk_view(std::forward<_Range>(__r), __n); }
6571 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6572 static constexpr int _S_arity = 2;
6573 static constexpr bool _S_has_simple_extra_args = true;
6576 inline constexpr _Chunk chunk;
6578#endif // __cpp_lib_ranges_chunk
6580#ifdef __cpp_lib_ranges_slide // C++ >= 23
6583 template<typename _Vp>
6584 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6586 template<typename _Vp>
6587 concept __slide_caches_last
6588 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6590 template<typename _Vp>
6591 concept __slide_caches_first
6592 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6595 template<forward_range _Vp>
6597 class slide_view : public view_interface<slide_view<_Vp>>
6600 range_difference_t<_Vp> _M_n;
6601 [[no_unique_address]]
6602 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6603 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6604 [[no_unique_address]]
6605 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6606 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6608 template<bool> class _Iterator;
6613 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6614 : _M_base(std::move(__base)), _M_n(__n)
6615 { __glibcxx_assert(__n > 0); }
6617 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6618 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
6620 base() const & requires copy_constructible<_Vp>
6625 { return std::move(_M_base); }
6628 begin() requires (!(__detail::__simple_view<_Vp>
6629 && __detail::__slide_caches_nothing<const _Vp>))
6631 if constexpr (__detail::__slide_caches_first<_Vp>)
6633 iterator_t<_Vp> __it;
6634 if (_M_cached_begin._M_has_value())
6635 __it = _M_cached_begin._M_get(_M_base);
6638 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6639 _M_cached_begin._M_set(_M_base, __it);
6641 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6644 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6648 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6649 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6652 end() requires (!(__detail::__simple_view<_Vp>
6653 && __detail::__slide_caches_nothing<const _Vp>))
6655 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6656 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6658 else if constexpr (__detail::__slide_caches_last<_Vp>)
6660 iterator_t<_Vp> __it;
6661 if (_M_cached_end._M_has_value())
6662 __it = _M_cached_end._M_get(_M_base);
6665 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6666 _M_cached_end._M_set(_M_base, __it);
6668 return _Iterator<false>(std::move(__it), _M_n);
6670 else if constexpr (common_range<_Vp>)
6671 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6673 return _Sentinel(ranges::end(_M_base));
6677 end() const requires __detail::__slide_caches_nothing<const _Vp>
6678 { return begin() + range_difference_t<const _Vp>(size()); }
6681 size() requires sized_range<_Vp>
6683 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6686 return __detail::__to_unsigned_like(__sz);
6690 size() const requires sized_range<const _Vp>
6692 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6695 return __detail::__to_unsigned_like(__sz);
6699 template<typename _Range>
6700 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6702 template<typename _Vp>
6703 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6704 = enable_borrowed_range<_Vp>;
6706 template<forward_range _Vp>
6708 template<bool _Const>
6709 class slide_view<_Vp>::_Iterator
6711 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6712 static constexpr bool _S_last_elt_present
6713 = __detail::__slide_caches_first<_Base>;
6715 iterator_t<_Base> _M_current = iterator_t<_Base>();
6716 [[no_unique_address]]
6717 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6718 _M_last_elt = decltype(_M_last_elt)();
6719 range_difference_t<_Base> _M_n = 0;
6722 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6723 requires (!_S_last_elt_present)
6724 : _M_current(__current), _M_n(__n)
6728 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6729 range_difference_t<_Base> __n)
6730 requires _S_last_elt_present
6731 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6737 if constexpr (random_access_range<_Base>)
6738 return random_access_iterator_tag{};
6739 else if constexpr (bidirectional_range<_Base>)
6740 return bidirectional_iterator_tag{};
6742 return forward_iterator_tag{};
6746 friend slide_view::_Sentinel;
6749 using iterator_category = input_iterator_tag;
6750 using iterator_concept = decltype(_S_iter_concept());
6751 using value_type = decltype(views::counted(_M_current, _M_n));
6752 using difference_type = range_difference_t<_Base>;
6754 _Iterator() = default;
6757 _Iterator(_Iterator<!_Const> __i)
6758 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6759 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6764 { return views::counted(_M_current, _M_n); }
6766 constexpr _Iterator&
6770 if constexpr (_S_last_elt_present)
6783 constexpr _Iterator&
6784 operator--() requires bidirectional_range<_Base>
6787 if constexpr (_S_last_elt_present)
6793 operator--(int) requires bidirectional_range<_Base>
6800 constexpr _Iterator&
6801 operator+=(difference_type __x)
6802 requires random_access_range<_Base>
6805 if constexpr (_S_last_elt_present)
6810 constexpr _Iterator&
6811 operator-=(difference_type __x)
6812 requires random_access_range<_Base>
6815 if constexpr (_S_last_elt_present)
6821 operator[](difference_type __n) const
6822 requires random_access_range<_Base>
6823 { return views::counted(_M_current + __n, _M_n); }
6825 friend constexpr bool
6826 operator==(const _Iterator& __x, const _Iterator& __y)
6828 if constexpr (_S_last_elt_present)
6829 return __x._M_last_elt == __y._M_last_elt;
6831 return __x._M_current == __y._M_current;
6834 friend constexpr bool
6835 operator<(const _Iterator& __x, const _Iterator& __y)
6836 requires random_access_range<_Base>
6837 { return __x._M_current < __y._M_current; }
6839 friend constexpr bool
6840 operator>(const _Iterator& __x, const _Iterator& __y)
6841 requires random_access_range<_Base>
6842 { return __y < __x; }
6844 friend constexpr bool
6845 operator<=(const _Iterator& __x, const _Iterator& __y)
6846 requires random_access_range<_Base>
6847 { return !(__y < __x); }
6849 friend constexpr bool
6850 operator>=(const _Iterator& __x, const _Iterator& __y)
6851 requires random_access_range<_Base>
6852 { return !(__x < __y); }
6854 friend constexpr auto
6855 operator<=>(const _Iterator& __x, const _Iterator& __y)
6856 requires random_access_range<_Base>
6857 && three_way_comparable<iterator_t<_Base>>
6858 { return __x._M_current <=> __y._M_current; }
6860 friend constexpr _Iterator
6861 operator+(const _Iterator& __i, difference_type __n)
6862 requires random_access_range<_Base>
6869 friend constexpr _Iterator
6870 operator+(difference_type __n, const _Iterator& __i)
6871 requires random_access_range<_Base>
6878 friend constexpr _Iterator
6879 operator-(const _Iterator& __i, difference_type __n)
6880 requires random_access_range<_Base>
6887 friend constexpr difference_type
6888 operator-(const _Iterator& __x, const _Iterator& __y)
6889 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6891 if constexpr (_S_last_elt_present)
6892 return __x._M_last_elt - __y._M_last_elt;
6894 return __x._M_current - __y._M_current;
6898 template<forward_range _Vp>
6900 class slide_view<_Vp>::_Sentinel
6902 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6905 _Sentinel(sentinel_t<_Vp> __end)
6912 _Sentinel() = default;
6914 friend constexpr bool
6915 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6916 { return __x._M_last_elt == __y._M_end; }
6918 friend constexpr range_difference_t<_Vp>
6919 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6920 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6921 { return __x._M_last_elt - __y._M_end; }
6923 friend constexpr range_difference_t<_Vp>
6924 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6925 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6926 { return __y._M_end -__x._M_last_elt; }
6933 template<typename _Range, typename _Dp>
6934 concept __can_slide_view
6935 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6938 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6940 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6941 requires __detail::__can_slide_view<_Range, _Dp>
6943 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6944 { return slide_view(std::forward<_Range>(__r), __n); }
6946 using __adaptor::_RangeAdaptor<_Slide>::operator();
6947 static constexpr int _S_arity = 2;
6948 static constexpr bool _S_has_simple_extra_args = true;
6951 inline constexpr _Slide slide;
6953#endif // __cpp_lib_ranges_slide
6955#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
6956 template<forward_range _Vp,
6957 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6958 requires view<_Vp> && is_object_v<_Pred>
6959 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6961 _Vp _M_base = _Vp();
6962 __detail::__box<_Pred> _M_pred;
6963 __detail::_CachedPosition<_Vp> _M_cached_begin;
6965 constexpr iterator_t<_Vp>
6966 _M_find_next(iterator_t<_Vp> __current)
6968 __glibcxx_assert(_M_pred.has_value());
6969 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6970 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6972 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6973 return ranges::next(__it, 1, ranges::end(_M_base));
6976 constexpr iterator_t<_Vp>
6977 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
6979 __glibcxx_assert(_M_pred.has_value());
6980 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6981 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
6983 auto __rbegin = std::make_reverse_iterator(__current);
6984 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
6985 __glibcxx_assert(__rbegin != __rend);
6986 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
6987 return ranges::prev(__it, 1, ranges::begin(_M_base));
6993 chunk_by_view() requires (default_initializable<_Vp>
6994 && default_initializable<_Pred>)
6998 chunk_by_view(_Vp __base, _Pred __pred)
6999 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
7003 base() const & requires copy_constructible<_Vp>
7008 { return std::move(_M_base); }
7010 constexpr const _Pred&
7012 { return *_M_pred; }
7017 __glibcxx_assert(_M_pred.has_value());
7018 iterator_t<_Vp> __it;
7019 if (_M_cached_begin._M_has_value())
7020 __it = _M_cached_begin._M_get(_M_base);
7023 __it = _M_find_next(ranges::begin(_M_base));
7024 _M_cached_begin._M_set(_M_base, __it);
7026 return _Iterator(*this, ranges::begin(_M_base), __it);
7032 if constexpr (common_range<_Vp>)
7033 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
7035 return default_sentinel;
7039 template<typename _Range, typename _Pred>
7040 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7042 template<forward_range _Vp,
7043 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7044 requires view<_Vp> && is_object_v<_Pred>
7045 class chunk_by_view<_Vp, _Pred>::_Iterator
7047 chunk_by_view* _M_parent = nullptr;
7048 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7049 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7052 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7053 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7059 if constexpr (bidirectional_range<_Vp>)
7060 return bidirectional_iterator_tag{};
7062 return forward_iterator_tag{};
7065 friend chunk_by_view;
7068 using value_type = subrange<iterator_t<_Vp>>;
7069 using difference_type = range_difference_t<_Vp>;
7070 using iterator_category = input_iterator_tag;
7071 using iterator_concept = decltype(_S_iter_concept());
7073 _Iterator() = default;
7075 constexpr value_type
7078 __glibcxx_assert(_M_current != _M_next);
7079 return ranges::subrange(_M_current, _M_next);
7082 constexpr _Iterator&
7085 __glibcxx_assert(_M_current != _M_next);
7086 _M_current = _M_next;
7087 _M_next = _M_parent->_M_find_next(_M_current);
7099 constexpr _Iterator&
7100 operator--() requires bidirectional_range<_Vp>
7102 _M_next = _M_current;
7103 _M_current = _M_parent->_M_find_prev(_M_next);
7108 operator--(int) requires bidirectional_range<_Vp>
7115 friend constexpr bool
7116 operator==(const _Iterator& __x, const _Iterator& __y)
7117 { return __x._M_current == __y._M_current; }
7119 friend constexpr bool
7120 operator==(const _Iterator& __x, default_sentinel_t)
7121 { return __x._M_current == __x._M_next; }
7128 template<typename _Range, typename _Pred>
7129 concept __can_chunk_by_view
7130 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7133 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7135 template<viewable_range _Range, typename _Pred>
7136 requires __detail::__can_chunk_by_view<_Range, _Pred>
7138 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7139 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7141 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7142 static constexpr int _S_arity = 2;
7143 static constexpr bool _S_has_simple_extra_args = true;
7146 inline constexpr _ChunkBy chunk_by;
7148#endif // __cpp_lib_ranges_chunk_by
7150#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7153 template<typename _Range, typename _Pattern>
7154 concept __compatible_joinable_ranges
7155 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7156 && common_reference_with<range_reference_t<_Range>,
7157 range_reference_t<_Pattern>>
7158 && common_reference_with<range_rvalue_reference_t<_Range>,
7159 range_rvalue_reference_t<_Pattern>>;
7161 template<typename _Range>
7162 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7165 template<input_range _Vp, forward_range _Pattern>
7166 requires view<_Vp> && view<_Pattern>
7167 && input_range<range_reference_t<_Vp>>
7168 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7169 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7171 using _InnerRange = range_reference_t<_Vp>;
7173 _Vp _M_base = _Vp();
7174 [[no_unique_address]]
7175 __detail::__maybe_present_t<!forward_range<_Vp>,
7176 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7177 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7178 _Pattern _M_pattern = _Pattern();
7180 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7181 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7182 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7184 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7185 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7186 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7188 template<bool _Const>
7189 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7191 template<bool _Const>
7195 template<bool _Const>
7196 requires _S_ref_is_glvalue<_Const>
7197 && forward_range<_Base<_Const>>
7198 && forward_range<_InnerBase<_Const>>
7199 struct __iter_cat<_Const>
7205 using _OuterIter = join_with_view::_OuterIter<_Const>;
7206 using _InnerIter = join_with_view::_InnerIter<_Const>;
7207 using _PatternIter = join_with_view::_PatternIter<_Const>;
7208 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7209 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7210 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7211 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7212 // 3798. Rvalue reference and iterator_category
7213 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7214 iter_reference_t<_PatternIter>>>)
7215 return input_iterator_tag{};
7216 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7217 && derived_from<_InnerCat, bidirectional_iterator_tag>
7218 && derived_from<_PatternCat, bidirectional_iterator_tag>
7219 && common_range<_InnerBase<_Const>>
7220 && common_range<_PatternBase<_Const>>)
7221 return bidirectional_iterator_tag{};
7222 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7223 && derived_from<_InnerCat, forward_iterator_tag>
7224 && derived_from<_PatternCat, forward_iterator_tag>)
7225 return forward_iterator_tag{};
7227 return input_iterator_tag{};
7230 using iterator_category = decltype(_S_iter_cat());
7233 template<bool> class _Iterator;
7234 template<bool> class _Sentinel;
7237 join_with_view() requires (default_initializable<_Vp>
7238 && default_initializable<_Pattern>)
7242 join_with_view(_Vp __base, _Pattern __pattern)
7243 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7246 template<input_range _Range>
7247 requires constructible_from<_Vp, views::all_t<_Range>>
7248 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7250 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7251 : _M_base(views::all(std::forward<_Range>(__r))),
7252 _M_pattern(views::single(std::move(__e)))
7256 base() const& requires copy_constructible<_Vp>
7261 { return std::move(_M_base); }
7266 if constexpr (forward_range<_Vp>)
7268 constexpr bool __use_const = is_reference_v<_InnerRange>
7269 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7270 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7274 _M_outer_it = ranges::begin(_M_base);
7275 return _Iterator<false>{*this};
7281 requires forward_range<const _Vp>
7282 && forward_range<const _Pattern>
7283 && is_reference_v<range_reference_t<const _Vp>>
7284 && input_range<range_reference_t<const _Vp>>
7285 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7290 constexpr bool __use_const
7291 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7292 if constexpr (is_reference_v<_InnerRange>
7293 && forward_range<_Vp> && common_range<_Vp>
7294 && forward_range<_InnerRange> && common_range<_InnerRange>)
7295 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7297 return _Sentinel<__use_const>{*this};
7302 requires forward_range<const _Vp>
7303 && forward_range<const _Pattern>
7304 && is_reference_v<range_reference_t<const _Vp>>
7305 && input_range<range_reference_t<const _Vp>>
7307 using _InnerConstRange = range_reference_t<const _Vp>;
7308 if constexpr (forward_range<_InnerConstRange>
7309 && common_range<const _Vp>
7310 && common_range<_InnerConstRange>)
7311 return _Iterator<true>{*this, ranges::end(_M_base)};
7313 return _Sentinel<true>{*this};
7317 template<typename _Range, typename _Pattern>
7318 join_with_view(_Range&&, _Pattern&&)
7319 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7321 template<input_range _Range>
7322 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7323 -> join_with_view<views::all_t<_Range>,
7324 single_view<range_value_t<range_reference_t<_Range>>>>;
7326 template<input_range _Vp, forward_range _Pattern>
7327 requires view<_Vp> && view<_Pattern>
7328 && input_range<range_reference_t<_Vp>>
7329 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7330 template<bool _Const>
7331 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7333 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7334 using _Base = join_with_view::_Base<_Const>;
7335 using _InnerBase = join_with_view::_InnerBase<_Const>;
7336 using _PatternBase = join_with_view::_PatternBase<_Const>;
7338 using _OuterIter = join_with_view::_OuterIter<_Const>;
7339 using _InnerIter = join_with_view::_InnerIter<_Const>;
7340 using _PatternIter = join_with_view::_PatternIter<_Const>;
7342 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7344 _Parent* _M_parent = nullptr;
7345 [[no_unique_address]]
7346 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
7347 = decltype(_M_outer_it)();
7348 variant<_PatternIter, _InnerIter> _M_inner_it;
7350 constexpr _OuterIter&
7353 if constexpr (forward_range<_Base>)
7356 return *_M_parent->_M_outer_it;
7359 constexpr const _OuterIter&
7360 _M_get_outer() const
7362 if constexpr (forward_range<_Base>)
7365 return *_M_parent->_M_outer_it;
7369 _Iterator(_Parent& __parent, _OuterIter __outer)
7370 requires forward_range<_Base>
7371 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7373 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7375 auto&& __inner = _M_update_inner();
7376 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7382 _Iterator(_Parent& __parent)
7383 requires (!forward_range<_Base>)
7384 : _M_parent(std::__addressof(__parent))
7386 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7388 auto&& __inner = _M_update_inner();
7389 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7397 _OuterIter& __outer = _M_get_outer();
7398 if constexpr (_S_ref_is_glvalue)
7399 return __detail::__as_lvalue(*__outer);
7401 return _M_parent->_M_inner._M_emplace_deref(__outer);
7407 if constexpr (_S_ref_is_glvalue)
7408 return __detail::__as_lvalue(*_M_get_outer());
7410 return *_M_parent->_M_inner;
7418 if (_M_inner_it.index() == 0)
7420 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7423 auto&& __inner = _M_update_inner();
7424 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7428 auto&& __inner = _M_get_inner();
7429 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7432 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7434 if constexpr (_S_ref_is_glvalue)
7435 _M_inner_it.template emplace<0>();
7439 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7447 if constexpr (_S_ref_is_glvalue
7448 && bidirectional_range<_Base>
7449 && __detail::__bidirectional_common<_InnerBase>
7450 && __detail::__bidirectional_common<_PatternBase>)
7451 return bidirectional_iterator_tag{};
7452 else if constexpr (_S_ref_is_glvalue
7453 && forward_range<_Base>
7454 && forward_range<_InnerBase>)
7455 return forward_iterator_tag{};
7457 return input_iterator_tag{};
7460 friend join_with_view;
7463 using iterator_concept = decltype(_S_iter_concept());
7464 // iterator_category defined in join_with_view::__iter_cat
7465 using value_type = common_type_t<iter_value_t<_InnerIter>,
7466 iter_value_t<_PatternIter>>;
7467 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7468 iter_difference_t<_InnerIter>,
7469 iter_difference_t<_PatternIter>>;
7471 _Iterator() = default;
7474 _Iterator(_Iterator<!_Const> __i)
7476 && convertible_to<iterator_t<_Vp>, _OuterIter>
7477 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7478 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7479 : _M_parent(__i._M_parent),
7480 _M_outer_it(std::move(__i._M_outer_it))
7482 if (__i._M_inner_it.index() == 0)
7483 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7485 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7488 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7489 iter_reference_t<_PatternIter>>
7492 if (_M_inner_it.index() == 0)
7493 return *std::get<0>(_M_inner_it);
7495 return *std::get<1>(_M_inner_it);
7498 constexpr _Iterator&
7501 if (_M_inner_it.index() == 0)
7502 ++std::get<0>(_M_inner_it);
7504 ++std::get<1>(_M_inner_it);
7515 requires _S_ref_is_glvalue
7516 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7518 _Iterator __tmp = *this;
7523 constexpr _Iterator&
7525 requires _S_ref_is_glvalue
7526 && bidirectional_range<_Base>
7527 && __detail::__bidirectional_common<_InnerBase>
7528 && __detail::__bidirectional_common<_PatternBase>
7530 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7532 auto&& __inner = *--_M_outer_it;
7533 _M_inner_it.template emplace<1>(ranges::end(__inner));
7538 if (_M_inner_it.index() == 0)
7540 auto& __it = std::get<0>(_M_inner_it);
7541 if (__it == ranges::begin(_M_parent->_M_pattern))
7543 auto&& __inner = *--_M_outer_it;
7544 _M_inner_it.template emplace<1>(ranges::end(__inner));
7551 auto& __it = std::get<1>(_M_inner_it);
7552 auto&& __inner = *_M_outer_it;
7553 if (__it == ranges::begin(__inner))
7554 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7560 if (_M_inner_it.index() == 0)
7561 --std::get<0>(_M_inner_it);
7563 --std::get<1>(_M_inner_it);
7569 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7570 && __detail::__bidirectional_common<_InnerBase>
7571 && __detail::__bidirectional_common<_PatternBase>
7573 _Iterator __tmp = *this;
7578 friend constexpr bool
7579 operator==(const _Iterator& __x, const _Iterator& __y)
7580 requires _S_ref_is_glvalue
7581 && forward_range<_Base> && equality_comparable<_InnerIter>
7582 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7584 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7585 iter_rvalue_reference_t<_PatternIter>>
7586 iter_move(const _Iterator& __x)
7588 if (__x._M_inner_it.index() == 0)
7589 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7591 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7594 friend constexpr void
7595 iter_swap(const _Iterator& __x, const _Iterator& __y)
7596 requires indirectly_swappable<_InnerIter, _PatternIter>
7598 if (__x._M_inner_it.index() == 0)
7600 if (__y._M_inner_it.index() == 0)
7601 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7603 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7607 if (__y._M_inner_it.index() == 0)
7608 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7610 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7615 template<input_range _Vp, forward_range _Pattern>
7616 requires view<_Vp> && view<_Pattern>
7617 && input_range<range_reference_t<_Vp>>
7618 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7619 template<bool _Const>
7620 class join_with_view<_Vp, _Pattern>::_Sentinel
7622 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7623 using _Base = join_with_view::_Base<_Const>;
7625 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7628 _Sentinel(_Parent& __parent)
7629 : _M_end(ranges::end(__parent._M_base))
7632 friend join_with_view;
7635 _Sentinel() = default;
7638 _Sentinel(_Sentinel<!_Const> __s)
7639 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7640 : _M_end(std::move(__s._M_end))
7643 template<bool _OtherConst>
7644 requires sentinel_for<sentinel_t<_Base>,
7645 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7646 friend constexpr bool
7647 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7648 { return __x._M_get_outer() == __y._M_end; }
7655 template<typename _Range, typename _Pattern>
7656 concept __can_join_with_view
7657 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7658 } // namespace __detail
7660 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7662 template<viewable_range _Range, typename _Pattern>
7663 requires __detail::__can_join_with_view<_Range, _Pattern>
7665 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7667 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7670 using _RangeAdaptor<_JoinWith>::operator();
7671 static constexpr int _S_arity = 2;
7672 template<typename _Pattern>
7673 static constexpr bool _S_has_simple_extra_args
7674 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7677 inline constexpr _JoinWith join_with;
7678 } // namespace views
7679#endif // __cpp_lib_ranges_join_with
7681#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7682 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7683 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7684 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7685 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7687 __detail::__box<_Tp> _M_value;
7688 [[no_unique_address]] _Bound _M_bound = _Bound();
7692 template<typename _Range>
7693 friend constexpr auto
7694 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7696 template<typename _Range>
7697 friend constexpr auto
7698 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7701 repeat_view() requires default_initializable<_Tp> = default;
7704 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7705 requires copy_constructible<_Tp>
7706 : _M_value(__value), _M_bound(__bound)
7708 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7709 __glibcxx_assert(__bound >= 0);
7713 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7714 : _M_value(std::move(__value)), _M_bound(__bound)
7717 template<typename... _Args, typename... _BoundArgs>
7718 requires constructible_from<_Tp, _Args...>
7719 && constructible_from<_Bound, _BoundArgs...>
7721 repeat_view(piecewise_construct_t,
7722 tuple<_Args...> __args,
7723 tuple<_BoundArgs...> __bound_args = tuple<>{})
7724 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7725 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7730 { return _Iterator(std::__addressof(*_M_value)); }
7733 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7734 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7736 constexpr unreachable_sentinel_t
7737 end() const noexcept
7738 { return unreachable_sentinel; }
7741 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7742 { return __detail::__to_unsigned_like(_M_bound); }
7745 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7746 // 4053. Unary call to std::views::repeat does not decay the argument
7747 template<typename _Tp, typename _Bound = unreachable_sentinel_t>
7748 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7750 template<move_constructible _Tp, semiregular _Bound>
7751 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7752 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7753 class repeat_view<_Tp, _Bound>::_Iterator
7756 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7758 const _Tp* _M_value = nullptr;
7759 __index_type _M_current = __index_type();
7762 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7763 : _M_value(__value), _M_current(__bound)
7765 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7766 __glibcxx_assert(__bound >= 0);
7772 using iterator_concept = random_access_iterator_tag;
7773 using iterator_category = random_access_iterator_tag;
7774 using value_type = _Tp;
7775 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7777 __detail::__iota_diff_t<__index_type>>;
7779 _Iterator() = default;
7781 constexpr const _Tp&
7782 operator*() const noexcept
7783 { return *_M_value; }
7785 constexpr _Iterator&
7800 constexpr _Iterator&
7803 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7804 __glibcxx_assert(_M_current > 0);
7817 constexpr _Iterator&
7818 operator+=(difference_type __n)
7820 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7821 __glibcxx_assert(_M_current + __n >= 0);
7826 constexpr _Iterator&
7827 operator-=(difference_type __n)
7829 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7830 __glibcxx_assert(_M_current - __n >= 0);
7835 constexpr const _Tp&
7836 operator[](difference_type __n) const noexcept
7837 { return *(*this + __n); }
7839 friend constexpr bool
7840 operator==(const _Iterator& __x, const _Iterator& __y)
7841 { return __x._M_current == __y._M_current; }
7843 friend constexpr auto
7844 operator<=>(const _Iterator& __x, const _Iterator& __y)
7845 { return __x._M_current <=> __y._M_current; }
7847 friend constexpr _Iterator
7848 operator+(_Iterator __i, difference_type __n)
7854 friend constexpr _Iterator
7855 operator+(difference_type __n, _Iterator __i)
7856 { return __i + __n; }
7858 friend constexpr _Iterator
7859 operator-(_Iterator __i, difference_type __n)
7865 friend constexpr difference_type
7866 operator-(const _Iterator& __x, const _Iterator& __y)
7868 return (static_cast<difference_type>(__x._M_current)
7869 - static_cast<difference_type>(__y._M_current));
7877 template<typename _Tp, typename _Bound>
7878 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7880 template<typename _Tp>
7881 concept __can_repeat_view
7882 = requires { repeat_view(std::declval<_Tp>()); };
7884 template<typename _Tp, typename _Bound>
7885 concept __can_bounded_repeat_view
7886 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7891 template<typename _Tp>
7892 requires __detail::__can_repeat_view<_Tp>
7894 operator() [[nodiscard]] (_Tp&& __value) const
7896 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7897 // 4054. Repeating a repeat_view should repeat the view
7898 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7901 template<typename _Tp, typename _Bound>
7902 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7904 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7905 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7908 inline constexpr _Repeat repeat;
7912 template<typename _Range>
7914 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7916 using _Tp = remove_cvref_t<_Range>;
7917 static_assert(__is_repeat_view<_Tp>);
7918 if constexpr (sized_range<_Tp>)
7919 return views::repeat(*std::forward<_Range>(__r)._M_value,
7920 std::min(ranges::distance(__r), __n));
7922 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7925 template<typename _Range>
7927 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7929 using _Tp = remove_cvref_t<_Range>;
7930 static_assert(__is_repeat_view<_Tp>);
7931 if constexpr (sized_range<_Tp>)
7933 auto __sz = ranges::distance(__r);
7934 return views::repeat(*std::forward<_Range>(__r)._M_value,
7935 __sz - std::min(__sz, __n));
7942#endif // __cpp_lib_ranges_repeat
7944#ifdef __cpp_lib_ranges_stride // C++ >= 23
7945 template<input_range _Vp>
7947 class stride_view : public view_interface<stride_view<_Vp>>
7950 range_difference_t<_Vp> _M_stride;
7952 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7954 template<bool _Const>
7958 template<bool _Const>
7959 requires forward_range<_Base<_Const>>
7960 struct __iter_cat<_Const>
7966 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7967 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7968 return random_access_iterator_tag{};
7973 using iterator_category = decltype(_S_iter_cat());
7976 template<bool> class _Iterator;
7980 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7981 : _M_base(std::move(__base)), _M_stride(__stride)
7982 { __glibcxx_assert(__stride > 0); }
7985 base() const& requires copy_constructible<_Vp>
7990 { return std::move(_M_base); }
7992 constexpr range_difference_t<_Vp>
7993 stride() const noexcept
7994 { return _M_stride; }
7997 begin() requires (!__detail::__simple_view<_Vp>)
7998 { return _Iterator<false>(this, ranges::begin(_M_base)); }
8001 begin() const requires range<const _Vp>
8002 { return _Iterator<true>(this, ranges::begin(_M_base)); }
8005 end() requires (!__detail::__simple_view<_Vp>)
8007 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8009 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8010 return _Iterator<false>(this, ranges::end(_M_base), __missing);
8012 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8013 return _Iterator<false>(this, ranges::end(_M_base));
8015 return default_sentinel;
8019 end() const requires range<const _Vp>
8021 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8022 && forward_range<const _Vp>)
8024 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8025 return _Iterator<true>(this, ranges::end(_M_base), __missing);
8027 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8028 return _Iterator<true>(this, ranges::end(_M_base));
8030 return default_sentinel;
8034 size() requires sized_range<_Vp>
8036 return __detail::__to_unsigned_like
8037 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8041 size() const requires sized_range<const _Vp>
8043 return __detail::__to_unsigned_like
8044 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8048 template<typename _Range>
8049 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8051 template<typename _Vp>
8052 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8053 = enable_borrowed_range<_Vp>;
8055 template<input_range _Vp>
8057 template<bool _Const>
8058 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8060 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8061 using _Base = stride_view::_Base<_Const>;
8063 iterator_t<_Base> _M_current = iterator_t<_Base>();
8064 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8065 range_difference_t<_Base> _M_stride = 0;
8066 range_difference_t<_Base> _M_missing = 0;
8069 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8070 range_difference_t<_Base> __missing = 0)
8071 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8072 _M_stride(__parent->_M_stride), _M_missing(__missing)
8078 if constexpr (random_access_range<_Base>)
8079 return random_access_iterator_tag{};
8080 else if constexpr (bidirectional_range<_Base>)
8081 return bidirectional_iterator_tag{};
8082 else if constexpr (forward_range<_Base>)
8083 return forward_iterator_tag{};
8085 return input_iterator_tag{};
8091 using difference_type = range_difference_t<_Base>;
8092 using value_type = range_value_t<_Base>;
8093 using iterator_concept = decltype(_S_iter_concept());
8094 // iterator_category defined in stride_view::__iter_cat
8096 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8099 _Iterator(_Iterator<!_Const> __other)
8101 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8102 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8103 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8104 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8107 constexpr iterator_t<_Base>
8109 { return std::move(_M_current); }
8111 constexpr const iterator_t<_Base>&
8112 base() const & noexcept
8113 { return _M_current; }
8115 constexpr decltype(auto)
8117 { return *_M_current; }
8119 constexpr _Iterator&
8122 __glibcxx_assert(_M_current != _M_end);
8123 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8132 operator++(int) requires forward_range<_Base>
8139 constexpr _Iterator&
8140 operator--() requires bidirectional_range<_Base>
8142 ranges::advance(_M_current, _M_missing - _M_stride);
8148 operator--(int) requires bidirectional_range<_Base>
8155 constexpr _Iterator&
8156 operator+=(difference_type __n) requires random_access_range<_Base>
8160 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8161 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8165 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8171 constexpr _Iterator&
8172 operator-=(difference_type __n) requires random_access_range<_Base>
8173 { return *this += -__n; }
8175 constexpr decltype(auto) operator[](difference_type __n) const
8176 requires random_access_range<_Base>
8177 { return *(*this + __n); }
8179 friend constexpr bool
8180 operator==(const _Iterator& __x, default_sentinel_t)
8181 { return __x._M_current == __x._M_end; }
8183 friend constexpr bool
8184 operator==(const _Iterator& __x, const _Iterator& __y)
8185 requires equality_comparable<iterator_t<_Base>>
8186 { return __x._M_current == __y._M_current; }
8188 friend constexpr bool
8189 operator<(const _Iterator& __x, const _Iterator& __y)
8190 requires random_access_range<_Base>
8191 { return __x._M_current < __y._M_current; }
8193 friend constexpr bool
8194 operator>(const _Iterator& __x, const _Iterator& __y)
8195 requires random_access_range<_Base>
8196 { return __y._M_current < __x._M_current; }
8198 friend constexpr bool
8199 operator<=(const _Iterator& __x, const _Iterator& __y)
8200 requires random_access_range<_Base>
8201 { return !(__y._M_current < __x._M_current); }
8203 friend constexpr bool
8204 operator>=(const _Iterator& __x, const _Iterator& __y)
8205 requires random_access_range<_Base>
8206 { return !(__x._M_current < __y._M_current); }
8208 friend constexpr auto
8209 operator<=>(const _Iterator& __x, const _Iterator& __y)
8210 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8211 { return __x._M_current <=> __y._M_current; }
8213 friend constexpr _Iterator
8214 operator+(const _Iterator& __i, difference_type __n)
8215 requires random_access_range<_Base>
8222 friend constexpr _Iterator
8223 operator+(difference_type __n, const _Iterator& __i)
8224 requires random_access_range<_Base>
8225 { return __i + __n; }
8227 friend constexpr _Iterator
8228 operator-(const _Iterator& __i, difference_type __n)
8229 requires random_access_range<_Base>
8236 friend constexpr difference_type
8237 operator-(const _Iterator& __x, const _Iterator& __y)
8238 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8240 auto __n = __x._M_current - __y._M_current;
8241 if constexpr (forward_range<_Base>)
8242 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8244 return -__detail::__div_ceil(-__n, __x._M_stride);
8246 return __detail::__div_ceil(__n, __x._M_stride);
8249 friend constexpr difference_type
8250 operator-(default_sentinel_t, const _Iterator& __x)
8251 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8252 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8254 friend constexpr difference_type
8255 operator-(const _Iterator& __x, default_sentinel_t __y)
8256 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8257 { return -(__y - __x); }
8259 friend constexpr range_rvalue_reference_t<_Base>
8260 iter_move(const _Iterator& __i)
8261 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8262 { return ranges::iter_move(__i._M_current); }
8264 friend constexpr void
8265 iter_swap(const _Iterator& __x, const _Iterator& __y)
8266 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8267 requires indirectly_swappable<iterator_t<_Base>>
8268 { ranges::iter_swap(__x._M_current, __y._M_current); }
8275 template<typename _Range, typename _Dp>
8276 concept __can_stride_view
8277 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8280 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8282 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8283 requires __detail::__can_stride_view<_Range, _Dp>
8285 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8286 { return stride_view(std::forward<_Range>(__r), __n); }
8288 using __adaptor::_RangeAdaptor<_Stride>::operator();
8289 static constexpr int _S_arity = 2;
8290 static constexpr bool _S_has_simple_extra_args = true;
8293 inline constexpr _Stride stride;
8295#endif // __cpp_lib_ranges_stride
8297#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8300 template<bool _Const, typename _First, typename... _Vs>
8301 concept __cartesian_product_is_random_access
8302 = (random_access_range<__maybe_const_t<_Const, _First>>
8304 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8305 && sized_range<__maybe_const_t<_Const, _Vs>>));
8307 template<typename _Range>
8308 concept __cartesian_product_common_arg
8309 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8311 template<bool _Const, typename _First, typename... _Vs>
8312 concept __cartesian_product_is_bidirectional
8313 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8315 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8316 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8318 template<typename _First, typename... _Vs>
8319 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8321 template<typename... _Vs>
8322 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8324 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8325 concept __cartesian_is_sized_sentinel
8326 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8327 iterator_t<__maybe_const_t<_Const, _First>>>
8329 && (sized_range<__maybe_const_t<_Const, _Vs>>
8330 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8331 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8333 template<__cartesian_product_common_arg _Range>
8335 __cartesian_common_arg_end(_Range& __r)
8337 if constexpr (common_range<_Range>)
8338 return ranges::end(__r);
8340 return ranges::begin(__r) + ranges::distance(__r);
8342 } // namespace __detail
8344 template<input_range _First, forward_range... _Vs>
8345 requires (view<_First> && ... && view<_Vs>)
8346 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8348 tuple<_First, _Vs...> _M_bases;
8350 template<bool> class _Iterator;
8353 _S_difference_type()
8355 // TODO: Implement the recommended practice of using the smallest
8356 // sufficiently wide type according to the maximum sizes of the
8357 // underlying ranges?
8358 return common_type_t<ptrdiff_t,
8359 range_difference_t<_First>,
8360 range_difference_t<_Vs>...>{};
8364 cartesian_product_view() = default;
8367 cartesian_product_view(_First __first, _Vs... __rest)
8368 : _M_bases(std::move(__first), std::move(__rest)...)
8371 constexpr _Iterator<false>
8372 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8373 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8375 constexpr _Iterator<true>
8376 begin() const requires (range<const _First> && ... && range<const _Vs>)
8377 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8379 constexpr _Iterator<false>
8380 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8381 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8383 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8384 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8385 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8386 auto& __first = std::get<0>(_M_bases);
8387 return _Ret{(__empty_tail
8388 ? ranges::begin(__first)
8389 : __detail::__cartesian_common_arg_end(__first)),
8390 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8391 }(make_index_sequence<sizeof...(_Vs)>{});
8393 return _Iterator<false>{*this, std::move(__its)};
8396 constexpr _Iterator<true>
8397 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8399 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8400 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8401 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8402 auto& __first = std::get<0>(_M_bases);
8403 return _Ret{(__empty_tail
8404 ? ranges::begin(__first)
8405 : __detail::__cartesian_common_arg_end(__first)),
8406 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8407 }(make_index_sequence<sizeof...(_Vs)>{});
8409 return _Iterator<true>{*this, std::move(__its)};
8412 constexpr default_sentinel_t
8413 end() const noexcept
8414 { return default_sentinel; }
8417 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8419 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8420 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8421 auto __size = static_cast<_ST>(1);
8422#ifdef _GLIBCXX_ASSERTIONS
8423 if constexpr (integral<_ST>)
8426 = (__builtin_mul_overflow(__size,
8427 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8430 __glibcxx_assert(!__overflow);
8434 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8436 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8440 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8442 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8443 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8444 auto __size = static_cast<_ST>(1);
8445#ifdef _GLIBCXX_ASSERTIONS
8446 if constexpr (integral<_ST>)
8449 = (__builtin_mul_overflow(__size,
8450 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8453 __glibcxx_assert(!__overflow);
8457 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8459 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8463 template<typename... _Vs>
8464 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8466 template<input_range _First, forward_range... _Vs>
8467 requires (view<_First> && ... && view<_Vs>)
8468 template<bool _Const>
8469 class cartesian_product_view<_First, _Vs...>::_Iterator
8471 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8472 _Parent* _M_parent = nullptr;
8473 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8474 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8477 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8478 : _M_parent(std::__addressof(__parent)),
8479 _M_current(std::move(__current))
8485 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8486 return random_access_iterator_tag{};
8487 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8488 return bidirectional_iterator_tag{};
8489 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8490 return forward_iterator_tag{};
8492 return input_iterator_tag{};
8495 friend cartesian_product_view;
8498 using iterator_category = input_iterator_tag;
8499 using iterator_concept = decltype(_S_iter_concept());
8501 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8502 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8504 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8505 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8506 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8508 _Iterator() = default;
8511 _Iterator(_Iterator<!_Const> __i)
8513 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8514 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8515 : _M_parent(std::__addressof(__i._M_parent)),
8516 _M_current(std::move(__i._M_current))
8522 auto __f = [](auto& __i) -> decltype(auto) {
8525 return __detail::__tuple_transform(__f, _M_current);
8528 constexpr _Iterator&
8540 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8547 constexpr _Iterator&
8549 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8557 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8564 constexpr _Iterator&
8565 operator+=(difference_type __x)
8566 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8572 constexpr _Iterator&
8573 operator-=(difference_type __x)
8574 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8575 { return *this += -__x; }
8578 operator[](difference_type __n) const
8579 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8580 { return *((*this) + __n); }
8582 friend constexpr bool
8583 operator==(const _Iterator& __x, const _Iterator& __y)
8584 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8585 { return __x._M_current == __y._M_current; }
8587 friend constexpr bool
8588 operator==(const _Iterator& __x, default_sentinel_t)
8590 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8591 return ((std::get<_Is>(__x._M_current)
8592 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8594 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8597 friend constexpr auto
8598 operator<=>(const _Iterator& __x, const _Iterator& __y)
8599 requires __detail::__all_random_access<_Const, _First, _Vs...>
8600 { return __x._M_current <=> __y._M_current; }
8602 friend constexpr _Iterator
8603 operator+(_Iterator __x, difference_type __y)
8604 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8605 { return __x += __y; }
8607 friend constexpr _Iterator
8608 operator+(difference_type __x, _Iterator __y)
8609 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8610 { return __y += __x; }
8612 friend constexpr _Iterator
8613 operator-(_Iterator __x, difference_type __y)
8614 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8615 { return __x -= __y; }
8617 friend constexpr difference_type
8618 operator-(const _Iterator& __x, const _Iterator& __y)
8619 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8620 { return __x._M_distance_from(__y._M_current); }
8622 friend constexpr difference_type
8623 operator-(const _Iterator& __i, default_sentinel_t)
8624 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8626 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8627 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8628 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8629 }(make_index_sequence<sizeof...(_Vs)>{});
8630 return __i._M_distance_from(__end_tuple);
8633 friend constexpr difference_type
8634 operator-(default_sentinel_t, const _Iterator& __i)
8635 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8636 { return -(__i - default_sentinel); }
8638 friend constexpr auto
8639 iter_move(const _Iterator& __i)
8640 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8642 friend constexpr void
8643 iter_swap(const _Iterator& __l, const _Iterator& __r)
8644 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8646 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8648 [&]<size_t... _Is>(index_sequence<_Is...>) {
8649 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8650 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8654 template<size_t _Nm = sizeof...(_Vs)>
8658 auto& __it = std::get<_Nm>(_M_current);
8660 if constexpr (_Nm > 0)
8661 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8663 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8668 template<size_t _Nm = sizeof...(_Vs)>
8672 auto& __it = std::get<_Nm>(_M_current);
8673 if constexpr (_Nm > 0)
8674 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8676 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8682 template<size_t _Nm = sizeof...(_Vs)>
8684 _M_advance(difference_type __x)
8685 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8693 // Constant time iterator advancement.
8694 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8695 auto& __it = std::get<_Nm>(_M_current);
8696 if constexpr (_Nm == 0)
8698#ifdef _GLIBCXX_ASSERTIONS
8699 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8701 auto __size = ranges::ssize(__r);
8702 auto __begin = ranges::begin(__r);
8703 auto __offset = __it - __begin;
8704 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8711 auto __size = ranges::ssize(__r);
8712 auto __begin = ranges::begin(__r);
8713 auto __offset = __it - __begin;
8715 __x = __offset / __size;
8719 __offset = __size + __offset;
8722 __it = __begin + __offset;
8723 _M_advance<_Nm - 1>(__x);
8728 template<typename _Tuple>
8729 constexpr difference_type
8730 _M_distance_from(const _Tuple& __t) const
8732 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8733 auto __sum = static_cast<difference_type>(0);
8734#ifdef _GLIBCXX_ASSERTIONS
8735 if constexpr (integral<difference_type>)
8738 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8740 __glibcxx_assert(!__overflow);
8744 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8746 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8749 template<size_t _Nm, typename _Tuple>
8750 constexpr difference_type
8751 _M_scaled_distance(const _Tuple& __t) const
8753 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8754 - std::get<_Nm>(__t));
8755#ifdef _GLIBCXX_ASSERTIONS
8756 if constexpr (integral<difference_type>)
8758 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8759 __glibcxx_assert(!__overflow);
8763 __dist *= _M_scaled_size<_Nm+1>();
8767 template<size_t _Nm>
8768 constexpr difference_type
8769 _M_scaled_size() const
8771 if constexpr (_Nm <= sizeof...(_Vs))
8773 auto __size = static_cast<difference_type>(ranges::size
8774 (std::get<_Nm>(_M_parent->_M_bases)));
8775#ifdef _GLIBCXX_ASSERTIONS
8776 if constexpr (integral<difference_type>)
8778 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8779 __glibcxx_assert(!__overflow);
8783 __size *= _M_scaled_size<_Nm+1>();
8787 return static_cast<difference_type>(1);
8795 template<typename... _Ts>
8796 concept __can_cartesian_product_view
8797 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8800 struct _CartesianProduct
8802 template<typename... _Ts>
8803 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8805 operator() [[nodiscard]] (_Ts&&... __ts) const
8807 if constexpr (sizeof...(_Ts) == 0)
8808 return views::single(tuple{});
8810 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8814 inline constexpr _CartesianProduct cartesian_product;
8816#endif // __cpp_lib_ranges_cartesian_product
8818#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8819 template<input_range _Vp>
8821 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8823 _Vp _M_base = _Vp();
8826 as_rvalue_view() requires default_initializable<_Vp> = default;
8829 as_rvalue_view(_Vp __base)
8830 : _M_base(std::move(__base))
8834 base() const& requires copy_constructible<_Vp>
8839 { return std::move(_M_base); }
8842 begin() requires (!__detail::__simple_view<_Vp>)
8843 { return move_iterator(ranges::begin(_M_base)); }
8846 begin() const requires range<const _Vp>
8847 { return move_iterator(ranges::begin(_M_base)); }
8850 end() requires (!__detail::__simple_view<_Vp>)
8852 if constexpr (common_range<_Vp>)
8853 return move_iterator(ranges::end(_M_base));
8855 return move_sentinel(ranges::end(_M_base));
8859 end() const requires range<const _Vp>
8861 if constexpr (common_range<const _Vp>)
8862 return move_iterator(ranges::end(_M_base));
8864 return move_sentinel(ranges::end(_M_base));
8868 size() requires sized_range<_Vp>
8869 { return ranges::size(_M_base); }
8872 size() const requires sized_range<const _Vp>
8873 { return ranges::size(_M_base); }
8876 template<typename _Range>
8877 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8879 template<typename _Tp>
8880 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8881 = enable_borrowed_range<_Tp>;
8887 template<typename _Tp>
8888 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8891 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8893 template<viewable_range _Range>
8894 requires __detail::__can_as_rvalue_view<_Range>
8896 operator() [[nodiscard]] (_Range&& __r) const
8898 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8899 range_reference_t<_Range>>)
8900 return views::all(std::forward<_Range>(__r));
8902 return as_rvalue_view(std::forward<_Range>(__r));
8906 inline constexpr _AsRvalue as_rvalue;
8908#endif // __cpp_lib_as_rvalue
8910#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8913 template<typename _Range>
8914 concept __range_with_movable_reference = input_range<_Range>
8915 && move_constructible<range_reference_t<_Range>>
8916 && move_constructible<range_rvalue_reference_t<_Range>>;
8920 requires __detail::__range_with_movable_reference<_Vp>
8921 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8923 _Vp _M_base = _Vp();
8925 template<bool _Const> class _Iterator;
8926 template<bool _Const> class _Sentinel;
8929 enumerate_view() requires default_initializable<_Vp> = default;
8932 enumerate_view(_Vp __base)
8933 : _M_base(std::move(__base))
8937 begin() requires (!__detail::__simple_view<_Vp>)
8938 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8941 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8942 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8945 end() requires (!__detail::__simple_view<_Vp>)
8947 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8948 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8950 return _Sentinel<false>(ranges::end(_M_base));
8954 end() const requires __detail::__range_with_movable_reference<const _Vp>
8956 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8957 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8959 return _Sentinel<true>(ranges::end(_M_base));
8963 size() requires sized_range<_Vp>
8964 { return ranges::size(_M_base); }
8967 size() const requires sized_range<const _Vp>
8968 { return ranges::size(_M_base); }
8971 base() const & requires copy_constructible<_Vp>
8976 { return std::move(_M_base); }
8979 template<typename _Range>
8980 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
8982 template<typename _Tp>
8983 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
8984 = enable_borrowed_range<_Tp>;
8987 requires __detail::__range_with_movable_reference<_Vp>
8988 template<bool _Const>
8989 class enumerate_view<_Vp>::_Iterator
8991 using _Base = __maybe_const_t<_Const, _Vp>;
8996 if constexpr (random_access_range<_Base>)
8997 return random_access_iterator_tag{};
8998 else if constexpr (bidirectional_range<_Base>)
8999 return bidirectional_iterator_tag{};
9000 else if constexpr (forward_range<_Base>)
9001 return forward_iterator_tag{};
9003 return input_iterator_tag{};
9006 friend enumerate_view;
9009 using iterator_category = input_iterator_tag;
9010 using iterator_concept = decltype(_S_iter_concept());
9011 using difference_type = range_difference_t<_Base>;
9012 using value_type = tuple<difference_type, range_value_t<_Base>>;
9015 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9017 iterator_t<_Base> _M_current = iterator_t<_Base>();
9018 difference_type _M_pos = 0;
9021 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9022 : _M_current(std::move(__current)), _M_pos(__pos)
9026 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
9029 _Iterator(_Iterator<!_Const> __i)
9030 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9031 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9034 constexpr const iterator_t<_Base> &
9035 base() const & noexcept
9036 { return _M_current; }
9038 constexpr iterator_t<_Base>
9040 { return std::move(_M_current); }
9042 constexpr difference_type
9043 index() const noexcept
9048 { return __reference_type(_M_pos, *_M_current); }
9050 constexpr _Iterator&
9063 operator++(int) requires forward_range<_Base>
9070 constexpr _Iterator&
9071 operator--() requires bidirectional_range<_Base>
9079 operator--(int) requires bidirectional_range<_Base>
9086 constexpr _Iterator&
9087 operator+=(difference_type __n) requires random_access_range<_Base>
9094 constexpr _Iterator&
9095 operator-=(difference_type __n) requires random_access_range<_Base>
9103 operator[](difference_type __n) const requires random_access_range<_Base>
9104 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9106 friend constexpr bool
9107 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9108 { return __x._M_pos == __y._M_pos; }
9110 friend constexpr strong_ordering
9111 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9112 { return __x._M_pos <=> __y._M_pos; }
9114 friend constexpr _Iterator
9115 operator+(const _Iterator& __x, difference_type __y)
9116 requires random_access_range<_Base>
9117 { return (auto(__x) += __y); }
9119 friend constexpr _Iterator
9120 operator+(difference_type __x, const _Iterator& __y)
9121 requires random_access_range<_Base>
9122 { return auto(__y) += __x; }
9124 friend constexpr _Iterator
9125 operator-(const _Iterator& __x, difference_type __y)
9126 requires random_access_range<_Base>
9127 { return auto(__x) -= __y; }
9129 friend constexpr difference_type
9130 operator-(const _Iterator& __x, const _Iterator& __y) noexcept
9131 { return __x._M_pos - __y._M_pos; }
9133 friend constexpr auto
9134 iter_move(const _Iterator& __i)
9135 noexcept(noexcept(ranges::iter_move(__i._M_current))
9136 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9138 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9139 (__i._M_pos, ranges::iter_move(__i._M_current));
9144 requires __detail::__range_with_movable_reference<_Vp>
9145 template<bool _Const>
9146 class enumerate_view<_Vp>::_Sentinel
9148 using _Base = __maybe_const_t<_Const, _Vp>;
9150 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9153 _Sentinel(sentinel_t<_Base> __end)
9154 : _M_end(std::move(__end))
9157 friend enumerate_view;
9160 _Sentinel() = default;
9163 _Sentinel(_Sentinel<!_Const> __other)
9164 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9165 : _M_end(std::move(__other._M_end))
9168 constexpr sentinel_t<_Base>
9172 template<bool _OtherConst>
9173 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9174 friend constexpr bool
9175 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9176 { return __x._M_current == __y._M_end; }
9178 template<bool _OtherConst>
9179 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9180 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9181 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9182 { return __x._M_current - __y._M_end; }
9184 template<bool _OtherConst>
9185 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9186 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9187 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9188 { return __x._M_end - __y._M_current; }
9195 template<typename _Tp>
9196 concept __can_enumerate_view
9197 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9200 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9202 template<viewable_range _Range>
9203 requires __detail::__can_enumerate_view<_Range>
9205 operator() [[nodiscard]] (_Range&& __r) const
9206 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9209 inline constexpr _Enumerate enumerate;
9211#endif // __cpp_lib_ranges_enumerate
9213#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9215 requires input_range<_Vp>
9216 class as_const_view : public view_interface<as_const_view<_Vp>>
9218 _Vp _M_base = _Vp();
9221 as_const_view() requires default_initializable<_Vp> = default;
9224 as_const_view(_Vp __base)
9225 noexcept(is_nothrow_move_constructible_v<_Vp>)
9226 : _M_base(std::move(__base))
9231 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9232 requires copy_constructible<_Vp>
9237 noexcept(is_nothrow_move_constructible_v<_Vp>)
9238 { return std::move(_M_base); }
9241 begin() requires (!__detail::__simple_view<_Vp>)
9242 { return ranges::cbegin(_M_base); }
9245 begin() const requires range<const _Vp>
9246 { return ranges::cbegin(_M_base); }
9249 end() requires (!__detail::__simple_view<_Vp>)
9250 { return ranges::cend(_M_base); }
9253 end() const requires range<const _Vp>
9254 { return ranges::cend(_M_base); }
9257 size() requires sized_range<_Vp>
9258 { return ranges::size(_M_base); }
9261 size() const requires sized_range<const _Vp>
9262 { return ranges::size(_M_base); }
9265 template<typename _Range>
9266 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9268 template<typename _Tp>
9269 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9270 = enable_borrowed_range<_Tp>;
9276 template<typename _Tp>
9277 inline constexpr bool __is_constable_ref_view = false;
9279 template<typename _Range>
9280 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9281 = constant_range<const _Range>;
9283 template<typename _Range>
9284 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9287 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9289 template<viewable_range _Range>
9291 operator()(_Range&& __r) const
9292 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9293 requires __detail::__can_as_const_view<_Range>
9295 using _Tp = remove_cvref_t<_Range>;
9296 using element_type = remove_reference_t<range_reference_t<_Range>>;
9297 if constexpr (constant_range<views::all_t<_Range>>)
9298 return views::all(std::forward<_Range>(__r));
9299 else if constexpr (__detail::__is_empty_view<_Tp>)
9300 return views::empty<const element_type>;
9301 else if constexpr (std::__detail::__is_span<_Tp>)
9302 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9303 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9304 return ref_view(std::as_const(std::forward<_Range>(__r).base()));
9305 else if constexpr (is_lvalue_reference_v<_Range>
9306 && constant_range<const _Tp>
9308 return ref_view(static_cast<const _Tp&>(__r));
9310 return as_const_view(std::forward<_Range>(__r));
9314 inline constexpr _AsConst as_const;
9316#endif // __cpp_lib_as_const
9317} // namespace ranges
9319 namespace views = ranges::views;
9321#if __cpp_lib_ranges_to_container // C++ >= 23
9324/// @cond undocumented
9327 template<typename _Container>
9328 constexpr bool __reservable_container
9329 = sized_range<_Container>
9330 && requires(_Container& __c, range_size_t<_Container> __n) {
9332 { __c.capacity() } -> same_as<decltype(__n)>;
9333 { __c.max_size() } -> same_as<decltype(__n)>;
9336 template<typename _Cont, typename _Range>
9337 constexpr bool __toable = requires {
9338 requires (!input_range<_Cont>
9339 || convertible_to<range_reference_t<_Range>,
9340 range_value_t<_Cont>>);
9342} // namespace __detail
9345 /// Convert a range to a container.
9347 * @tparam _Cont A container type.
9348 * @param __r A range that models the `input_range` concept.
9349 * @param __args... Arguments to pass to the container constructor.
9352 * This function converts a range to the `_Cont` type.
9354 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9355 * will convert the view to `std::vector<int>`.
9357 * Additional constructor arguments for the container can be supplied after
9358 * the input range argument, e.g.
9359 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9361 template<typename _Cont, input_range _Rg, typename... _Args>
9362 requires (!view<_Cont>)
9364 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9366 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9367 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9369 if constexpr (__detail::__toable<_Cont, _Rg>)
9371 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9372 return _Cont(std::forward<_Rg>(__r),
9373 std::forward<_Args>(__args)...);
9374 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9375 return _Cont(from_range, std::forward<_Rg>(__r),
9376 std::forward<_Args>(__args)...);
9377 else if constexpr (requires { requires common_range<_Rg>;
9378 typename __iter_category_t<iterator_t<_Rg>>;
9379 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9380 input_iterator_tag>;
9381 requires constructible_from<_Cont, iterator_t<_Rg>,
9382 sentinel_t<_Rg>, _Args...>;
9384 return _Cont(ranges::begin(__r), ranges::end(__r),
9385 std::forward<_Args>(__args)...);
9388 static_assert(constructible_from<_Cont, _Args...>);
9389 _Cont __c(std::forward<_Args>(__args)...);
9390 if constexpr (sized_range<_Rg>
9391 && __detail::__reservable_container<_Cont>)
9392 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9393 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9394 // 4016. container-insertable checks do not match what
9395 // container-inserter does
9396 auto __it = ranges::begin(__r);
9397 const auto __sent = ranges::end(__r);
9398 while (__it != __sent)
9400 if constexpr (requires { __c.emplace_back(*__it); })
9401 __c.emplace_back(*__it);
9402 else if constexpr (requires { __c.push_back(*__it); })
9403 __c.push_back(*__it);
9404 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9405 __c.emplace(__c.end(), *__it);
9407 __c.insert(__c.end(), *__it);
9415 static_assert(input_range<range_reference_t<_Rg>>);
9416 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9417 // 3984. ranges::to's recursion branch may be ill-formed
9418 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9419 []<typename _Elt>(_Elt&& __elem) {
9420 using _ValT = range_value_t<_Cont>;
9421 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9422 }), std::forward<_Args>(__args)...);
9426/// @cond undocumented
9429 template<typename _Rg>
9432 using iterator_category = input_iterator_tag;
9433 using value_type = range_value_t<_Rg>;
9434 using difference_type = ptrdiff_t;
9435 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9436 using reference = range_reference_t<_Rg>;
9437 reference operator*() const;
9438 pointer operator->() const;
9439 _InputIter& operator++();
9440 _InputIter operator++(int);
9441 bool operator==(const _InputIter&) const;
9444 template<template<typename...> typename _Cont, input_range _Rg,
9447 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9449 template<template<typename...> typename _Cont, input_range _Rg,
9452 = decltype(_Cont(from_range, std::declval<_Rg>(),
9453 std::declval<_Args>()...));
9455 template<template<typename...> typename _Cont, input_range _Rg,
9458 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9459 std::declval<_InputIter<_Rg>>(),
9460 std::declval<_Args>()...));
9462} // namespace __detail
9465 template<template<typename...> typename _Cont, input_range _Rg,
9468 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9470 using __detail::_DeduceExpr1;
9471 using __detail::_DeduceExpr2;
9472 using __detail::_DeduceExpr3;
9473 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9474 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9475 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9476 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9477 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9478 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9479 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9480 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9481 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9483 static_assert(false); // Cannot deduce container specialization.
9486/// @cond undocumented
9489 template<typename _Cont>
9492 template<typename _Range, typename... _Args>
9493 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9494 std::declval<_Args>()...); }
9496 operator()(_Range&& __r, _Args&&... __args) const
9498 return ranges::to<_Cont>(std::forward<_Range>(__r),
9499 std::forward<_Args>(__args)...);
9502} // namespace __detail
9505 /// ranges::to adaptor for converting a range to a container type
9507 * @tparam _Cont A container type.
9508 * @param __args... Arguments to pass to the container constructor.
9511 * This range adaptor returns a range adaptor closure object that converts
9512 * a range to the `_Cont` type.
9514 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9515 * will convert the view to `std::vector<int>`.
9517 * Additional constructor arguments for the container can be supplied, e.g.
9518 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9520 template<typename _Cont, typename... _Args>
9521 requires (!view<_Cont>)
9523 to [[nodiscard]] (_Args&&... __args)
9525 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9526 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9528 using __detail::_To;
9529 using views::__adaptor::_Partial;
9530 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9533/// @cond undocumented
9536 template<template<typename...> typename _Cont>
9539 template<typename _Range, typename... _Args>
9540 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9541 std::declval<_Args>()...); }
9543 operator()(_Range&& __r, _Args&&... __args) const
9545 return ranges::to<_Cont>(std::forward<_Range>(__r),
9546 std::forward<_Args>(__args)...);
9549} // namespace __detail
9552 /// ranges::to adaptor for converting a range to a deduced container type.
9554 * @tparam _Cont A container template.
9555 * @param __args... Arguments to pass to the container constructor.
9558 * This range adaptor returns a range adaptor closure object that converts
9559 * a range to a specialization of the `_Cont` class template. The specific
9560 * specialization of `_Cont` to be used is deduced automatically.
9562 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9563 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9564 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9566 * Additional constructor arguments for the container can be supplied, e.g.
9567 * `r | std::ranges::to<std::vector>(an_allocator)`.
9569 template<template<typename...> typename _Cont, typename... _Args>
9571 to [[nodiscard]] (_Args&&... __args)
9573 using __detail::_To2;
9574 using views::__adaptor::_Partial;
9575 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9578} // namespace ranges
9579#endif // __cpp_lib_ranges_to_container
9581#if __cpp_lib_ranges_concat // C++ >= C++26
9586 template<typename... _Rs>
9587 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9589 template<typename... _Rs>
9590 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9592 template<typename... _Rs>
9593 using __concat_rvalue_reference_t
9594 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9596 template<typename _Ref, typename _RRef, typename _It>
9597 concept __concat_indirectly_readable_impl = requires(const _It __it) {
9598 { *__it } -> convertible_to<_Ref>;
9599 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9602 template<typename... _Rs>
9603 concept __concat_indirectly_readable
9604 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9605 && common_reference_with<__concat_reference_t<_Rs...>&&,
9606 __concat_rvalue_reference_t<_Rs...>&&>
9607 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9608 __concat_value_t<_Rs...> const&>
9609 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9610 __concat_rvalue_reference_t<_Rs...>,
9614 template<typename... _Rs>
9615 concept __concatable = requires {
9616 typename __concat_reference_t<_Rs...>;
9617 typename __concat_value_t<_Rs...>;
9618 typename __concat_rvalue_reference_t<_Rs...>;
9619 } && __concat_indirectly_readable<_Rs...>;
9621 template<bool _Const, typename _Range, typename... _Rs>
9622 struct __all_but_last_common
9624 static inline constexpr bool value
9625 = requires { requires (common_range<__maybe_const_t<_Const, _Range>>
9626 && __all_but_last_common<_Const, _Rs...>::value); };
9629 template<bool _Const, typename _Range>
9630 struct __all_but_last_common<_Const, _Range>
9631 { static inline constexpr bool value = true; };
9633 template<bool _Const, typename... _Rs>
9634 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9635 && __all_but_last_common<_Const, _Rs...>::value;
9637 template<bool _Const, typename... _Rs>
9638 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9639 && __all_but_last_common<_Const, _Rs...>::value;
9641 template<typename _Range, typename... _Rs>
9642 struct __all_but_first_sized
9643 { static inline constexpr bool value = (sized_range<_Rs> && ...); };
9644 } // namespace __detail
9646 template<input_range... _Vs>
9647 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9648 class concat_view : public view_interface<concat_view<_Vs...>>
9650 tuple<_Vs...> _M_views;
9652 template<bool _Const> class _Iterator;
9655 constexpr concat_view() = default;
9658 concat_view(_Vs... __views)
9659 : _M_views(std::move(__views)...)
9662 constexpr _Iterator<false>
9663 begin() requires (!(__detail::__simple_view<_Vs> && ...))
9665 _Iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9666 __it.template _M_satisfy<0>();
9670 constexpr _Iterator<true>
9671 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9673 _Iterator<true> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9674 __it.template _M_satisfy<0>();
9679 end() requires (!(__detail::__simple_view<_Vs> && ...))
9681 constexpr auto __n = sizeof...(_Vs);
9682 if constexpr (__detail::__all_forward<false, _Vs...>
9683 && common_range<_Vs...[__n - 1]>)
9684 return _Iterator<false>(this, in_place_index<__n - 1>,
9685 ranges::end(std::get<__n - 1>(_M_views)));
9687 return default_sentinel;
9691 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9693 constexpr auto __n = sizeof...(_Vs);
9694 if constexpr (__detail::__all_forward<true, _Vs...>
9695 && common_range<const _Vs...[__n - 1]>)
9696 return _Iterator<true>(this, in_place_index<__n - 1>,
9697 ranges::end(std::get<__n - 1>(_M_views)));
9699 return default_sentinel;
9703 size() requires (sized_range<_Vs>&&...)
9705 return std::apply([](auto... __sizes) {
9706 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9707 return (_CT(__sizes) + ...);
9708 }, __detail::__tuple_transform(ranges::size, _M_views));
9712 size() const requires (sized_range<const _Vs>&&...)
9714 return std::apply([](auto... __sizes) {
9715 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9716 return (_CT(__sizes) + ...);
9717 }, __detail::__tuple_transform(ranges::size, _M_views));
9721 template<typename... _Rs>
9722 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9726 template<bool _Const, typename... _Vs>
9727 struct __concat_view_iter_cat
9730 template<bool _Const, typename... _Vs>
9731 requires __detail::__all_forward<_Const, _Vs...>
9732 struct __concat_view_iter_cat<_Const, _Vs...>
9737 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9738 return input_iterator_tag{};
9740 return []<typename... _Cats>(_Cats... __cats) {
9741 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9742 && __concat_is_random_access<_Const, _Vs...>)
9743 return random_access_iterator_tag{};
9744 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9745 && __concat_is_bidirectional<_Const, _Vs...>)
9746 return bidirectional_iterator_tag{};
9747 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9748 return forward_iterator_tag{};
9750 return input_iterator_tag{};
9751 }(typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9752 ::iterator_category{}...);
9757 template<input_range... _Vs>
9758 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9759 template<bool _Const>
9760 class concat_view<_Vs...>::_Iterator
9761 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9766 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9767 return random_access_iterator_tag{};
9768 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9769 return bidirectional_iterator_tag{};
9770 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9771 return forward_iterator_tag{};
9773 return input_iterator_tag{};
9777 friend _Iterator<!_Const>;
9780 // iterator_category defined in __concat_view_iter_cat
9781 using iterator_concept = decltype(_S_iter_concept());
9782 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9783 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9786 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9788 __maybe_const_t<_Const, concat_view>* _M_parent = nullptr;
9791 template<size_t _Nm>
9795 if constexpr (_Nm < (sizeof...(_Vs) - 1))
9797 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9799 _M_it.template emplace<_Nm + 1>(ranges::begin
9800 (std::get<_Nm + 1>(_M_parent->_M_views)));
9801 _M_satisfy<_Nm + 1>();
9806 template<size_t _Nm>
9810 if constexpr (_Nm == 0)
9811 --std::get<0>(_M_it);
9814 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
9816 _M_it.template emplace<_Nm - 1>(ranges::end
9817 (std::get<_Nm - 1>(_M_parent->_M_views)));
9821 --std::get<_Nm>(_M_it);
9825 template<size_t _Nm>
9827 _M_advance_fwd(difference_type __offset, difference_type __steps)
9829 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9830 if constexpr (_Nm == sizeof...(_Vs) - 1)
9831 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9834 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
9835 if (__offset + __steps < __n_size)
9836 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9839 _M_it.template emplace<_Nm + 1>(ranges::begin
9840 (std::get<_Nm + 1>(_M_parent->_M_views)));
9841 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
9846 template<size_t _Nm>
9848 _M_advance_bwd(difference_type __offset, difference_type __steps)
9850 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9851 if constexpr (_Nm == 0)
9852 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9854 if (__offset >= __steps)
9855 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9858 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
9859 _M_it.template emplace<_Nm - 1>(ranges::end
9860 (std::get<_Nm - 1>(_M_parent->_M_views)));
9861 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
9866 // Invoke the function object __f, which has a call operator with a size_t
9867 // template parameter (corresponding to an index into the pack of views),
9868 // using the runtime value of __index as the template argument.
9869 template<typename _Fp>
9870 static constexpr auto
9871 _S_invoke_with_runtime_index(_Fp&& __f, size_t __index)
9873 return [&__f, __index]<size_t _Idx>(this auto&& __self) {
9874 if (_Idx == __index)
9875 return __f.template operator()<_Idx>();
9876 if constexpr (_Idx + 1 < sizeof...(_Vs))
9877 return __self.template operator()<_Idx + 1>();
9878 __builtin_unreachable();
9879 }.template operator()<0>();
9882 template<typename _Fp>
9884 _M_invoke_with_runtime_index(_Fp&& __f)
9885 { return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); }
9887 template<typename... _Args>
9889 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
9890 requires constructible_from<__base_iter, _Args&&...>
9891 : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...)
9895 _Iterator() = default;
9898 _Iterator(_Iterator<!_Const> __it)
9899 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
9900 : _M_parent(__it._M_parent),
9901 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
9902 return __base_iter(in_place_index<_Idx>,
9903 std::get<_Idx>(std::move(__it._M_it)));
9904 }, __it._M_it.index()))
9907 constexpr decltype(auto)
9910 __glibcxx_assert(!_M_it.valueless_by_exception());
9911 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
9912 return std::visit([](auto&& __it) -> reference { return *__it; }, _M_it);
9915 constexpr _Iterator&
9918 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9919 ++std::get<_Idx>(_M_it);
9931 requires __detail::__all_forward<_Const, _Vs...>
9938 constexpr _Iterator&
9940 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9942 __glibcxx_assert(!_M_it.valueless_by_exception());
9943 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9951 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9958 constexpr _Iterator&
9959 operator+=(difference_type __n)
9960 requires __detail::__concat_is_random_access<_Const, _Vs...>
9962 __glibcxx_assert(!_M_it.valueless_by_exception());
9963 _M_invoke_with_runtime_index([this, __n]<size_t _Idx>() {
9964 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
9966 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
9968 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
9973 constexpr _Iterator&
9974 operator-=(difference_type __n)
9975 requires __detail::__concat_is_random_access<_Const, _Vs...>
9981 constexpr decltype(auto)
9982 operator[](difference_type __n) const
9983 requires __detail::__concat_is_random_access<_Const, _Vs...>
9984 { return *((*this) + __n); }
9986 friend constexpr bool
9987 operator==(const _Iterator& __x, const _Iterator& __y)
9988 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
9990 __glibcxx_assert(!__x._M_it.valueless_by_exception());
9991 __glibcxx_assert(!__y._M_it.valueless_by_exception());
9992 return __x._M_it == __y._M_it;
9995 friend constexpr bool
9996 operator==(const _Iterator& __it, default_sentinel_t)
9998 __glibcxx_assert(!__it._M_it.valueless_by_exception());
9999 constexpr auto __last_idx = sizeof...(_Vs) - 1;
10000 return (__it._M_it.index() == __last_idx
10001 && (std::get<__last_idx>(__it._M_it)
10002 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10005 friend constexpr bool
10006 operator<(const _Iterator& __x, const _Iterator& __y)
10007 requires __detail::__all_random_access<_Const, _Vs...>
10008 { return __x._M_it < __y._M_it; }
10010 friend constexpr bool
10011 operator>(const _Iterator& __x, const _Iterator& __y)
10012 requires __detail::__all_random_access<_Const, _Vs...>
10013 { return __x._M_it > __y._M_it; }
10015 friend constexpr bool
10016 operator<=(const _Iterator& __x, const _Iterator& __y)
10017 requires __detail::__all_random_access<_Const, _Vs...>
10018 { return __x._M_it <= __y._M_it; }
10020 friend constexpr bool
10021 operator>=(const _Iterator& __x, const _Iterator& __y)
10022 requires __detail::__all_random_access<_Const, _Vs...>
10023 { return __x._M_it >= __y._M_it; }
10025 friend constexpr auto
10026 operator<=>(const _Iterator& __x, const _Iterator& __y)
10027 requires __detail::__all_random_access<_Const, _Vs...>
10028 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10029 { return __x._M_it <=> __y._M_it; }
10031 friend constexpr _Iterator
10032 operator+(const _Iterator& __it, difference_type __n)
10033 requires __detail::__concat_is_random_access<_Const, _Vs...>
10034 { return auto(__it) += __n; }
10036 friend constexpr _Iterator
10037 operator+(difference_type __n, const _Iterator& __it)
10038 requires __detail::__concat_is_random_access<_Const, _Vs...>
10039 { return __it + __n; }
10041 friend constexpr _Iterator
10042 operator-(const _Iterator& __it, difference_type __n)
10043 requires __detail::__concat_is_random_access<_Const, _Vs...>
10044 { return auto(__it) -= __n; }
10046 friend constexpr difference_type
10047 operator-(const _Iterator& __x, const _Iterator& __y)
10048 requires __detail::__concat_is_random_access<_Const, _Vs...>
10050 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10051 return _S_invoke_with_runtime_index([&]<size_t _Iy>() -> difference_type {
10052 if constexpr (_Ix > _Iy)
10054 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10055 ranges::end(std::get<_Iy>(__y._M_parent
10057 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10059 std::get<_Ix>(__x._M_it));
10060 difference_type __s = 0;
10061 [&]<size_t _Idx = _Iy + 1>(this auto&& __self) {
10062 if constexpr (_Idx < _Ix)
10064 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10065 __self.template operator()<_Idx + 1>();
10068 return __dy + __s + __dx;
10070 else if constexpr (_Ix < _Iy)
10071 return -(__y - __x);
10073 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10074 }, __y._M_it.index());
10075 }, __x._M_it.index());
10078 friend constexpr difference_type
10079 operator-(const _Iterator& __x, default_sentinel_t)
10080 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10081 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10082 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10084 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10085 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10086 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10087 difference_type __s = 0;
10088 [&]<size_t _Idx = _Ix + 1>(this auto&& __self) {
10089 if constexpr (_Idx < sizeof...(_Vs))
10091 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10092 __self.template operator()<_Idx + 1>();
10095 return -(__dx + __s);
10096 }, __x._M_it.index());
10099 friend constexpr difference_type
10100 operator-(default_sentinel_t, const _Iterator& __x)
10101 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10102 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10103 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10104 { return -(__x - default_sentinel); }
10106 friend constexpr decltype(auto)
10107 iter_move(const _Iterator& __it)
10109 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10110 return std::visit([](const auto& __i) -> _Res {
10111 return ranges::iter_move(__i);
10115 friend constexpr void
10116 iter_swap(const _Iterator& __x, const _Iterator& __y)
10117 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10118 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10120 std::visit([&]<typename _Tp, typename _Up>(const _Tp& __it1, const _Up& __it2) {
10121 if constexpr (is_same_v<_Tp, _Up>)
10122 ranges::iter_swap(__it1, __it2);
10124 ranges::swap(*__it1, *__it2);
10125 }, __x._M_it, __y._M_it);
10133 template<typename... _Ts>
10134 concept __can_concat_view = requires { concat_view(std::declval<_Ts>()...); };
10139 template<typename... _Ts>
10140 requires __detail::__can_concat_view<_Ts...>
10142 operator() [[nodiscard]] (_Ts&&... __ts) const
10143 { return concat_view(std::forward<_Ts>(__ts)...); }
10145 template<input_range _Range>
10147 operator() [[nodiscard]] (_Range&& __t) const
10148 { return views::all(std::forward<_Range>(__t)); }
10151 inline constexpr _Concat concat;
10154} // namespace ranges
10155#endif // __cpp_lib_ranges_concat
10157#if __cpp_lib_ranges_cache_latest // C++ >= 26
10160 template<input_range _Vp>
10162 class cache_latest_view : public view_interface<cache_latest_view<_Vp>>
10164 _Vp _M_base = _Vp();
10166 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10167 add_pointer_t<range_reference_t<_Vp>>,
10168 range_reference_t<_Vp>>;
10169 __detail::__non_propagating_cache<__cache_t> _M_cache;
10175 cache_latest_view() requires default_initializable<_Vp> = default;
10178 cache_latest_view(_Vp __base)
10179 : _M_base(std::move(__base))
10183 base() const & requires copy_constructible<_Vp>
10184 { return _M_base; }
10188 { return std::move(_M_base); }
10192 { return _Iterator(*this); }
10196 { return _Sentinel(*this); }
10199 size() requires sized_range<_Vp>
10200 { return ranges::size(_M_base); }
10203 size() const requires sized_range<const _Vp>
10204 { return ranges::size(_M_base); }
10207 template<typename _Range>
10208 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10210 template<input_range _Vp>
10212 class cache_latest_view<_Vp>::_Iterator
10214 cache_latest_view* _M_parent;
10215 iterator_t<_Vp> _M_current;
10218 _Iterator(cache_latest_view& __parent)
10219 : _M_parent(std::__addressof(__parent)),
10220 _M_current(ranges::begin(__parent._M_base))
10223 friend class cache_latest_view;
10226 using difference_type = range_difference_t<_Vp>;
10227 using value_type = range_value_t<_Vp>;
10228 using iterator_concept = input_iterator_tag;
10230 _Iterator(_Iterator&&) = default;
10233 operator=(_Iterator&&) = default;
10235 constexpr iterator_t<_Vp>
10237 { return std::move(_M_current); }
10239 constexpr const iterator_t<_Vp>&
10240 base() const & noexcept
10241 { return _M_current; }
10243 constexpr range_reference_t<_Vp>&
10246 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10248 if (!_M_parent->_M_cache)
10249 _M_parent->_M_cache = std::__addressof(__detail::__as_lvalue(*_M_current));
10250 return **_M_parent->_M_cache;
10254 if (!_M_parent->_M_cache)
10255 _M_parent->_M_cache._M_emplace_deref(_M_current);
10256 return *_M_parent->_M_cache;
10260 constexpr _Iterator&
10263 _M_parent->_M_cache._M_reset();
10272 friend constexpr range_rvalue_reference_t<_Vp>
10273 iter_move(const _Iterator& __i)
10274 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10275 { return ranges::iter_move(__i._M_current); }
10277 friend constexpr void
10278 iter_swap(const _Iterator& __x, const _Iterator& __y)
10279 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10280 requires indirectly_swappable<iterator_t<_Vp>>
10281 { ranges::iter_swap(__x._M_current, __y._M_current); }
10284 template<input_range _Vp>
10286 class cache_latest_view<_Vp>::_Sentinel
10288 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10291 _Sentinel(cache_latest_view& __parent)
10292 : _M_end(ranges::end(__parent._M_base))
10295 friend class cache_latest_view;
10298 _Sentinel() = default;
10300 constexpr sentinel_t<_Vp>
10304 friend constexpr bool
10305 operator==(const _Iterator& __x, const _Sentinel& __y)
10306 { return __x._M_current == __y._M_end; }
10308 friend constexpr range_difference_t<_Vp>
10309 operator-(const _Iterator& __x, const _Sentinel& __y)
10310 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10311 { return __x._M_current - __y._M_end; }
10313 friend constexpr range_difference_t<_Vp>
10314 operator-(const _Sentinel& __x, const _Iterator& __y)
10315 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10316 { return __x._M_end - __y._M_current; }
10323 template<typename _Tp>
10324 concept __can_cache_latest = requires { cache_latest_view(std::declval<_Tp>()); };
10327 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10329 template<viewable_range _Range>
10330 requires __detail::__can_cache_latest<_Range>
10332 operator() [[nodiscard]] (_Range&& __r) const
10333 { return cache_latest_view(std::forward<_Range>(__r)); }
10335 static constexpr bool _S_has_simple_call_op = true;
10338 inline constexpr _CacheLatest cache_latest;
10340} // namespace ranges
10341#endif // __cpp_lib_ranges_cache_latest
10343#if __cpp_lib_ranges_to_input // C++ >= 26
10346 template<input_range _Vp>
10348 class to_input_view : public view_interface<to_input_view<_Vp>>
10350 _Vp _M_base = _Vp();
10352 template<bool _Const>
10356 to_input_view() requires default_initializable<_Vp> = default;
10359 to_input_view(_Vp __base)
10360 : _M_base(std::move(__base))
10364 base() const & requires copy_constructible<_Vp>
10365 { return _M_base; }
10369 { return std::move(_M_base); }
10372 begin() requires (!__detail::__simple_view<_Vp>)
10373 { return _Iterator<false>(ranges::begin(_M_base)); }
10376 begin() const requires range<const _Vp>
10377 { return _Iterator<true>(ranges::begin(_M_base)); }
10380 end() requires (!__detail::__simple_view<_Vp>)
10381 { return ranges::end(_M_base); }
10384 end() const requires range<const _Vp>
10385 { return ranges::end(_M_base); }
10388 size() requires sized_range<_Vp>
10389 { return ranges::size(_M_base); }
10392 size() const requires sized_range<const _Vp>
10393 { return ranges::size(_M_base); }
10396 template<typename _Range>
10397 to_input_view(_Range&&) -> to_input_view<views::all_t<_Range>>;
10399 template<input_range _Vp>
10401 template<bool _Const>
10402 class to_input_view<_Vp>::_Iterator
10404 using _Base = __maybe_const_t<_Const, _Vp>;
10406 iterator_t<_Base> _M_current = iterator_t<_Base>();
10409 _Iterator(iterator_t<_Base> __current)
10410 : _M_current(std::move(__current))
10413 friend to_input_view;
10414 friend _Iterator<!_Const>;
10417 using difference_type = range_difference_t<_Base>;
10418 using value_type = range_value_t<_Base>;
10419 using iterator_concept = input_iterator_tag;
10421 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
10423 _Iterator(_Iterator&&) = default;
10424 _Iterator& operator=(_Iterator&&) = default;
10427 _Iterator(_Iterator<!_Const> __i)
10428 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10429 : _M_current(std::move(__i._M_current))
10432 constexpr iterator_t<_Base>
10434 { return std::move(_M_current); }
10436 constexpr const iterator_t<_Base>&
10437 base() const & noexcept
10438 { return _M_current; }
10440 constexpr decltype(auto)
10442 { return *_M_current; }
10444 constexpr _Iterator&
10455 friend constexpr bool
10456 operator==(const _Iterator& __x, const sentinel_t<_Base>& __y)
10457 { return __x._M_current == __y; }
10459 friend constexpr difference_type
10460 operator-(const sentinel_t<_Base>& __y, const _Iterator& __x)
10461 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10462 { return __y - __x._M_current; }
10464 friend constexpr difference_type
10465 operator-(const _Iterator& __x, const sentinel_t<_Base>& __y)
10466 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10467 { return __x._M_current - __y; }
10469 friend constexpr range_rvalue_reference_t<_Base>
10470 iter_move(const _Iterator& __i)
10471 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10472 { return ranges::iter_move(__i._M_current); }
10474 friend constexpr void
10475 iter_swap(const _Iterator& __x, const _Iterator& __y)
10476 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10477 requires indirectly_swappable<iterator_t<_Base>>
10478 { ranges::iter_swap(__x._M_current, __y._M_current); }
10485 template<typename _Tp>
10486 concept __can_to_input = requires { to_input_view(std::declval<_Tp>()); };
10489 struct _ToInput : __adaptor::_RangeAdaptorClosure<_ToInput>
10491 template<viewable_range _Range>
10492 requires __detail::__can_to_input<_Range>
10494 operator() [[nodiscard]] (_Range&& __r) const
10496 if constexpr (input_range<_Range>
10497 && !common_range<_Range>
10498 && !forward_range<_Range>)
10499 return views::all(std::forward<_Range>(__r));
10501 return to_input_view(std::forward<_Range>(__r));
10504 static constexpr bool _S_has_simple_call_op = true;
10507 inline constexpr _ToInput to_input;
10509} // namespace ranges
10510#endif // __cpp_lib_ranges_to_input
10512_GLIBCXX_END_NAMESPACE_VERSION
10514#endif // library concepts
10516#endif /* _GLIBCXX_RANGES */