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/ranges_util.h>
55#include <bits/refwrap.h>
57#define __glibcxx_want_algorithm_default_value_type
58#define __glibcxx_want_ranges
59#define __glibcxx_want_ranges_as_const
60#define __glibcxx_want_ranges_as_rvalue
61#define __glibcxx_want_ranges_cache_latest
62#define __glibcxx_want_ranges_cartesian_product
63#define __glibcxx_want_ranges_concat
64#define __glibcxx_want_ranges_chunk
65#define __glibcxx_want_ranges_chunk_by
66#define __glibcxx_want_ranges_enumerate
67#define __glibcxx_want_ranges_join_with
68#define __glibcxx_want_ranges_repeat
69#define __glibcxx_want_ranges_slide
70#define __glibcxx_want_ranges_stride
71#define __glibcxx_want_ranges_to_container
72#define __glibcxx_want_ranges_to_input
73#define __glibcxx_want_ranges_zip
74#include <bits/version.h>
76#ifdef __glibcxx_generator // C++ >= 23 && __glibcxx_coroutine
77# include <bits/elements_of.h>
81 * @defgroup ranges Ranges
83 * Components for dealing with ranges of elements.
86namespace std _GLIBCXX_VISIBILITY(default)
88_GLIBCXX_BEGIN_NAMESPACE_VERSION
91 // [range.access] customization point objects
92 // [range.req] range and view concepts
93 // [range.dangling] dangling iterator handling
94 // Defined in <bits/ranges_base.h>
96 // [view.interface] View interface
97 // [range.subrange] Sub-ranges
98 // Defined in <bits/ranges_util.h>
100 // C++20 24.6 [range.factories] Range factories
102 /// A view that contains no elements.
103 template<typename _Tp> requires is_object_v<_Tp>
105 : public view_interface<empty_view<_Tp>>
108 static constexpr _Tp* begin() noexcept { return nullptr; }
109 static constexpr _Tp* end() noexcept { return nullptr; }
110 static constexpr _Tp* data() noexcept { return nullptr; }
111 static constexpr size_t size() noexcept { return 0; }
112 static constexpr bool empty() noexcept { return true; }
115 template<typename _Tp>
116 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
120#if __cpp_lib_ranges >= 202207L // C++ >= 23
121 // P2494R2 Relaxing range adaptors to allow for move only types
122 template<typename _Tp>
123 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
125 template<typename _Tp>
126 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
129 template<__boxable _Tp>
130 struct __box : std::optional<_Tp>
132 using std::optional<_Tp>::optional;
136 noexcept(is_nothrow_default_constructible_v<_Tp>)
137 requires default_initializable<_Tp>
138 : std::optional<_Tp>{std::in_place}
141 __box(const __box&) = default;
142 __box(__box&&) = default;
144 using std::optional<_Tp>::operator=;
146 // _GLIBCXX_RESOLVE_LIB_DEFECTS
147 // 3477. Simplify constraints for semiregular-box
148 // 3572. copyable-box should be fully constexpr
150 operator=(const __box& __that)
151 noexcept(is_nothrow_copy_constructible_v<_Tp>)
152 requires (!copyable<_Tp>) && copy_constructible<_Tp>
154 if (this != std::__addressof(__that))
157 this->emplace(*__that);
165 operator=(__box&& __that)
166 noexcept(is_nothrow_move_constructible_v<_Tp>)
167 requires (!movable<_Tp>)
169 if (this != std::__addressof(__that))
172 this->emplace(std::move(*__that));
180 template<typename _Tp>
181 concept __boxable_copyable
182 = copy_constructible<_Tp>
183 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
184 && is_nothrow_copy_constructible_v<_Tp>));
185 template<typename _Tp>
186 concept __boxable_movable
187 = (!copy_constructible<_Tp>)
188 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
190 // For types which are already copyable (or since C++23, movable)
191 // this specialization of the box wrapper stores the object directly
192 // without going through std::optional. It provides just the subset of
193 // the primary template's API that we currently use.
194 template<__boxable _Tp>
195 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
199 [[no_unique_address]] _Tp _M_value = _Tp();
202 __box() requires default_initializable<_Tp> = default;
205 __box(const _Tp& __t)
206 noexcept(is_nothrow_copy_constructible_v<_Tp>)
207 requires copy_constructible<_Tp>
213 noexcept(is_nothrow_move_constructible_v<_Tp>)
214 : _M_value(std::move(__t))
217 template<typename... _Args>
218 requires constructible_from<_Tp, _Args...>
220 __box(in_place_t, _Args&&... __args)
221 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
222 : _M_value(std::forward<_Args>(__args)...)
225 __box(const __box&) = default;
226 __box(__box&&) = default;
227 __box& operator=(const __box&) requires copyable<_Tp> = default;
228 __box& operator=(__box&&) requires movable<_Tp> = default;
230 // When _Tp is nothrow_copy_constructible but not copy_assignable,
231 // copy assignment is implemented via destroy-then-copy-construct.
233 operator=(const __box& __that) noexcept
234 requires (!copyable<_Tp>) && copy_constructible<_Tp>
236 static_assert(is_nothrow_copy_constructible_v<_Tp>);
237 if (this != std::__addressof(__that))
240 std::construct_at(std::__addressof(_M_value), *__that);
245 // Likewise for move assignment.
247 operator=(__box&& __that) noexcept
248 requires (!movable<_Tp>)
250 static_assert(is_nothrow_move_constructible_v<_Tp>);
251 if (this != std::__addressof(__that))
254 std::construct_at(std::__addressof(_M_value), std::move(*__that));
260 has_value() const noexcept
264 operator*() & noexcept
268 operator*() const & noexcept
272 operator*() && noexcept
273 { return std::move(_M_value); }
275 constexpr const _Tp&&
276 operator*() const && noexcept
277 { return std::move(_M_value); }
280 operator->() noexcept
281 { return std::__addressof(_M_value); }
284 operator->() const noexcept
285 { return std::__addressof(_M_value); }
287 } // namespace __detail
289 /// A view that contains exactly one element.
290#if __cpp_lib_ranges >= 202207L // C++ >= 23
291 template<move_constructible _Tp>
293 template<copy_constructible _Tp>
295 requires is_object_v<_Tp>
296 class single_view : public view_interface<single_view<_Tp>>
299 single_view() requires default_initializable<_Tp> = default;
302 single_view(const _Tp& __t)
303 noexcept(is_nothrow_copy_constructible_v<_Tp>)
304 requires copy_constructible<_Tp>
309 single_view(_Tp&& __t)
310 noexcept(is_nothrow_move_constructible_v<_Tp>)
311 : _M_value(std::move(__t))
314 // _GLIBCXX_RESOLVE_LIB_DEFECTS
315 // 3428. single_view's in place constructor should be explicit
316 template<typename... _Args>
317 requires constructible_from<_Tp, _Args...>
319 single_view(in_place_t, _Args&&... __args)
320 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
321 : _M_value{in_place, std::forward<_Args>(__args)...}
329 begin() const noexcept
334 { return data() + 1; }
338 { return data() + 1; }
340 // _GLIBCXX_RESOLVE_LIB_DEFECTS
341 // 4035. single_view should provide empty
342 static constexpr bool
346 static constexpr size_t
352 { return _M_value.operator->(); }
355 data() const noexcept
356 { return _M_value.operator->(); }
359 [[no_unique_address]] __detail::__box<_Tp> _M_value;
362 template<typename _Tp>
363 single_view(_Tp) -> single_view<_Tp>;
367 template<typename _Wp>
368 constexpr auto __to_signed_like(_Wp __w) noexcept
370 if constexpr (!integral<_Wp>)
371 return iter_difference_t<_Wp>();
372 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
373 return iter_difference_t<_Wp>(__w);
374 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
375 return ptrdiff_t(__w);
376 else if constexpr (sizeof(long long) > sizeof(_Wp))
377 return (long long)(__w);
378#ifdef __SIZEOF_INT128__
379 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
380 return __int128(__w);
383 return __max_diff_type(__w);
386 template<typename _Wp>
387 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
389 template<typename _It>
390 concept __decrementable = incrementable<_It>
393 { --__i } -> same_as<_It&>;
394 { __i-- } -> same_as<_It>;
397 template<typename _It>
398 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
399 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
401 { __i += __n } -> same_as<_It&>;
402 { __i -= __n } -> same_as<_It&>;
406 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
409 template<typename _Winc>
410 struct __iota_view_iter_cat
413 template<incrementable _Winc>
414 struct __iota_view_iter_cat<_Winc>
415 { using iterator_category = input_iterator_tag; };
416 } // namespace __detail
418 template<weakly_incrementable _Winc,
419 semiregular _Bound = unreachable_sentinel_t>
420 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
422 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
427 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
433 using namespace __detail;
434 if constexpr (__advanceable<_Winc>)
435 return random_access_iterator_tag{};
436 else if constexpr (__decrementable<_Winc>)
437 return bidirectional_iterator_tag{};
438 else if constexpr (incrementable<_Winc>)
439 return forward_iterator_tag{};
441 return input_iterator_tag{};
445 using iterator_concept = decltype(_S_iter_concept());
446 // iterator_category defined in __iota_view_iter_cat
447 using value_type = _Winc;
448 using difference_type = __detail::__iota_diff_t<_Winc>;
450 _Iterator() requires default_initializable<_Winc> = default;
453 _Iterator(_Winc __value)
454 : _M_value(__value) { }
457 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
472 operator++(int) requires incrementable<_Winc>
480 operator--() requires __detail::__decrementable<_Winc>
487 operator--(int) requires __detail::__decrementable<_Winc>
495 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
497 using __detail::__is_integer_like;
498 using __detail::__is_signed_integer_like;
499 if constexpr (__is_integer_like<_Winc>
500 && !__is_signed_integer_like<_Winc>)
502 if (__n >= difference_type(0))
503 _M_value += static_cast<_Winc>(__n);
505 _M_value -= static_cast<_Winc>(-__n);
513 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
515 using __detail::__is_integer_like;
516 using __detail::__is_signed_integer_like;
517 if constexpr (__is_integer_like<_Winc>
518 && !__is_signed_integer_like<_Winc>)
520 if (__n >= difference_type(0))
521 _M_value -= static_cast<_Winc>(__n);
523 _M_value += static_cast<_Winc>(-__n);
531 operator[](difference_type __n) const
532 requires __detail::__advanceable<_Winc>
533 { return _Winc(_M_value + __n); }
535 friend constexpr bool
536 operator==(const _Iterator& __x, const _Iterator& __y)
537 requires equality_comparable<_Winc>
538 { return __x._M_value == __y._M_value; }
540 friend constexpr bool
541 operator<(const _Iterator& __x, const _Iterator& __y)
542 requires totally_ordered<_Winc>
543 { return __x._M_value < __y._M_value; }
545 friend constexpr bool
546 operator>(const _Iterator& __x, const _Iterator& __y)
547 requires totally_ordered<_Winc>
548 { return __y < __x; }
550 friend constexpr bool
551 operator<=(const _Iterator& __x, const _Iterator& __y)
552 requires totally_ordered<_Winc>
553 { return !(__y < __x); }
555 friend constexpr bool
556 operator>=(const _Iterator& __x, const _Iterator& __y)
557 requires totally_ordered<_Winc>
558 { return !(__x < __y); }
560#ifdef __cpp_lib_three_way_comparison
561 friend constexpr auto
562 operator<=>(const _Iterator& __x, const _Iterator& __y)
563 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
564 { return __x._M_value <=> __y._M_value; }
567 friend constexpr _Iterator
568 operator+(_Iterator __i, difference_type __n)
569 requires __detail::__advanceable<_Winc>
575 friend constexpr _Iterator
576 operator+(difference_type __n, _Iterator __i)
577 requires __detail::__advanceable<_Winc>
578 { return __i += __n; }
580 friend constexpr _Iterator
581 operator-(_Iterator __i, difference_type __n)
582 requires __detail::__advanceable<_Winc>
588 friend constexpr difference_type
589 operator-(const _Iterator& __x, const _Iterator& __y)
590 requires __detail::__advanceable<_Winc>
592 using __detail::__is_integer_like;
593 using __detail::__is_signed_integer_like;
594 using _Dt = difference_type;
595 if constexpr (__is_integer_like<_Winc>)
597 if constexpr (__is_signed_integer_like<_Winc>)
598 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
600 return (__y._M_value > __x._M_value)
601 ? _Dt(-_Dt(__y._M_value - __x._M_value))
602 : _Dt(__x._M_value - __y._M_value);
605 return __x._M_value - __y._M_value;
609 _Winc _M_value = _Winc();
619 _M_equal(const _Iterator& __x) const
620 { return __x._M_value == _M_bound; }
623 _M_distance_from(const _Iterator& __x) const
624 { return _M_bound - __x._M_value; }
626 _Bound _M_bound = _Bound();
629 _Sentinel() = default;
632 _Sentinel(_Bound __bound)
633 : _M_bound(__bound) { }
635 friend constexpr bool
636 operator==(const _Iterator& __x, const _Sentinel& __y)
637 { return __y._M_equal(__x); }
639 friend constexpr iter_difference_t<_Winc>
640 operator-(const _Iterator& __x, const _Sentinel& __y)
641 requires sized_sentinel_for<_Bound, _Winc>
642 { return -__y._M_distance_from(__x); }
644 friend constexpr iter_difference_t<_Winc>
645 operator-(const _Sentinel& __x, const _Iterator& __y)
646 requires sized_sentinel_for<_Bound, _Winc>
647 { return __x._M_distance_from(__y); }
652 _Winc _M_value = _Winc();
653 [[no_unique_address]] _Bound _M_bound = _Bound();
656 iota_view() requires default_initializable<_Winc> = default;
659 iota_view(_Winc __value)
664 iota_view(type_identity_t<_Winc> __value,
665 type_identity_t<_Bound> __bound)
666 : _M_value(__value), _M_bound(__bound)
668 if constexpr (totally_ordered_with<_Winc, _Bound>)
669 __glibcxx_assert( bool(__value <= __bound) );
673 iota_view(_Iterator __first, _Iterator __last)
674 requires same_as<_Winc, _Bound>
675 : iota_view(__first._M_value, __last._M_value)
679 iota_view(_Iterator __first, unreachable_sentinel_t __last)
680 requires same_as<_Bound, unreachable_sentinel_t>
681 : iota_view(__first._M_value, __last)
685 iota_view(_Iterator __first, _Sentinel __last)
686 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
687 : iota_view(__first._M_value, __last._M_bound)
691 begin() const { return _Iterator{_M_value}; }
696 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
697 return unreachable_sentinel;
699 return _Sentinel{_M_bound};
703 end() const requires same_as<_Winc, _Bound>
704 { return _Iterator{_M_bound}; }
706 // _GLIBCXX_RESOLVE_LIB_DEFECTS
707 // 4001. iota_view should provide empty
710 { return _M_value == _M_bound; }
714 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
715 || (integral<_Winc> && integral<_Bound>)
716 || sized_sentinel_for<_Bound, _Winc>
718 using __detail::__is_integer_like;
719 using __detail::__to_unsigned_like;
720 if constexpr (integral<_Winc> && integral<_Bound>)
722 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
723 return _Up(_M_bound) - _Up(_M_value);
725 else if constexpr (__is_integer_like<_Winc>)
726 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
728 return __to_unsigned_like(_M_bound - _M_value);
732 template<typename _Winc, typename _Bound>
733 requires (!__detail::__is_integer_like<_Winc>
734 || !__detail::__is_integer_like<_Bound>
735 || (__detail::__is_signed_integer_like<_Winc>
736 == __detail::__is_signed_integer_like<_Bound>))
737 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
739 template<typename _Winc, typename _Bound>
740 inline constexpr bool
741 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
745 template<typename _Tp>
746 inline constexpr empty_view<_Tp> empty{};
750 template<typename _Tp>
751 concept __can_single_view
752 = requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
753 } // namespace __detail
757 template<__detail::__can_single_view _Tp>
759 operator() [[nodiscard]] (_Tp&& __e) const
760 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
761 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
764 inline constexpr _Single single{};
768 template<typename... _Args>
769 concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); };
770 } // namespace __detail
774 template<__detail::__can_iota_view _Tp>
776 operator() [[nodiscard]] (_Tp&& __e) const
777 { return iota_view(std::forward<_Tp>(__e)); }
779 template<typename _Tp, typename _Up>
780 requires __detail::__can_iota_view<_Tp, _Up>
782 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const
783 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
786 inline constexpr _Iota iota{};
792 template<typename _Val, typename _CharT, typename _Traits>
793 concept __stream_extractable
794 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
795 } // namespace __detail
797 template<movable _Val, typename _CharT,
798 typename _Traits = char_traits<_CharT>>
799 requires default_initializable<_Val>
800 && __detail::__stream_extractable<_Val, _CharT, _Traits>
801 class basic_istream_view
802 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
806 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
807 : _M_stream(std::__addressof(__stream))
813 *_M_stream >> _M_object;
814 return _Iterator{this};
817 constexpr default_sentinel_t
819 { return default_sentinel; }
822 basic_istream<_CharT, _Traits>* _M_stream;
823 _Val _M_object = _Val();
828 using iterator_concept = input_iterator_tag;
829 using difference_type = ptrdiff_t;
830 using value_type = _Val;
833 _Iterator(basic_istream_view* __parent) noexcept
834 : _M_parent(__parent)
837 _Iterator(const _Iterator&) = delete;
838 _Iterator(_Iterator&&) = default;
839 _Iterator& operator=(const _Iterator&) = delete;
840 _Iterator& operator=(_Iterator&&) = default;
845 *_M_parent->_M_stream >> _M_parent->_M_object;
855 { return _M_parent->_M_object; }
858 operator==(const _Iterator& __x, default_sentinel_t)
859 { return __x._M_at_end(); }
862 basic_istream_view* _M_parent;
866 { return !*_M_parent->_M_stream; }
872 template<typename _Val>
873 using istream_view = basic_istream_view<_Val, char>;
875 template<typename _Val>
876 using wistream_view = basic_istream_view<_Val, wchar_t>;
882 template<typename _Tp, typename _Up>
883 concept __can_istream_view = requires (_Up __e) {
884 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
886 } // namespace __detail
888 template<typename _Tp>
891 template<typename _CharT, typename _Traits>
893 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
894 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
895 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
898 template<typename _Tp>
899 inline constexpr _Istream<_Tp> istream;
903 // C++20 24.7 [range.adaptors] Range adaptors
907 template<typename _Tp, int _Disc>
910 // Alias for a type that is conditionally present
911 // (and is an empty type otherwise).
912 // Data members using this alias should use [[no_unique_address]] so that
913 // they take no space when not needed.
914 // The optional template parameter _Disc is for discriminating two otherwise
915 // equivalent absent types so that even they can overlap.
916 template<bool _Present, typename _Tp, int _Disc = 0>
917 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
919 // Alias for a type that is conditionally const.
920 template<bool _Const, typename _Tp>
921 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
923} // namespace __detail
925// Shorthand for __detail::__maybe_const_t.
926using __detail::__maybe_const_t;
928namespace views::__adaptor
930 // True if the range adaptor _Adaptor can be applied with _Args.
931 template<typename _Adaptor, typename... _Args>
932 concept __adaptor_invocable
933 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
935 // True if the range adaptor non-closure _Adaptor can be partially applied
937 template<typename _Adaptor, typename... _Args>
938 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
939 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
940 && (constructible_from<decay_t<_Args>, _Args> && ...);
942 template<typename _Adaptor, typename... _Args>
945 template<typename _Lhs, typename _Rhs>
948 // The base class of every range adaptor closure.
950 // The derived class should define the optional static data member
951 // _S_has_simple_call_op to true if the behavior of this adaptor is
952 // independent of the constness/value category of the adaptor object.
953 template<typename _Derived>
954 struct _RangeAdaptorClosure;
956 template<typename _Tp, typename _Up>
957 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
958 void __is_range_adaptor_closure_fn
959 (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined
961 template<typename _Tp>
962 concept __is_range_adaptor_closure
963 = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
965#pragma GCC diagnostic push
966#pragma GCC diagnostic ignored "-Wdangling-reference"
967 // range | adaptor is equivalent to adaptor(range).
968 template<typename _Self, typename _Range>
969 requires __is_range_adaptor_closure<_Self>
970 && __adaptor_invocable<_Self, _Range>
972 operator|(_Range&& __r, _Self&& __self)
973 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
975 // Compose the adaptors __lhs and __rhs into a pipeline, returning
976 // another range adaptor closure object.
977 template<typename _Lhs, typename _Rhs>
978 requires __is_range_adaptor_closure<_Lhs>
979 && __is_range_adaptor_closure<_Rhs>
981 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
983 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
984 std::forward<_Rhs>(__rhs)};
986#pragma GCC diagnostic pop
988 template<typename _Derived>
989 struct _RangeAdaptorClosure
991 // In non-modules compilation ADL finds these operators either way and
992 // the friend declarations are redundant. But with the std module these
993 // friend declarations enable ADL to find these operators without having
995 template<typename _Self, typename _Range>
996 requires __is_range_adaptor_closure<_Self>
997 && __adaptor_invocable<_Self, _Range>
998 friend constexpr auto
999 operator|(_Range&& __r, _Self&& __self);
1001 template<typename _Lhs, typename _Rhs>
1002 requires __is_range_adaptor_closure<_Lhs>
1003 && __is_range_adaptor_closure<_Rhs>
1004 friend constexpr auto
1005 operator|(_Lhs&& __lhs, _Rhs&& __rhs);
1008 // The base class of every range adaptor non-closure.
1010 // The static data member _Derived::_S_arity must contain the total number of
1011 // arguments that the adaptor takes, and the class _Derived must introduce
1012 // _RangeAdaptor::operator() into the class scope via a using-declaration.
1014 // The optional static data member _Derived::_S_has_simple_extra_args should
1015 // be defined to true if the behavior of this adaptor is independent of the
1016 // constness/value category of the extra arguments. This data member could
1017 // also be defined as a variable template parameterized by the types of the
1019 template<typename _Derived>
1020 struct _RangeAdaptor
1022 // Partially apply the arguments __args to the range adaptor _Derived,
1023 // returning a range adaptor closure object.
1024 template<typename... _Args>
1025 requires __adaptor_partial_app_viable<_Derived, _Args...>
1027 operator()(_Args&&... __args) const
1029 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
1033 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
1034 // one that's not overloaded according to constness or value category of the
1036 template<typename _Adaptor>
1037 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1039 // True if the behavior of the range adaptor non-closure _Adaptor is
1040 // independent of the value category of its extra arguments _Args.
1041 template<typename _Adaptor, typename... _Args>
1042 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1043 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1045 // A range adaptor closure that represents partial application of
1046 // the range adaptor _Adaptor with arguments _Args.
1047 template<typename _Adaptor, typename... _Args>
1048 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1050 tuple<_Args...> _M_args;
1052 // First parameter is to ensure this constructor is never used
1053 // instead of the copy/move constructor.
1054 template<typename... _Ts>
1056 _Partial(int, _Ts&&... __args)
1057 : _M_args(std::forward<_Ts>(__args)...)
1060 // Invoke _Adaptor with arguments __r, _M_args... according to the
1061 // value category of this _Partial object.
1062#if __cpp_explicit_this_parameter
1063 template<typename _Self, typename _Range>
1064 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1066 operator()(this _Self&& __self, _Range&& __r)
1068 auto __forwarder = [&__r] (auto&&... __args) {
1069 return _Adaptor{}(std::forward<_Range>(__r),
1070 std::forward<decltype(__args)>(__args)...);
1072 return std::apply(__forwarder, __like_t<_Self, _Partial>(__self)._M_args);
1075 template<typename _Range>
1076 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1078 operator()(_Range&& __r) const &
1080 auto __forwarder = [&__r] (const auto&... __args) {
1081 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1083 return std::apply(__forwarder, _M_args);
1086 template<typename _Range>
1087 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1089 operator()(_Range&& __r) &&
1091 auto __forwarder = [&__r] (auto&... __args) {
1092 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
1094 return std::apply(__forwarder, _M_args);
1097 template<typename _Range>
1099 operator()(_Range&& __r) const && = delete;
1103 // A lightweight specialization of the above primary template for
1104 // the common case where _Adaptor accepts a single extra argument.
1105 template<typename _Adaptor, typename _Arg>
1106 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1110 template<typename _Tp>
1112 _Partial(int, _Tp&& __arg)
1113 : _M_arg(std::forward<_Tp>(__arg))
1116#if __cpp_explicit_this_parameter
1117 template<typename _Self, typename _Range>
1118 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Arg>>
1120 operator()(this _Self&& __self, _Range&& __r)
1122 return _Adaptor{}(std::forward<_Range>(__r),
1123 __like_t<_Self, _Partial>(__self)._M_arg);
1126 template<typename _Range>
1127 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1129 operator()(_Range&& __r) const &
1130 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1132 template<typename _Range>
1133 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
1135 operator()(_Range&& __r) &&
1136 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
1138 template<typename _Range>
1140 operator()(_Range&& __r) const && = delete;
1144 // Partial specialization of the primary template for the case where the extra
1145 // arguments of the adaptor can always be safely and efficiently forwarded by
1146 // const reference. This lets us get away with a single operator() overload,
1147 // which makes overload resolution failure diagnostics more concise.
1148 template<typename _Adaptor, typename... _Args>
1149 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1150 && (is_trivially_copy_constructible_v<_Args> && ...)
1151 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1153 tuple<_Args...> _M_args;
1155 template<typename... _Ts>
1157 _Partial(int, _Ts&&... __args)
1158 : _M_args(std::forward<_Ts>(__args)...)
1161 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1162 // of the value category of this _Partial object.
1163 template<typename _Range>
1164 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1166 operator()(_Range&& __r) const
1168 auto __forwarder = [&__r] (const auto&... __args) {
1169 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1171 return std::apply(__forwarder, _M_args);
1174 static constexpr bool _S_has_simple_call_op = true;
1177 // A lightweight specialization of the above template for the common case
1178 // where _Adaptor accepts a single extra argument.
1179 template<typename _Adaptor, typename _Arg>
1180 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1181 && is_trivially_copy_constructible_v<_Arg>
1182 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1186 template<typename _Tp>
1188 _Partial(int, _Tp&& __arg)
1189 : _M_arg(std::forward<_Tp>(__arg))
1192 template<typename _Range>
1193 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1195 operator()(_Range&& __r) const
1196 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1198 static constexpr bool _S_has_simple_call_op = true;
1201 template<typename _Lhs, typename _Rhs, typename _Range>
1202 concept __pipe_invocable
1203 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1205 // A range adaptor closure that represents composition of the range
1206 // adaptor closures _Lhs and _Rhs.
1207 template<typename _Lhs, typename _Rhs>
1208 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1210 [[no_unique_address]] _Lhs _M_lhs;
1211 [[no_unique_address]] _Rhs _M_rhs;
1213 template<typename _Tp, typename _Up>
1215 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1216 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1219 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1220 // range adaptor closure object.
1221#if __cpp_explicit_this_parameter
1222 template<typename _Self, typename _Range>
1223 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1225 operator()(this _Self&& __self, _Range&& __r)
1227 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1228 (__like_t<_Self, _Pipe>(__self)._M_lhs
1229 (std::forward<_Range>(__r))));
1232 template<typename _Range>
1233 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1235 operator()(_Range&& __r) const &
1236 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1238 template<typename _Range>
1239 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1241 operator()(_Range&& __r) &&
1242 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1244 template<typename _Range>
1246 operator()(_Range&& __r) const && = delete;
1250 // A partial specialization of the above primary template for the case where
1251 // both adaptor operands have a simple operator(). This in turn lets us
1252 // implement composition using a single simple operator(), which makes
1253 // overload resolution failure diagnostics more concise.
1254 template<typename _Lhs, typename _Rhs>
1255 requires __closure_has_simple_call_op<_Lhs>
1256 && __closure_has_simple_call_op<_Rhs>
1257 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1259 [[no_unique_address]] _Lhs _M_lhs;
1260 [[no_unique_address]] _Rhs _M_rhs;
1262 template<typename _Tp, typename _Up>
1264 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1265 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1268 template<typename _Range>
1269 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1271 operator()(_Range&& __r) const
1272 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1274 static constexpr bool _S_has_simple_call_op = true;
1276} // namespace views::__adaptor
1278#if __cpp_lib_ranges >= 202202L
1279 // P2387R3 Pipe support for user-defined range adaptors
1280 template<typename _Derived>
1281 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1282 class range_adaptor_closure
1283 : public views::__adaptor::_RangeAdaptorClosure<_Derived>
1287 template<range _Range> requires is_object_v<_Range>
1288 class ref_view : public view_interface<ref_view<_Range>>
1293 static void _S_fun(_Range&); // not defined
1294 static void _S_fun(_Range&&) = delete;
1297 template<__detail::__different_from<ref_view> _Tp>
1298 requires convertible_to<_Tp, _Range&>
1299 && requires { _S_fun(declval<_Tp>()); }
1302 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1303 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1310 constexpr iterator_t<_Range>
1312 { return ranges::begin(*_M_r); }
1314 constexpr sentinel_t<_Range>
1316 { return ranges::end(*_M_r); }
1319 empty() const requires requires { ranges::empty(*_M_r); }
1320 { return ranges::empty(*_M_r); }
1323 size() const requires sized_range<_Range>
1324 { return ranges::size(*_M_r); }
1327 data() const requires contiguous_range<_Range>
1328 { return ranges::data(*_M_r); }
1331 template<typename _Range>
1332 ref_view(_Range&) -> ref_view<_Range>;
1334 template<typename _Tp>
1335 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1337 template<range _Range>
1338 requires movable<_Range>
1339 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1340 class owning_view : public view_interface<owning_view<_Range>>
1343 _Range _M_r = _Range();
1346 owning_view() requires default_initializable<_Range> = default;
1349 owning_view(_Range&& __t)
1350 noexcept(is_nothrow_move_constructible_v<_Range>)
1351 : _M_r(std::move(__t))
1354 owning_view(owning_view&&) = default;
1355 owning_view& operator=(owning_view&&) = default;
1361 constexpr const _Range&
1362 base() const& noexcept
1367 { return std::move(_M_r); }
1369 constexpr const _Range&&
1370 base() const&& noexcept
1371 { return std::move(_M_r); }
1373 constexpr iterator_t<_Range>
1375 { return ranges::begin(_M_r); }
1377 constexpr sentinel_t<_Range>
1379 { return ranges::end(_M_r); }
1382 begin() const requires range<const _Range>
1383 { return ranges::begin(_M_r); }
1386 end() const requires range<const _Range>
1387 { return ranges::end(_M_r); }
1390 empty() requires requires { ranges::empty(_M_r); }
1391 { return ranges::empty(_M_r); }
1394 empty() const requires requires { ranges::empty(_M_r); }
1395 { return ranges::empty(_M_r); }
1398 size() requires sized_range<_Range>
1399 { return ranges::size(_M_r); }
1402 size() const requires sized_range<const _Range>
1403 { return ranges::size(_M_r); }
1406 data() requires contiguous_range<_Range>
1407 { return ranges::data(_M_r); }
1410 data() const requires contiguous_range<const _Range>
1411 { return ranges::data(_M_r); }
1414 template<typename _Tp>
1415 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1416 = enable_borrowed_range<_Tp>;
1422 template<typename _Range>
1423 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1425 template<typename _Range>
1426 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1427 } // namespace __detail
1429 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1431 template<typename _Range>
1432 static constexpr bool
1435 if constexpr (view<decay_t<_Range>>)
1436 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1437 else if constexpr (__detail::__can_ref_view<_Range>)
1440 return noexcept(owning_view{std::declval<_Range>()});
1443 template<viewable_range _Range>
1444 requires view<decay_t<_Range>>
1445 || __detail::__can_ref_view<_Range>
1446 || __detail::__can_owning_view<_Range>
1448 operator() [[nodiscard]] (_Range&& __r) const
1449 noexcept(_S_noexcept<_Range>())
1451 if constexpr (view<decay_t<_Range>>)
1452 return std::forward<_Range>(__r);
1453 else if constexpr (__detail::__can_ref_view<_Range>)
1454 return ref_view{std::forward<_Range>(__r)};
1456 return owning_view{std::forward<_Range>(__r)};
1459 static constexpr bool _S_has_simple_call_op = true;
1462 inline constexpr _All all;
1464 template<viewable_range _Range>
1465 using all_t = decltype(all(std::declval<_Range>()));
1466 } // namespace views
1470 template<typename _Tp>
1471 struct __non_propagating_cache
1473 // When _Tp is not an object type (e.g. is a reference type), we make
1474 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1475 // users can easily conditionally declare data members with this type
1476 // (such as join_view::_M_inner).
1479 template<typename _Tp>
1480 requires is_object_v<_Tp>
1481 struct __non_propagating_cache<_Tp>
1482 : protected _Optional_base<_Tp>
1484 __non_propagating_cache() = default;
1487 __non_propagating_cache(const __non_propagating_cache&) noexcept
1491 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1492 { __other._M_reset(); }
1494 constexpr __non_propagating_cache&
1495 operator=(const __non_propagating_cache& __other) noexcept
1497 if (std::__addressof(__other) != this)
1502 constexpr __non_propagating_cache&
1503 operator=(__non_propagating_cache&& __other) noexcept
1510 constexpr __non_propagating_cache&
1511 operator=(_Tp __val)
1514 this->_M_payload._M_construct(std::move(__val));
1519 operator bool() const noexcept
1520 { return this->_M_is_engaged(); }
1523 operator*() noexcept
1524 { return this->_M_get(); }
1526 constexpr const _Tp&
1527 operator*() const noexcept
1528 { return this->_M_get(); }
1530 template<typename _Iter>
1532 _M_emplace_deref(const _Iter& __i)
1535 auto __f = [] (auto& __x) { return *__x; };
1536 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1537 return this->_M_get();
1540 using _Optional_base<_Tp>::_M_reset;
1543 template<range _Range>
1544 struct _CachedPosition
1547 _M_has_value() const
1550 constexpr iterator_t<_Range>
1551 _M_get(const _Range&) const
1553 __glibcxx_assert(false);
1554 __builtin_unreachable();
1558 _M_set(const _Range&, const iterator_t<_Range>&) const
1562 template<forward_range _Range>
1563 struct _CachedPosition<_Range>
1564 : protected __non_propagating_cache<iterator_t<_Range>>
1567 _M_has_value() const
1568 { return this->_M_is_engaged(); }
1570 constexpr iterator_t<_Range>
1571 _M_get(const _Range&) const
1573 __glibcxx_assert(_M_has_value());
1578 _M_set(const _Range&, const iterator_t<_Range>& __it)
1580 __glibcxx_assert(!_M_has_value());
1581 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1583 this->_M_payload._M_engaged = true;
1587 template<random_access_range _Range>
1588 requires (sizeof(range_difference_t<_Range>)
1589 <= sizeof(iterator_t<_Range>))
1590 struct _CachedPosition<_Range>
1593 range_difference_t<_Range> _M_offset = -1;
1596 _CachedPosition() = default;
1599 _CachedPosition(const _CachedPosition&) = default;
1602 _CachedPosition(_CachedPosition&& __other) noexcept
1603 { *this = std::move(__other); }
1605 constexpr _CachedPosition&
1606 operator=(const _CachedPosition&) = default;
1608 constexpr _CachedPosition&
1609 operator=(_CachedPosition&& __other) noexcept
1611 // Propagate the cached offset, but invalidate the source.
1612 _M_offset = __other._M_offset;
1613 __other._M_offset = -1;
1618 _M_has_value() const
1619 { return _M_offset >= 0; }
1621 constexpr iterator_t<_Range>
1622 _M_get(_Range& __r) const
1624 __glibcxx_assert(_M_has_value());
1625 return ranges::begin(__r) + _M_offset;
1629 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1631 __glibcxx_assert(!_M_has_value());
1632 _M_offset = __it - ranges::begin(__r);
1635 } // namespace __detail
1639 template<typename _Base>
1640 struct __filter_view_iter_cat
1643 template<forward_range _Base>
1644 struct __filter_view_iter_cat<_Base>
1650 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1651 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1652 return bidirectional_iterator_tag{};
1653 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1654 return forward_iterator_tag{};
1659 using iterator_category = decltype(_S_iter_cat());
1661 } // namespace __detail
1663 template<input_range _Vp,
1664 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1665 requires view<_Vp> && is_object_v<_Pred>
1666 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1671 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1674 static constexpr auto
1677 if constexpr (bidirectional_range<_Vp>)
1678 return bidirectional_iterator_tag{};
1679 else if constexpr (forward_range<_Vp>)
1680 return forward_iterator_tag{};
1682 return input_iterator_tag{};
1687 using _Vp_iter = iterator_t<_Vp>;
1689 _Vp_iter _M_current = _Vp_iter();
1690 filter_view* _M_parent = nullptr;
1693 using iterator_concept = decltype(_S_iter_concept());
1694 // iterator_category defined in __filter_view_iter_cat
1695 using value_type = range_value_t<_Vp>;
1696 using difference_type = range_difference_t<_Vp>;
1698 _Iterator() requires default_initializable<_Vp_iter> = default;
1701 _Iterator(filter_view* __parent, _Vp_iter __current)
1702 : _M_current(std::move(__current)),
1706 constexpr const _Vp_iter&
1707 base() const & noexcept
1708 { return _M_current; }
1712 { return std::move(_M_current); }
1714 constexpr range_reference_t<_Vp>
1716 { return *_M_current; }
1720 requires __detail::__has_arrow<_Vp_iter>
1721 && copyable<_Vp_iter>
1722 { return _M_current; }
1724 constexpr _Iterator&
1727 _M_current = ranges::find_if(std::move(++_M_current),
1728 ranges::end(_M_parent->_M_base),
1729 std::ref(*_M_parent->_M_pred));
1738 operator++(int) requires forward_range<_Vp>
1745 constexpr _Iterator&
1746 operator--() requires bidirectional_range<_Vp>
1750 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1755 operator--(int) requires bidirectional_range<_Vp>
1762 friend constexpr bool
1763 operator==(const _Iterator& __x, const _Iterator& __y)
1764 requires equality_comparable<_Vp_iter>
1765 { return __x._M_current == __y._M_current; }
1767 friend constexpr range_rvalue_reference_t<_Vp>
1768 iter_move(const _Iterator& __i)
1769 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1770 { return ranges::iter_move(__i._M_current); }
1772 friend constexpr void
1773 iter_swap(const _Iterator& __x, const _Iterator& __y)
1774 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1775 requires indirectly_swappable<_Vp_iter>
1776 { ranges::iter_swap(__x._M_current, __y._M_current); }
1782 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1785 __equal(const _Iterator& __i) const
1786 { return __i._M_current == _M_end; }
1789 _Sentinel() = default;
1792 _Sentinel(filter_view* __parent)
1793 : _M_end(ranges::end(__parent->_M_base))
1796 constexpr sentinel_t<_Vp>
1800 friend constexpr bool
1801 operator==(const _Iterator& __x, const _Sentinel& __y)
1802 { return __y.__equal(__x); }
1805 _Vp _M_base = _Vp();
1806 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1807 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1810 filter_view() requires (default_initializable<_Vp>
1811 && default_initializable<_Pred>)
1815 filter_view(_Vp __base, _Pred __pred)
1816 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1820 base() const& requires copy_constructible<_Vp>
1825 { return std::move(_M_base); }
1827 constexpr const _Pred&
1829 { return *_M_pred; }
1834 if (_M_cached_begin._M_has_value())
1835 return {this, _M_cached_begin._M_get(_M_base)};
1837 __glibcxx_assert(_M_pred.has_value());
1838 auto __it = ranges::find_if(ranges::begin(_M_base),
1839 ranges::end(_M_base),
1840 std::ref(*_M_pred));
1841 _M_cached_begin._M_set(_M_base, __it);
1842 return {this, std::move(__it)};
1848 if constexpr (common_range<_Vp>)
1849 return _Iterator{this, ranges::end(_M_base)};
1851 return _Sentinel{this};
1855 template<typename _Range, typename _Pred>
1856 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1862 template<typename _Range, typename _Pred>
1863 concept __can_filter_view
1864 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1865 } // namespace __detail
1867 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1869 template<viewable_range _Range, typename _Pred>
1870 requires __detail::__can_filter_view<_Range, _Pred>
1872 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1874 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1877 using _RangeAdaptor<_Filter>::operator();
1878 static constexpr int _S_arity = 2;
1879 static constexpr bool _S_has_simple_extra_args = true;
1882 inline constexpr _Filter filter;
1883 } // namespace views
1885#if __cpp_lib_ranges >= 202207L // C++ >= 23
1886 template<input_range _Vp, move_constructible _Fp>
1888 template<input_range _Vp, copy_constructible _Fp>
1890 requires view<_Vp> && is_object_v<_Fp>
1891 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1892 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1893 range_reference_t<_Vp>>>
1894 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1897 template<bool _Const>
1898 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1900 template<bool _Const>
1904 template<bool _Const>
1905 requires forward_range<_Base<_Const>>
1906 struct __iter_cat<_Const>
1912 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1913 // 3564. transform_view::iterator<true>::value_type and
1914 // iterator_category should use const F&
1915 using _Base = transform_view::_Base<_Const>;
1916 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1917 range_reference_t<_Base>>;
1918 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1919 // 3798. Rvalue reference and iterator_category
1920 if constexpr (is_reference_v<_Res>)
1923 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1924 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1925 return random_access_iterator_tag{};
1930 return input_iterator_tag{};
1933 using iterator_category = decltype(_S_iter_cat());
1936 template<bool _Const>
1939 template<bool _Const>
1940 struct _Iterator : __iter_cat<_Const>
1943 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1944 using _Base = transform_view::_Base<_Const>;
1949 if constexpr (random_access_range<_Base>)
1950 return random_access_iterator_tag{};
1951 else if constexpr (bidirectional_range<_Base>)
1952 return bidirectional_iterator_tag{};
1953 else if constexpr (forward_range<_Base>)
1954 return forward_iterator_tag{};
1956 return input_iterator_tag{};
1959 using _Base_iter = iterator_t<_Base>;
1961 _Base_iter _M_current = _Base_iter();
1962 _Parent* _M_parent = nullptr;
1965 using iterator_concept = decltype(_S_iter_concept());
1966 // iterator_category defined in __transform_view_iter_cat
1968 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1969 range_reference_t<_Base>>>;
1970 using difference_type = range_difference_t<_Base>;
1972 _Iterator() requires default_initializable<_Base_iter> = default;
1975 _Iterator(_Parent* __parent, _Base_iter __current)
1976 : _M_current(std::move(__current)),
1981 _Iterator(_Iterator<!_Const> __i)
1983 && convertible_to<iterator_t<_Vp>, _Base_iter>
1984 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1987 constexpr const _Base_iter&
1988 base() const & noexcept
1989 { return _M_current; }
1991 constexpr _Base_iter
1993 { return std::move(_M_current); }
1995 constexpr decltype(auto)
1997 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1998 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
2000 constexpr _Iterator&
2012 operator++(int) requires forward_range<_Base>
2019 constexpr _Iterator&
2020 operator--() requires bidirectional_range<_Base>
2027 operator--(int) requires bidirectional_range<_Base>
2034 constexpr _Iterator&
2035 operator+=(difference_type __n) requires random_access_range<_Base>
2041 constexpr _Iterator&
2042 operator-=(difference_type __n) requires random_access_range<_Base>
2048 constexpr decltype(auto)
2049 operator[](difference_type __n) const
2050 requires random_access_range<_Base>
2051 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
2053 friend constexpr bool
2054 operator==(const _Iterator& __x, const _Iterator& __y)
2055 requires equality_comparable<_Base_iter>
2056 { return __x._M_current == __y._M_current; }
2058 friend constexpr bool
2059 operator<(const _Iterator& __x, const _Iterator& __y)
2060 requires random_access_range<_Base>
2061 { return __x._M_current < __y._M_current; }
2063 friend constexpr bool
2064 operator>(const _Iterator& __x, const _Iterator& __y)
2065 requires random_access_range<_Base>
2066 { return __y < __x; }
2068 friend constexpr bool
2069 operator<=(const _Iterator& __x, const _Iterator& __y)
2070 requires random_access_range<_Base>
2071 { return !(__y < __x); }
2073 friend constexpr bool
2074 operator>=(const _Iterator& __x, const _Iterator& __y)
2075 requires random_access_range<_Base>
2076 { return !(__x < __y); }
2078#ifdef __cpp_lib_three_way_comparison
2079 friend constexpr auto
2080 operator<=>(const _Iterator& __x, const _Iterator& __y)
2081 requires random_access_range<_Base>
2082 && three_way_comparable<_Base_iter>
2083 { return __x._M_current <=> __y._M_current; }
2086 friend constexpr _Iterator
2087 operator+(_Iterator __i, difference_type __n)
2088 requires random_access_range<_Base>
2089 { return {__i._M_parent, __i._M_current + __n}; }
2091 friend constexpr _Iterator
2092 operator+(difference_type __n, _Iterator __i)
2093 requires random_access_range<_Base>
2094 { return {__i._M_parent, __i._M_current + __n}; }
2096 friend constexpr _Iterator
2097 operator-(_Iterator __i, difference_type __n)
2098 requires random_access_range<_Base>
2099 { return {__i._M_parent, __i._M_current - __n}; }
2101 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2102 // 3483. transform_view::iterator's difference is overconstrained
2103 friend constexpr difference_type
2104 operator-(const _Iterator& __x, const _Iterator& __y)
2105 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2106 { return __x._M_current - __y._M_current; }
2108 friend constexpr decltype(auto)
2109 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
2111 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
2112 return std::move(*__i);
2117 friend _Iterator<!_Const>;
2118 template<bool> friend struct _Sentinel;
2121 template<bool _Const>
2125 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2126 using _Base = transform_view::_Base<_Const>;
2128 template<bool _Const2>
2130 __distance_from(const _Iterator<_Const2>& __i) const
2131 { return _M_end - __i._M_current; }
2133 template<bool _Const2>
2135 __equal(const _Iterator<_Const2>& __i) const
2136 { return __i._M_current == _M_end; }
2138 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2141 _Sentinel() = default;
2144 _Sentinel(sentinel_t<_Base> __end)
2149 _Sentinel(_Sentinel<!_Const> __i)
2151 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2152 : _M_end(std::move(__i._M_end))
2155 constexpr sentinel_t<_Base>
2159 template<bool _Const2>
2160 requires sentinel_for<sentinel_t<_Base>,
2161 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2162 friend constexpr bool
2163 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2164 { return __y.__equal(__x); }
2166 template<bool _Const2,
2167 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2168 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2169 friend constexpr range_difference_t<_Base2>
2170 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2171 { return -__y.__distance_from(__x); }
2173 template<bool _Const2,
2174 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2175 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2176 friend constexpr range_difference_t<_Base2>
2177 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2178 { return __y.__distance_from(__x); }
2180 friend _Sentinel<!_Const>;
2183 _Vp _M_base = _Vp();
2184 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2187 transform_view() requires (default_initializable<_Vp>
2188 && default_initializable<_Fp>)
2192 transform_view(_Vp __base, _Fp __fun)
2193 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2197 base() const& requires copy_constructible<_Vp>
2198 { return _M_base ; }
2202 { return std::move(_M_base); }
2204 constexpr _Iterator<false>
2206 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2208 constexpr _Iterator<true>
2210 requires range<const _Vp>
2211 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2212 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2214 constexpr _Sentinel<false>
2216 { return _Sentinel<false>{ranges::end(_M_base)}; }
2218 constexpr _Iterator<false>
2219 end() requires common_range<_Vp>
2220 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2222 constexpr _Sentinel<true>
2224 requires range<const _Vp>
2225 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2226 { return _Sentinel<true>{ranges::end(_M_base)}; }
2228 constexpr _Iterator<true>
2230 requires common_range<const _Vp>
2231 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2232 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2235 size() requires sized_range<_Vp>
2236 { return ranges::size(_M_base); }
2239 size() const requires sized_range<const _Vp>
2240 { return ranges::size(_M_base); }
2243 template<typename _Range, typename _Fp>
2244 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2250 template<typename _Range, typename _Fp>
2251 concept __can_transform_view
2252 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2253 } // namespace __detail
2255 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2257 template<viewable_range _Range, typename _Fp>
2258 requires __detail::__can_transform_view<_Range, _Fp>
2260 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2262 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2265 using _RangeAdaptor<_Transform>::operator();
2266 static constexpr int _S_arity = 2;
2267 static constexpr bool _S_has_simple_extra_args = true;
2270 inline constexpr _Transform transform;
2271 } // namespace views
2274 class take_view : public view_interface<take_view<_Vp>>
2277 template<bool _Const>
2278 using _CI = counted_iterator<
2279 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2281 template<bool _Const>
2285 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2286 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2289 _Sentinel() = default;
2292 _Sentinel(sentinel_t<_Base> __end)
2297 _Sentinel(_Sentinel<!_Const> __s)
2298 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2299 : _M_end(std::move(__s._M_end))
2302 constexpr sentinel_t<_Base>
2306 friend constexpr bool
2307 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2308 { return __y.count() == 0 || __y.base() == __x._M_end; }
2310 template<bool _OtherConst = !_Const,
2311 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2312 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2313 friend constexpr bool
2314 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2315 { return __y.count() == 0 || __y.base() == __x._M_end; }
2317 friend _Sentinel<!_Const>;
2320 _Vp _M_base = _Vp();
2321 range_difference_t<_Vp> _M_count = 0;
2324 take_view() requires default_initializable<_Vp> = default;
2327 take_view(_Vp __base, range_difference_t<_Vp> __count)
2328 : _M_base(std::move(__base)), _M_count(std::move(__count))
2332 base() const& requires copy_constructible<_Vp>
2337 { return std::move(_M_base); }
2340 begin() requires (!__detail::__simple_view<_Vp>)
2342 if constexpr (sized_range<_Vp>)
2344 if constexpr (random_access_range<_Vp>)
2345 return ranges::begin(_M_base);
2349 return counted_iterator(ranges::begin(_M_base), __sz);
2353 return counted_iterator(ranges::begin(_M_base), _M_count);
2357 begin() const requires range<const _Vp>
2359 if constexpr (sized_range<const _Vp>)
2361 if constexpr (random_access_range<const _Vp>)
2362 return ranges::begin(_M_base);
2366 return counted_iterator(ranges::begin(_M_base), __sz);
2370 return counted_iterator(ranges::begin(_M_base), _M_count);
2374 end() requires (!__detail::__simple_view<_Vp>)
2376 if constexpr (sized_range<_Vp>)
2378 if constexpr (random_access_range<_Vp>)
2379 return ranges::begin(_M_base) + size();
2381 return default_sentinel;
2384 return _Sentinel<false>{ranges::end(_M_base)};
2388 end() const requires range<const _Vp>
2390 if constexpr (sized_range<const _Vp>)
2392 if constexpr (random_access_range<const _Vp>)
2393 return ranges::begin(_M_base) + size();
2395 return default_sentinel;
2398 return _Sentinel<true>{ranges::end(_M_base)};
2402 size() requires sized_range<_Vp>
2404 auto __n = ranges::size(_M_base);
2405 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2409 size() const requires sized_range<const _Vp>
2411 auto __n = ranges::size(_M_base);
2412 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2416 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2417 // 3447. Deduction guides for take_view and drop_view have different
2419 template<typename _Range>
2420 take_view(_Range&&, range_difference_t<_Range>)
2421 -> take_view<views::all_t<_Range>>;
2423 template<typename _Tp>
2424 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2425 = enable_borrowed_range<_Tp>;
2431 template<typename _Range>
2432 inline constexpr bool __is_empty_view = false;
2434 template<typename _Tp>
2435 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2437 template<typename _Range>
2438 inline constexpr bool __is_basic_string_view = false;
2440 template<typename _CharT, typename _Traits>
2441 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2444 using ranges::__detail::__is_subrange;
2446 template<typename _Range>
2447 inline constexpr bool __is_iota_view = false;
2449 template<typename _Winc, typename _Bound>
2450 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2452 template<typename _Range>
2453 inline constexpr bool __is_repeat_view = false;
2455 template<typename _Range>
2457 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2459 template<typename _Range, typename _Dp>
2460 concept __can_take_view
2461 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2462 } // namespace __detail
2464 struct _Take : __adaptor::_RangeAdaptor<_Take>
2466 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2467 requires __detail::__can_take_view<_Range, _Dp>
2469 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2471 using _Tp = remove_cvref_t<_Range>;
2472 if constexpr (__detail::__is_empty_view<_Tp>)
2474 else if constexpr (random_access_range<_Tp>
2476 && (std::__detail::__is_span<_Tp>
2477 || __detail::__is_basic_string_view<_Tp>
2478 || __detail::__is_subrange<_Tp>
2479 || __detail::__is_iota_view<_Tp>))
2481 __n = std::min<_Dp>(ranges::distance(__r), __n);
2482 auto __begin = ranges::begin(__r);
2483 auto __end = __begin + __n;
2484 if constexpr (std::__detail::__is_span<_Tp>)
2485 return span<typename _Tp::element_type>(__begin, __end);
2486 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2487 return _Tp(__begin, __end);
2488 else if constexpr (__detail::__is_subrange<_Tp>)
2489 return subrange<iterator_t<_Tp>>(__begin, __end);
2491 return iota_view(*__begin, *__end);
2493 else if constexpr (__detail::__is_repeat_view<_Tp>)
2494 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2496 return take_view(std::forward<_Range>(__r), __n);
2499 using _RangeAdaptor<_Take>::operator();
2500 static constexpr int _S_arity = 2;
2501 // The count argument of views::take is not always simple -- it can be
2502 // e.g. a move-only class that's implicitly convertible to the difference
2503 // type. But an integer-like count argument is surely simple.
2504 template<typename _Tp>
2505 static constexpr bool _S_has_simple_extra_args
2506 = ranges::__detail::__is_integer_like<_Tp>;
2509 inline constexpr _Take take;
2510 } // namespace views
2512 template<view _Vp, typename _Pred>
2513 requires input_range<_Vp> && is_object_v<_Pred>
2514 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2515 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2517 template<bool _Const>
2521 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2523 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2524 const _Pred* _M_pred = nullptr;
2527 _Sentinel() = default;
2530 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2531 : _M_end(__end), _M_pred(__pred)
2535 _Sentinel(_Sentinel<!_Const> __s)
2536 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2537 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2540 constexpr sentinel_t<_Base>
2541 base() const { return _M_end; }
2543 friend constexpr bool
2544 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2545 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2547 template<bool _OtherConst = !_Const,
2548 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2549 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2550 friend constexpr bool
2551 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2552 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2554 friend _Sentinel<!_Const>;
2557 _Vp _M_base = _Vp();
2558 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2561 take_while_view() requires (default_initializable<_Vp>
2562 && default_initializable<_Pred>)
2566 take_while_view(_Vp __base, _Pred __pred)
2567 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2571 base() const& requires copy_constructible<_Vp>
2576 { return std::move(_M_base); }
2578 constexpr const _Pred&
2580 { return *_M_pred; }
2583 begin() requires (!__detail::__simple_view<_Vp>)
2584 { return ranges::begin(_M_base); }
2587 begin() const requires range<const _Vp>
2588 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2589 { return ranges::begin(_M_base); }
2592 end() requires (!__detail::__simple_view<_Vp>)
2593 { return _Sentinel<false>(ranges::end(_M_base),
2594 std::__addressof(*_M_pred)); }
2597 end() const requires range<const _Vp>
2598 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2599 { return _Sentinel<true>(ranges::end(_M_base),
2600 std::__addressof(*_M_pred)); }
2603 template<typename _Range, typename _Pred>
2604 take_while_view(_Range&&, _Pred)
2605 -> take_while_view<views::all_t<_Range>, _Pred>;
2611 template<typename _Range, typename _Pred>
2612 concept __can_take_while_view
2613 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2614 } // namespace __detail
2616 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2618 template<viewable_range _Range, typename _Pred>
2619 requires __detail::__can_take_while_view<_Range, _Pred>
2621 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2623 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2626 using _RangeAdaptor<_TakeWhile>::operator();
2627 static constexpr int _S_arity = 2;
2628 static constexpr bool _S_has_simple_extra_args = true;
2631 inline constexpr _TakeWhile take_while;
2632 } // namespace views
2635 class drop_view : public view_interface<drop_view<_Vp>>
2638 _Vp _M_base = _Vp();
2639 range_difference_t<_Vp> _M_count = 0;
2641 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2642 // both random_access_range and sized_range. Otherwise, cache its result.
2643 static constexpr bool _S_needs_cached_begin
2644 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2645 [[no_unique_address]]
2646 __detail::__maybe_present_t<_S_needs_cached_begin,
2647 __detail::_CachedPosition<_Vp>>
2651 drop_view() requires default_initializable<_Vp> = default;
2654 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2655 : _M_base(std::move(__base)), _M_count(__count)
2656 { __glibcxx_assert(__count >= 0); }
2659 base() const& requires copy_constructible<_Vp>
2664 { return std::move(_M_base); }
2666 // This overload is disabled for simple views with constant-time begin().
2669 requires (!(__detail::__simple_view<_Vp>
2670 && random_access_range<const _Vp>
2671 && sized_range<const _Vp>))
2673 if constexpr (_S_needs_cached_begin)
2674 if (_M_cached_begin._M_has_value())
2675 return _M_cached_begin._M_get(_M_base);
2677 auto __it = ranges::next(ranges::begin(_M_base),
2678 _M_count, ranges::end(_M_base));
2679 if constexpr (_S_needs_cached_begin)
2680 _M_cached_begin._M_set(_M_base, __it);
2684 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2685 // 3482. drop_view's const begin should additionally require sized_range
2688 requires random_access_range<const _Vp> && sized_range<const _Vp>
2690 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2695 end() requires (!__detail::__simple_view<_Vp>)
2696 { return ranges::end(_M_base); }
2699 end() const requires range<const _Vp>
2700 { return ranges::end(_M_base); }
2703 size() requires sized_range<_Vp>
2705 const auto __s = ranges::size(_M_base);
2706 const auto __c = static_cast<decltype(__s)>(_M_count);
2707 return __s < __c ? 0 : __s - __c;
2711 size() const requires sized_range<const _Vp>
2713 const auto __s = ranges::size(_M_base);
2714 const auto __c = static_cast<decltype(__s)>(_M_count);
2715 return __s < __c ? 0 : __s - __c;
2719 template<typename _Range>
2720 drop_view(_Range&&, range_difference_t<_Range>)
2721 -> drop_view<views::all_t<_Range>>;
2723 template<typename _Tp>
2724 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2725 = enable_borrowed_range<_Tp>;
2731 template<typename _Range>
2733 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2735 template<typename _Range, typename _Dp>
2736 concept __can_drop_view
2737 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2738 } // namespace __detail
2740 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2742 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2743 requires __detail::__can_drop_view<_Range, _Dp>
2745 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2747 using _Tp = remove_cvref_t<_Range>;
2748 if constexpr (__detail::__is_empty_view<_Tp>)
2750 else if constexpr (random_access_range<_Tp>
2752 && (std::__detail::__is_span<_Tp>
2753 || __detail::__is_basic_string_view<_Tp>
2754 || __detail::__is_iota_view<_Tp>
2755 || __detail::__is_subrange<_Tp>))
2757 __n = std::min<_Dp>(ranges::distance(__r), __n);
2758 auto __begin = ranges::begin(__r) + __n;
2759 auto __end = ranges::end(__r);
2760 if constexpr (std::__detail::__is_span<_Tp>)
2761 return span<typename _Tp::element_type>(__begin, __end);
2762 else if constexpr (__detail::__is_subrange<_Tp>)
2764 if constexpr (_Tp::_S_store_size)
2766 using ranges::__detail::__to_unsigned_like;
2767 auto __m = ranges::distance(__r) - __n;
2768 return _Tp(__begin, __end, __to_unsigned_like(__m));
2771 return _Tp(__begin, __end);
2774 return _Tp(__begin, __end);
2776 else if constexpr (__detail::__is_repeat_view<_Tp>)
2777 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2779 return drop_view(std::forward<_Range>(__r), __n);
2782 using _RangeAdaptor<_Drop>::operator();
2783 static constexpr int _S_arity = 2;
2784 template<typename _Tp>
2785 static constexpr bool _S_has_simple_extra_args
2786 = _Take::_S_has_simple_extra_args<_Tp>;
2789 inline constexpr _Drop drop;
2790 } // namespace views
2792 template<view _Vp, typename _Pred>
2793 requires input_range<_Vp> && is_object_v<_Pred>
2794 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2795 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2798 _Vp _M_base = _Vp();
2799 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2800 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2803 drop_while_view() requires (default_initializable<_Vp>
2804 && default_initializable<_Pred>)
2808 drop_while_view(_Vp __base, _Pred __pred)
2809 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2813 base() const& requires copy_constructible<_Vp>
2818 { return std::move(_M_base); }
2820 constexpr const _Pred&
2822 { return *_M_pred; }
2827 if (_M_cached_begin._M_has_value())
2828 return _M_cached_begin._M_get(_M_base);
2830 __glibcxx_assert(_M_pred.has_value());
2831 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2832 ranges::end(_M_base),
2833 std::cref(*_M_pred));
2834 _M_cached_begin._M_set(_M_base, __it);
2840 { return ranges::end(_M_base); }
2843 template<typename _Range, typename _Pred>
2844 drop_while_view(_Range&&, _Pred)
2845 -> drop_while_view<views::all_t<_Range>, _Pred>;
2847 template<typename _Tp, typename _Pred>
2848 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2849 = enable_borrowed_range<_Tp>;
2855 template<typename _Range, typename _Pred>
2856 concept __can_drop_while_view
2857 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2858 } // namespace __detail
2860 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2862 template<viewable_range _Range, typename _Pred>
2863 requires __detail::__can_drop_while_view<_Range, _Pred>
2865 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2867 return drop_while_view(std::forward<_Range>(__r),
2868 std::forward<_Pred>(__p));
2871 using _RangeAdaptor<_DropWhile>::operator();
2872 static constexpr int _S_arity = 2;
2873 static constexpr bool _S_has_simple_extra_args = true;
2876 inline constexpr _DropWhile drop_while;
2877 } // namespace views
2881 template<typename _Tp>
2883 __as_lvalue(_Tp&& __t)
2884 { return static_cast<_Tp&>(__t); }
2885 } // namespace __detail
2887 template<input_range _Vp>
2888 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2889 class join_view : public view_interface<join_view<_Vp>>
2892 using _InnerRange = range_reference_t<_Vp>;
2894 template<bool _Const>
2895 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2897 template<bool _Const>
2898 using _Outer_iter = iterator_t<_Base<_Const>>;
2900 template<bool _Const>
2901 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2903 template<bool _Const>
2904 static constexpr bool _S_ref_is_glvalue
2905 = is_reference_v<range_reference_t<_Base<_Const>>>;
2907 template<bool _Const>
2911 template<bool _Const>
2912 requires _S_ref_is_glvalue<_Const>
2913 && forward_range<_Base<_Const>>
2914 && forward_range<range_reference_t<_Base<_Const>>>
2915 struct __iter_cat<_Const>
2918 static constexpr auto
2921 using _Outer_iter = join_view::_Outer_iter<_Const>;
2922 using _Inner_iter = join_view::_Inner_iter<_Const>;
2923 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2924 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2925 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2926 && derived_from<_InnerCat, bidirectional_iterator_tag>
2927 && common_range<range_reference_t<_Base<_Const>>>)
2928 return bidirectional_iterator_tag{};
2929 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2930 && derived_from<_InnerCat, forward_iterator_tag>)
2931 return forward_iterator_tag{};
2933 return input_iterator_tag{};
2936 using iterator_category = decltype(_S_iter_cat());
2939 template<bool _Const>
2942 template<bool _Const>
2943 struct _Iterator : __iter_cat<_Const>
2946 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2947 using _Base = join_view::_Base<_Const>;
2951 static constexpr bool _S_ref_is_glvalue
2952 = join_view::_S_ref_is_glvalue<_Const>;
2957 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2958 if constexpr (_S_ref_is_glvalue)
2961 return _M_parent->_M_inner._M_emplace_deref(__x);
2964 _Outer_iter& __outer = _M_get_outer();
2965 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2967 auto&& __inner = __update_inner(__outer);
2968 _M_inner = ranges::begin(__inner);
2969 if (_M_inner != ranges::end(__inner))
2973 if constexpr (_S_ref_is_glvalue)
2977 static constexpr auto
2980 if constexpr (_S_ref_is_glvalue
2981 && bidirectional_range<_Base>
2982 && bidirectional_range<range_reference_t<_Base>>
2983 && common_range<range_reference_t<_Base>>)
2984 return bidirectional_iterator_tag{};
2985 else if constexpr (_S_ref_is_glvalue
2986 && forward_range<_Base>
2987 && forward_range<range_reference_t<_Base>>)
2988 return forward_iterator_tag{};
2990 return input_iterator_tag{};
2993 using _Outer_iter = join_view::_Outer_iter<_Const>;
2994 using _Inner_iter = join_view::_Inner_iter<_Const>;
2996 constexpr _Outer_iter&
2999 if constexpr (forward_range<_Base>)
3002 return *_M_parent->_M_outer;
3005 constexpr const _Outer_iter&
3006 _M_get_outer() const
3008 if constexpr (forward_range<_Base>)
3011 return *_M_parent->_M_outer;
3015 _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base>
3016 : _M_outer(std::move(__outer)), _M_parent(__parent)
3020 _Iterator(_Parent* __parent) requires (!forward_range<_Base>)
3021 : _M_parent(__parent)
3024 [[no_unique_address]]
3025 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer;
3026 optional<_Inner_iter> _M_inner;
3027 _Parent* _M_parent = nullptr;
3030 using iterator_concept = decltype(_S_iter_concept());
3031 // iterator_category defined in __join_view_iter_cat
3032 using value_type = range_value_t<range_reference_t<_Base>>;
3033 using difference_type
3034 = common_type_t<range_difference_t<_Base>,
3035 range_difference_t<range_reference_t<_Base>>>;
3037 _Iterator() = default;
3040 _Iterator(_Iterator<!_Const> __i)
3042 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3043 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3044 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
3045 _M_parent(__i._M_parent)
3048 constexpr decltype(auto)
3050 { return **_M_inner; }
3052 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3053 // 3500. join_view::iterator::operator->() is bogus
3054 constexpr _Inner_iter
3056 requires __detail::__has_arrow<_Inner_iter>
3057 && copyable<_Inner_iter>
3058 { return *_M_inner; }
3060 constexpr _Iterator&
3063 auto&& __inner_range = [this] () -> auto&& {
3064 if constexpr (_S_ref_is_glvalue)
3065 return *_M_get_outer();
3067 return *_M_parent->_M_inner;
3069 if (++*_M_inner == ranges::end(__inner_range))
3083 requires _S_ref_is_glvalue && forward_range<_Base>
3084 && forward_range<range_reference_t<_Base>>
3091 constexpr _Iterator&
3093 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3094 && bidirectional_range<range_reference_t<_Base>>
3095 && common_range<range_reference_t<_Base>>
3097 if (_M_outer == ranges::end(_M_parent->_M_base))
3098 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3099 while (*_M_inner == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3100 *_M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3107 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3108 && bidirectional_range<range_reference_t<_Base>>
3109 && common_range<range_reference_t<_Base>>
3116 friend constexpr bool
3117 operator==(const _Iterator& __x, const _Iterator& __y)
3118 requires _S_ref_is_glvalue
3119 && forward_range<_Base>
3120 && equality_comparable<_Inner_iter>
3122 return (__x._M_outer == __y._M_outer
3123 && __x._M_inner == __y._M_inner);
3126 friend constexpr decltype(auto)
3127 iter_move(const _Iterator& __i)
3128 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
3129 { return ranges::iter_move(*__i._M_inner); }
3131 friend constexpr void
3132 iter_swap(const _Iterator& __x, const _Iterator& __y)
3133 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
3134 requires indirectly_swappable<_Inner_iter>
3135 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
3137 friend _Iterator<!_Const>;
3138 template<bool> friend struct _Sentinel;
3141 template<bool _Const>
3145 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3146 using _Base = join_view::_Base<_Const>;
3148 template<bool _Const2>
3150 __equal(const _Iterator<_Const2>& __i) const
3151 { return __i._M_get_outer() == _M_end; }
3153 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3156 _Sentinel() = default;
3159 _Sentinel(_Parent* __parent)
3160 : _M_end(ranges::end(__parent->_M_base))
3164 _Sentinel(_Sentinel<!_Const> __s)
3165 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3166 : _M_end(std::move(__s._M_end))
3169 template<bool _Const2>
3170 requires sentinel_for<sentinel_t<_Base>,
3171 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3172 friend constexpr bool
3173 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3174 { return __y.__equal(__x); }
3176 friend _Sentinel<!_Const>;
3179 _Vp _M_base = _Vp();
3180 [[no_unique_address]]
3181 __detail::__maybe_present_t<!forward_range<_Vp>,
3182 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3183 [[no_unique_address]]
3184 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3187 join_view() requires default_initializable<_Vp> = default;
3190 join_view(_Vp __base)
3191 : _M_base(std::move(__base))
3195 base() const& requires copy_constructible<_Vp>
3200 { return std::move(_M_base); }
3205 if constexpr (forward_range<_Vp>)
3207 constexpr bool __use_const
3208 = (__detail::__simple_view<_Vp>
3209 && is_reference_v<range_reference_t<_Vp>>);
3210 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3214 _M_outer = ranges::begin(_M_base);
3215 return _Iterator<false>{this};
3221 requires forward_range<const _Vp>
3222 && is_reference_v<range_reference_t<const _Vp>>
3223 && input_range<range_reference_t<const _Vp>>
3225 return _Iterator<true>{this, ranges::begin(_M_base)};
3231 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3232 && forward_range<_InnerRange>
3233 && common_range<_Vp> && common_range<_InnerRange>)
3234 return _Iterator<__detail::__simple_view<_Vp>>{this,
3235 ranges::end(_M_base)};
3237 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3242 requires forward_range<const _Vp>
3243 && is_reference_v<range_reference_t<const _Vp>>
3244 && input_range<range_reference_t<const _Vp>>
3246 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3247 && forward_range<range_reference_t<const _Vp>>
3248 && common_range<const _Vp>
3249 && common_range<range_reference_t<const _Vp>>)
3250 return _Iterator<true>{this, ranges::end(_M_base)};
3252 return _Sentinel<true>{this};
3256 template<typename _Range>
3257 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3263 template<typename _Range>
3264 concept __can_join_view
3265 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3266 } // namespace __detail
3268 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3270 template<viewable_range _Range>
3271 requires __detail::__can_join_view<_Range>
3273 operator() [[nodiscard]] (_Range&& __r) const
3275 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3276 // 3474. Nesting join_views is broken because of CTAD
3277 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3280 static constexpr bool _S_has_simple_call_op = true;
3283 inline constexpr _Join join;
3284 } // namespace views
3289 struct __require_constant;
3291 template<typename _Range>
3292 concept __tiny_range = sized_range<_Range>
3294 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3295 && (remove_reference_t<_Range>::size() <= 1);
3297 template<typename _Base>
3298 struct __lazy_split_view_outer_iter_cat
3301 template<forward_range _Base>
3302 struct __lazy_split_view_outer_iter_cat<_Base>
3303 { using iterator_category = input_iterator_tag; };
3305 template<typename _Base>
3306 struct __lazy_split_view_inner_iter_cat
3309 template<forward_range _Base>
3310 struct __lazy_split_view_inner_iter_cat<_Base>
3313 static constexpr auto
3316 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3317 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3318 return forward_iterator_tag{};
3323 using iterator_category = decltype(_S_iter_cat());
3327 template<input_range _Vp, forward_range _Pattern>
3328 requires view<_Vp> && view<_Pattern>
3329 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3331 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3332 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3335 template<bool _Const>
3336 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3338 template<bool _Const>
3341 template<bool _Const>
3343 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3346 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3347 using _Base = lazy_split_view::_Base<_Const>;
3351 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3353 // [range.lazy.split.outer] p1
3354 // Many of the following specifications refer to the notional member
3355 // current of outer-iterator. current is equivalent to current_ if
3356 // V models forward_range, and parent_->current_ otherwise.
3358 __current() noexcept
3360 if constexpr (forward_range<_Vp>)
3363 return *_M_parent->_M_current;
3367 __current() const noexcept
3369 if constexpr (forward_range<_Vp>)
3372 return *_M_parent->_M_current;
3375 _Parent* _M_parent = nullptr;
3377 [[no_unique_address]]
3378 __detail::__maybe_present_t<forward_range<_Vp>,
3379 iterator_t<_Base>> _M_current;
3380 bool _M_trailing_empty = false;
3383 using iterator_concept = __conditional_t<forward_range<_Base>,
3384 forward_iterator_tag,
3385 input_iterator_tag>;
3386 // iterator_category defined in __lazy_split_view_outer_iter_cat
3387 using difference_type = range_difference_t<_Base>;
3389 struct value_type : view_interface<value_type>
3392 _OuterIter _M_i = _OuterIter();
3394 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3395 // 4013. lazy_split_view::outer-iterator::value_type should not
3396 // provide default constructor
3398 value_type(_OuterIter __i)
3399 : _M_i(std::move(__i))
3405 constexpr _InnerIter<_Const>
3407 { return _InnerIter<_Const>{_M_i}; }
3409 constexpr default_sentinel_t
3410 end() const noexcept
3411 { return default_sentinel; }
3414 _OuterIter() = default;
3417 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3418 : _M_parent(__parent)
3422 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3423 requires forward_range<_Base>
3424 : _M_parent(__parent),
3425 _M_current(std::move(__current))
3429 _OuterIter(_OuterIter<!_Const> __i)
3431 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3432 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3433 _M_trailing_empty(__i._M_trailing_empty)
3436 constexpr value_type
3438 { return value_type{*this}; }
3440 constexpr _OuterIter&
3443 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3444 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3445 const auto __end = ranges::end(_M_parent->_M_base);
3446 if (__current() == __end)
3448 _M_trailing_empty = false;
3451 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3452 if (__pbegin == __pend)
3454 else if constexpr (__detail::__tiny_range<_Pattern>)
3456 __current() = ranges::find(std::move(__current()), __end,
3458 if (__current() != __end)
3461 if (__current() == __end)
3462 _M_trailing_empty = true;
3469 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3473 if (__current() == __end)
3474 _M_trailing_empty = true;
3477 } while (++__current() != __end);
3481 constexpr decltype(auto)
3484 if constexpr (forward_range<_Base>)
3494 friend constexpr bool
3495 operator==(const _OuterIter& __x, const _OuterIter& __y)
3496 requires forward_range<_Base>
3498 return __x._M_current == __y._M_current
3499 && __x._M_trailing_empty == __y._M_trailing_empty;
3502 friend constexpr bool
3503 operator==(const _OuterIter& __x, default_sentinel_t)
3504 { return __x.__at_end(); };
3506 friend _OuterIter<!_Const>;
3507 friend _InnerIter<_Const>;
3510 template<bool _Const>
3512 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3515 using _Base = lazy_split_view::_Base<_Const>;
3520 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3521 auto __end = ranges::end(_M_i._M_parent->_M_base);
3522 if constexpr (__detail::__tiny_range<_Pattern>)
3524 const auto& __cur = _M_i_current();
3527 if (__pcur == __pend)
3528 return _M_incremented;
3529 return *__cur == *__pcur;
3533 auto __cur = _M_i_current();
3536 if (__pcur == __pend)
3537 return _M_incremented;
3540 if (*__cur != *__pcur)
3542 if (++__pcur == __pend)
3544 } while (++__cur != __end);
3550 _M_i_current() noexcept
3551 { return _M_i.__current(); }
3554 _M_i_current() const noexcept
3555 { return _M_i.__current(); }
3557 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3558 bool _M_incremented = false;
3561 using iterator_concept
3562 = typename _OuterIter<_Const>::iterator_concept;
3563 // iterator_category defined in __lazy_split_view_inner_iter_cat
3564 using value_type = range_value_t<_Base>;
3565 using difference_type = range_difference_t<_Base>;
3567 _InnerIter() = default;
3570 _InnerIter(_OuterIter<_Const> __i)
3571 : _M_i(std::move(__i))
3574 constexpr const iterator_t<_Base>&
3575 base() const& noexcept
3576 { return _M_i_current(); }
3578 constexpr iterator_t<_Base>
3579 base() && requires forward_range<_Vp>
3580 { return std::move(_M_i_current()); }
3582 constexpr decltype(auto)
3584 { return *_M_i_current(); }
3586 constexpr _InnerIter&
3589 _M_incremented = true;
3590 if constexpr (!forward_range<_Base>)
3591 if constexpr (_Pattern::size() == 0)
3597 constexpr decltype(auto)
3600 if constexpr (forward_range<_Base>)
3610 friend constexpr bool
3611 operator==(const _InnerIter& __x, const _InnerIter& __y)
3612 requires forward_range<_Base>
3613 { return __x._M_i == __y._M_i; }
3615 friend constexpr bool
3616 operator==(const _InnerIter& __x, default_sentinel_t)
3617 { return __x.__at_end(); }
3619 friend constexpr decltype(auto)
3620 iter_move(const _InnerIter& __i)
3621 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3622 { return ranges::iter_move(__i._M_i_current()); }
3624 friend constexpr void
3625 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3626 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3627 __y._M_i_current())))
3628 requires indirectly_swappable<iterator_t<_Base>>
3629 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3632 _Vp _M_base = _Vp();
3633 _Pattern _M_pattern = _Pattern();
3634 [[no_unique_address]]
3635 __detail::__maybe_present_t<!forward_range<_Vp>,
3636 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3640 lazy_split_view() requires (default_initializable<_Vp>
3641 && default_initializable<_Pattern>)
3645 lazy_split_view(_Vp __base, _Pattern __pattern)
3646 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3649 template<input_range _Range>
3650 requires constructible_from<_Vp, views::all_t<_Range>>
3651 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3653 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3654 : _M_base(views::all(std::forward<_Range>(__r))),
3655 _M_pattern(views::single(std::move(__e)))
3659 base() const& requires copy_constructible<_Vp>
3664 { return std::move(_M_base); }
3669 if constexpr (forward_range<_Vp>)
3671 constexpr bool __simple
3672 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3673 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3677 _M_current = ranges::begin(_M_base);
3678 return _OuterIter<false>{this};
3683 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3685 return _OuterIter<true>{this, ranges::begin(_M_base)};
3689 end() requires forward_range<_Vp> && common_range<_Vp>
3691 constexpr bool __simple
3692 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3693 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3699 if constexpr (forward_range<_Vp>
3700 && forward_range<const _Vp>
3701 && common_range<const _Vp>)
3702 return _OuterIter<true>{this, ranges::end(_M_base)};
3704 return default_sentinel;
3708 template<typename _Range, typename _Pattern>
3709 lazy_split_view(_Range&&, _Pattern&&)
3710 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3712 template<input_range _Range>
3713 lazy_split_view(_Range&&, range_value_t<_Range>)
3714 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3720 template<typename _Range, typename _Pattern>
3721 concept __can_lazy_split_view
3722 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3723 } // namespace __detail
3725 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3727 template<viewable_range _Range, typename _Pattern>
3728 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3730 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3732 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3735 using _RangeAdaptor<_LazySplit>::operator();
3736 static constexpr int _S_arity = 2;
3737 // The pattern argument of views::lazy_split is not always simple -- it can be
3738 // a non-view range, the value category of which affects whether the call
3739 // is well-formed. But a scalar or a view pattern argument is surely
3741 template<typename _Pattern>
3742 static constexpr bool _S_has_simple_extra_args
3743 = is_scalar_v<_Pattern> || (view<_Pattern>
3744 && copy_constructible<_Pattern>);
3747 inline constexpr _LazySplit lazy_split;
3748 } // namespace views
3750 template<forward_range _Vp, forward_range _Pattern>
3751 requires view<_Vp> && view<_Pattern>
3752 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3754 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3757 _Vp _M_base = _Vp();
3758 _Pattern _M_pattern = _Pattern();
3759 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3765 split_view() requires (default_initializable<_Vp>
3766 && default_initializable<_Pattern>)
3770 split_view(_Vp __base, _Pattern __pattern)
3771 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3774 template<forward_range _Range>
3775 requires constructible_from<_Vp, views::all_t<_Range>>
3776 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3778 split_view(_Range&& __r, range_value_t<_Range> __e)
3779 : _M_base(views::all(std::forward<_Range>(__r))),
3780 _M_pattern(views::single(std::move(__e)))
3784 base() const& requires copy_constructible<_Vp>
3789 { return std::move(_M_base); }
3794 if (!_M_cached_begin)
3795 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3796 return {this, ranges::begin(_M_base), *_M_cached_begin};
3802 if constexpr (common_range<_Vp>)
3803 return _Iterator{this, ranges::end(_M_base), {}};
3805 return _Sentinel{this};
3808 constexpr subrange<iterator_t<_Vp>>
3809 _M_find_next(iterator_t<_Vp> __it)
3811 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3812 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3824 split_view* _M_parent = nullptr;
3825 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3826 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3827 bool _M_trailing_empty = false;
3829 friend struct _Sentinel;
3832 using iterator_concept = forward_iterator_tag;
3833 using iterator_category = input_iterator_tag;
3834 using value_type = subrange<iterator_t<_Vp>>;
3835 using difference_type = range_difference_t<_Vp>;
3837 _Iterator() = default;
3840 _Iterator(split_view* __parent,
3841 iterator_t<_Vp> __current,
3842 subrange<iterator_t<_Vp>> __next)
3843 : _M_parent(__parent),
3844 _M_cur(std::move(__current)),
3845 _M_next(std::move(__next))
3848 constexpr iterator_t<_Vp>
3852 constexpr value_type
3854 { return {_M_cur, _M_next.begin()}; }
3856 constexpr _Iterator&
3859 _M_cur = _M_next.begin();
3860 if (_M_cur != ranges::end(_M_parent->_M_base))
3862 _M_cur = _M_next.end();
3863 if (_M_cur == ranges::end(_M_parent->_M_base))
3865 _M_trailing_empty = true;
3866 _M_next = {_M_cur, _M_cur};
3869 _M_next = _M_parent->_M_find_next(_M_cur);
3872 _M_trailing_empty = false;
3884 friend constexpr bool
3885 operator==(const _Iterator& __x, const _Iterator& __y)
3887 return __x._M_cur == __y._M_cur
3888 && __x._M_trailing_empty == __y._M_trailing_empty;
3895 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3898 _M_equal(const _Iterator& __x) const
3899 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3902 _Sentinel() = default;
3905 _Sentinel(split_view* __parent)
3906 : _M_end(ranges::end(__parent->_M_base))
3909 friend constexpr bool
3910 operator==(const _Iterator& __x, const _Sentinel& __y)
3911 { return __y._M_equal(__x); }
3915 template<typename _Range, typename _Pattern>
3916 split_view(_Range&&, _Pattern&&)
3917 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3919 template<forward_range _Range>
3920 split_view(_Range&&, range_value_t<_Range>)
3921 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3927 template<typename _Range, typename _Pattern>
3928 concept __can_split_view
3929 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3930 } // namespace __detail
3932 struct _Split : __adaptor::_RangeAdaptor<_Split>
3934 template<viewable_range _Range, typename _Pattern>
3935 requires __detail::__can_split_view<_Range, _Pattern>
3937 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3939 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3942 using _RangeAdaptor<_Split>::operator();
3943 static constexpr int _S_arity = 2;
3944 template<typename _Pattern>
3945 static constexpr bool _S_has_simple_extra_args
3946 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3949 inline constexpr _Split split;
3950 } // namespace views
3956 template<input_or_output_iterator _Iter>
3958 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3960 if constexpr (contiguous_iterator<_Iter>)
3961 return span(std::to_address(__i), __n);
3962 else if constexpr (random_access_iterator<_Iter>)
3963 return subrange(__i, __i + __n);
3965 return subrange(counted_iterator(std::move(__i), __n),
3970 inline constexpr _Counted counted{};
3971 } // namespace views
3974 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3975 class common_view : public view_interface<common_view<_Vp>>
3978 _Vp _M_base = _Vp();
3981 common_view() requires default_initializable<_Vp> = default;
3984 common_view(_Vp __r)
3985 : _M_base(std::move(__r))
3989 base() const& requires copy_constructible<_Vp>
3994 { return std::move(_M_base); }
3996 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3997 // 4012. common_view::begin/end are missing the simple-view check
3999 begin() requires (!__detail::__simple_view<_Vp>)
4001 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4002 return ranges::begin(_M_base);
4004 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4005 (ranges::begin(_M_base));
4009 begin() const requires range<const _Vp>
4011 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4012 return ranges::begin(_M_base);
4014 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4015 (ranges::begin(_M_base));
4019 end() requires (!__detail::__simple_view<_Vp>)
4021 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4022 return ranges::begin(_M_base) + ranges::size(_M_base);
4024 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4025 (ranges::end(_M_base));
4029 end() const requires range<const _Vp>
4031 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4032 return ranges::begin(_M_base) + ranges::size(_M_base);
4034 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4035 (ranges::end(_M_base));
4039 size() requires sized_range<_Vp>
4040 { return ranges::size(_M_base); }
4043 size() const requires sized_range<const _Vp>
4044 { return ranges::size(_M_base); }
4047 template<typename _Range>
4048 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4050 template<typename _Tp>
4051 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4052 = enable_borrowed_range<_Tp>;
4058 template<typename _Range>
4059 concept __already_common = common_range<_Range>
4060 && requires { views::all(std::declval<_Range>()); };
4062 template<typename _Range>
4063 concept __can_common_view
4064 = requires { common_view{std::declval<_Range>()}; };
4065 } // namespace __detail
4067 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4069 template<viewable_range _Range>
4070 requires __detail::__already_common<_Range>
4071 || __detail::__can_common_view<_Range>
4073 operator() [[nodiscard]] (_Range&& __r) const
4075 if constexpr (__detail::__already_common<_Range>)
4076 return views::all(std::forward<_Range>(__r));
4078 return common_view{std::forward<_Range>(__r)};
4081 static constexpr bool _S_has_simple_call_op = true;
4084 inline constexpr _Common common;
4085 } // namespace views
4088 requires bidirectional_range<_Vp>
4089 class reverse_view : public view_interface<reverse_view<_Vp>>
4092 static constexpr bool _S_needs_cached_begin
4093 = !common_range<_Vp> && !(random_access_range<_Vp>
4094 && sized_sentinel_for<sentinel_t<_Vp>,
4097 _Vp _M_base = _Vp();
4098 [[no_unique_address]]
4099 __detail::__maybe_present_t<_S_needs_cached_begin,
4100 __detail::_CachedPosition<_Vp>>
4104 reverse_view() requires default_initializable<_Vp> = default;
4107 reverse_view(_Vp __r)
4108 : _M_base(std::move(__r))
4112 base() const& requires copy_constructible<_Vp>
4117 { return std::move(_M_base); }
4119 constexpr reverse_iterator<iterator_t<_Vp>>
4122 if constexpr (_S_needs_cached_begin)
4123 if (_M_cached_begin._M_has_value())
4124 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
4126 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4127 if constexpr (_S_needs_cached_begin)
4128 _M_cached_begin._M_set(_M_base, __it);
4129 return std::make_reverse_iterator(std::move(__it));
4133 begin() requires common_range<_Vp>
4134 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4137 begin() const requires common_range<const _Vp>
4138 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4140 constexpr reverse_iterator<iterator_t<_Vp>>
4142 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4145 end() const requires common_range<const _Vp>
4146 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4149 size() requires sized_range<_Vp>
4150 { return ranges::size(_M_base); }
4153 size() const requires sized_range<const _Vp>
4154 { return ranges::size(_M_base); }
4157 template<typename _Range>
4158 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4160 template<typename _Tp>
4161 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4162 = enable_borrowed_range<_Tp>;
4169 inline constexpr bool __is_reversible_subrange = false;
4171 template<typename _Iter, subrange_kind _Kind>
4172 inline constexpr bool
4173 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4174 reverse_iterator<_Iter>,
4178 inline constexpr bool __is_reverse_view = false;
4180 template<typename _Vp>
4181 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
4183 template<typename _Range>
4184 concept __can_reverse_view
4185 = requires { reverse_view{std::declval<_Range>()}; };
4186 } // namespace __detail
4188 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4190 template<viewable_range _Range>
4191 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4192 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4193 || __detail::__can_reverse_view<_Range>
4195 operator() [[nodiscard]] (_Range&& __r) const
4197 using _Tp = remove_cvref_t<_Range>;
4198 if constexpr (__detail::__is_reverse_view<_Tp>)
4199 return std::forward<_Range>(__r).base();
4200 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4202 using _Iter = decltype(ranges::begin(__r).base());
4203 if constexpr (sized_range<_Tp>)
4204 return subrange<_Iter, _Iter, subrange_kind::sized>
4205 {__r.end().base(), __r.begin().base(), __r.size()};
4207 return subrange<_Iter, _Iter, subrange_kind::unsized>
4208 {__r.end().base(), __r.begin().base()};
4211 return reverse_view{std::forward<_Range>(__r)};
4214 static constexpr bool _S_has_simple_call_op = true;
4217 inline constexpr _Reverse reverse;
4218 } // namespace views
4222#if __cpp_lib_tuple_like // >= C++23
4223 template<typename _Tp, size_t _Nm>
4224 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4226 template<typename _Tp, size_t _Nm>
4227 concept __has_tuple_element = requires(_Tp __t)
4229 typename tuple_size<_Tp>::type;
4230 requires _Nm < tuple_size_v<_Tp>;
4231 typename tuple_element_t<_Nm, _Tp>;
4232 { std::get<_Nm>(__t) }
4233 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4237 template<typename _Tp, size_t _Nm>
4238 concept __returnable_element
4239 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4242 template<input_range _Vp, size_t _Nm>
4244 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4245 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4247 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4248 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4251 elements_view() requires default_initializable<_Vp> = default;
4254 elements_view(_Vp __base)
4255 : _M_base(std::move(__base))
4259 base() const& requires copy_constructible<_Vp>
4264 { return std::move(_M_base); }
4267 begin() requires (!__detail::__simple_view<_Vp>)
4268 { return _Iterator<false>(ranges::begin(_M_base)); }
4271 begin() const requires range<const _Vp>
4272 { return _Iterator<true>(ranges::begin(_M_base)); }
4275 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4276 { return _Sentinel<false>{ranges::end(_M_base)}; }
4279 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4280 { return _Iterator<false>{ranges::end(_M_base)}; }
4283 end() const requires range<const _Vp>
4284 { return _Sentinel<true>{ranges::end(_M_base)}; }
4287 end() const requires common_range<const _Vp>
4288 { return _Iterator<true>{ranges::end(_M_base)}; }
4291 size() requires sized_range<_Vp>
4292 { return ranges::size(_M_base); }
4295 size() const requires sized_range<const _Vp>
4296 { return ranges::size(_M_base); }
4299 template<bool _Const>
4300 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4302 template<bool _Const>
4306 template<bool _Const>
4307 requires forward_range<_Base<_Const>>
4308 struct __iter_cat<_Const>
4311 static auto _S_iter_cat()
4313 using _Base = elements_view::_Base<_Const>;
4314 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4315 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4316 if constexpr (!is_lvalue_reference_v<_Res>)
4317 return input_iterator_tag{};
4318 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4319 return random_access_iterator_tag{};
4324 using iterator_category = decltype(_S_iter_cat());
4327 template<bool _Const>
4330 template<bool _Const>
4331 struct _Iterator : __iter_cat<_Const>
4334 using _Base = elements_view::_Base<_Const>;
4336 iterator_t<_Base> _M_current = iterator_t<_Base>();
4338 static constexpr decltype(auto)
4339 _S_get_element(const iterator_t<_Base>& __i)
4341 if constexpr (is_reference_v<range_reference_t<_Base>>)
4342 return std::get<_Nm>(*__i);
4345 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4346 return static_cast<_Et>(std::get<_Nm>(*__i));
4353 if constexpr (random_access_range<_Base>)
4354 return random_access_iterator_tag{};
4355 else if constexpr (bidirectional_range<_Base>)
4356 return bidirectional_iterator_tag{};
4357 else if constexpr (forward_range<_Base>)
4358 return forward_iterator_tag{};
4360 return input_iterator_tag{};
4363 friend _Iterator<!_Const>;
4366 using iterator_concept = decltype(_S_iter_concept());
4367 // iterator_category defined in elements_view::__iter_cat
4369 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4370 using difference_type = range_difference_t<_Base>;
4372 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4375 _Iterator(iterator_t<_Base> __current)
4376 : _M_current(std::move(__current))
4380 _Iterator(_Iterator<!_Const> __i)
4381 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4382 : _M_current(std::move(__i._M_current))
4385 constexpr const iterator_t<_Base>&
4386 base() const& noexcept
4387 { return _M_current; }
4389 constexpr iterator_t<_Base>
4391 { return std::move(_M_current); }
4393 constexpr decltype(auto)
4395 { return _S_get_element(_M_current); }
4397 constexpr _Iterator&
4409 operator++(int) requires forward_range<_Base>
4416 constexpr _Iterator&
4417 operator--() requires bidirectional_range<_Base>
4424 operator--(int) requires bidirectional_range<_Base>
4431 constexpr _Iterator&
4432 operator+=(difference_type __n)
4433 requires random_access_range<_Base>
4439 constexpr _Iterator&
4440 operator-=(difference_type __n)
4441 requires random_access_range<_Base>
4447 constexpr decltype(auto)
4448 operator[](difference_type __n) const
4449 requires random_access_range<_Base>
4450 { return _S_get_element(_M_current + __n); }
4452 friend constexpr bool
4453 operator==(const _Iterator& __x, const _Iterator& __y)
4454 requires equality_comparable<iterator_t<_Base>>
4455 { return __x._M_current == __y._M_current; }
4457 friend constexpr bool
4458 operator<(const _Iterator& __x, const _Iterator& __y)
4459 requires random_access_range<_Base>
4460 { return __x._M_current < __y._M_current; }
4462 friend constexpr bool
4463 operator>(const _Iterator& __x, const _Iterator& __y)
4464 requires random_access_range<_Base>
4465 { return __y._M_current < __x._M_current; }
4467 friend constexpr bool
4468 operator<=(const _Iterator& __x, const _Iterator& __y)
4469 requires random_access_range<_Base>
4470 { return !(__y._M_current > __x._M_current); }
4472 friend constexpr bool
4473 operator>=(const _Iterator& __x, const _Iterator& __y)
4474 requires random_access_range<_Base>
4475 { return !(__x._M_current > __y._M_current); }
4477#ifdef __cpp_lib_three_way_comparison
4478 friend constexpr auto
4479 operator<=>(const _Iterator& __x, const _Iterator& __y)
4480 requires random_access_range<_Base>
4481 && three_way_comparable<iterator_t<_Base>>
4482 { return __x._M_current <=> __y._M_current; }
4485 friend constexpr _Iterator
4486 operator+(const _Iterator& __x, difference_type __y)
4487 requires random_access_range<_Base>
4488 { return _Iterator{__x} += __y; }
4490 friend constexpr _Iterator
4491 operator+(difference_type __x, const _Iterator& __y)
4492 requires random_access_range<_Base>
4493 { return __y + __x; }
4495 friend constexpr _Iterator
4496 operator-(const _Iterator& __x, difference_type __y)
4497 requires random_access_range<_Base>
4498 { return _Iterator{__x} -= __y; }
4500 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4501 // 3483. transform_view::iterator's difference is overconstrained
4502 friend constexpr difference_type
4503 operator-(const _Iterator& __x, const _Iterator& __y)
4504 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4505 { return __x._M_current - __y._M_current; }
4507 template <bool> friend struct _Sentinel;
4510 template<bool _Const>
4514 template<bool _Const2>
4516 _M_equal(const _Iterator<_Const2>& __x) const
4517 { return __x._M_current == _M_end; }
4519 template<bool _Const2>
4521 _M_distance_from(const _Iterator<_Const2>& __i) const
4522 { return _M_end - __i._M_current; }
4524 using _Base = elements_view::_Base<_Const>;
4525 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4528 _Sentinel() = default;
4531 _Sentinel(sentinel_t<_Base> __end)
4532 : _M_end(std::move(__end))
4536 _Sentinel(_Sentinel<!_Const> __other)
4538 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4539 : _M_end(std::move(__other._M_end))
4542 constexpr sentinel_t<_Base>
4546 template<bool _Const2>
4547 requires sentinel_for<sentinel_t<_Base>,
4548 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4549 friend constexpr bool
4550 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4551 { return __y._M_equal(__x); }
4553 template<bool _Const2,
4554 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4555 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4556 friend constexpr range_difference_t<_Base2>
4557 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4558 { return -__y._M_distance_from(__x); }
4560 template<bool _Const2,
4561 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4562 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4563 friend constexpr range_difference_t<_Base2>
4564 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4565 { return __x._M_distance_from(__y); }
4567 friend _Sentinel<!_Const>;
4570 _Vp _M_base = _Vp();
4573 template<typename _Tp, size_t _Nm>
4574 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4575 = enable_borrowed_range<_Tp>;
4577 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4578 // 3563. keys_view example is broken
4579 template<typename _Range>
4580 using keys_view = elements_view<_Range, 0>;
4582 template<typename _Range>
4583 using values_view = elements_view<_Range, 1>;
4589 template<size_t _Nm, typename _Range>
4590 concept __can_elements_view
4591 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4592 } // namespace __detail
4594 template<size_t _Nm>
4595 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4597 template<viewable_range _Range>
4598 requires __detail::__can_elements_view<_Nm, _Range>
4600 operator() [[nodiscard]] (_Range&& __r) const
4602 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4605 static constexpr bool _S_has_simple_call_op = true;
4608 template<size_t _Nm>
4609 inline constexpr _Elements<_Nm> elements;
4610 inline constexpr auto keys = elements<0>;
4611 inline constexpr auto values = elements<1>;
4612 } // namespace views
4614#ifdef __cpp_lib_ranges_zip // C++ >= 23
4617 template<typename... _Rs>
4618 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4619 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4620 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4622 template<typename _Fp, typename _Tuple>
4624 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4626 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4627 return tuple<invoke_result_t<_Fp&, _Ts>...>
4628 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4629 }, std::forward<_Tuple>(__tuple));
4632 template<typename _Fp, typename _Tuple>
4634 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4636 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4637 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4638 }, std::forward<_Tuple>(__tuple));
4640 } // namespace __detail
4642 template<input_range... _Vs>
4643 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4644 class zip_view : public view_interface<zip_view<_Vs...>>
4646 tuple<_Vs...> _M_views;
4648 template<bool> class _Iterator;
4649 template<bool> class _Sentinel;
4652 zip_view() = default;
4655 zip_view(_Vs... __views)
4656 : _M_views(std::move(__views)...)
4660 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4661 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4664 begin() const requires (range<const _Vs> && ...)
4665 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4668 end() requires (!(__detail::__simple_view<_Vs> && ...))
4670 if constexpr (!__detail::__zip_is_common<_Vs...>)
4671 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4672 else if constexpr ((random_access_range<_Vs> && ...))
4673 return begin() + iter_difference_t<_Iterator<false>>(size());
4675 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4679 end() const requires (range<const _Vs> && ...)
4681 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4682 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4683 else if constexpr ((random_access_range<const _Vs> && ...))
4684 return begin() + iter_difference_t<_Iterator<true>>(size());
4686 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4690 size() requires (sized_range<_Vs> && ...)
4692 return std::apply([](auto... sizes) {
4693 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4694 return ranges::min({_CT(sizes)...});
4695 }, __detail::__tuple_transform(ranges::size, _M_views));
4699 size() const requires (sized_range<const _Vs> && ...)
4701 return std::apply([](auto... sizes) {
4702 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4703 return ranges::min({_CT(sizes)...});
4704 }, __detail::__tuple_transform(ranges::size, _M_views));
4708 template<typename... _Rs>
4709 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4711 template<typename... _Views>
4712 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4713 = (enable_borrowed_range<_Views> && ...);
4717 template<bool _Const, typename... _Vs>
4718 concept __all_random_access
4719 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4721 template<bool _Const, typename... _Vs>
4722 concept __all_bidirectional
4723 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4725 template<bool _Const, typename... _Vs>
4726 concept __all_forward
4727 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4729 template<bool _Const, typename... _Views>
4730 struct __zip_view_iter_cat
4733 template<bool _Const, typename... _Views>
4734 requires __all_forward<_Const, _Views...>
4735 struct __zip_view_iter_cat<_Const, _Views...>
4736 { using iterator_category = input_iterator_tag; };
4737 } // namespace __detail
4739 template<input_range... _Vs>
4740 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4741 template<bool _Const>
4742 class zip_view<_Vs...>::_Iterator
4743 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4745#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
4748 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4751 _Iterator(decltype(_M_current) __current)
4752 : _M_current(std::move(__current))
4758 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4759 return random_access_iterator_tag{};
4760 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4761 return bidirectional_iterator_tag{};
4762 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4763 return forward_iterator_tag{};
4765 return input_iterator_tag{};
4768#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
4769 template<move_constructible _Fp, input_range... _Ws>
4770 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4771 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4772 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4773 friend class zip_transform_view;
4777 // iterator_category defined in __zip_view_iter_cat
4778 using iterator_concept = decltype(_S_iter_concept());
4780 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4781 using difference_type
4782 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4784 _Iterator() = default;
4787 _Iterator(_Iterator<!_Const> __i)
4789 && (convertible_to<iterator_t<_Vs>,
4790 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4791 : _M_current(std::move(__i._M_current))
4797 auto __f = [](auto& __i) -> decltype(auto) {
4800 return __detail::__tuple_transform(__f, _M_current);
4803 constexpr _Iterator&
4806 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4816 requires __detail::__all_forward<_Const, _Vs...>
4823 constexpr _Iterator&
4825 requires __detail::__all_bidirectional<_Const, _Vs...>
4827 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4833 requires __detail::__all_bidirectional<_Const, _Vs...>
4840 constexpr _Iterator&
4841 operator+=(difference_type __x)
4842 requires __detail::__all_random_access<_Const, _Vs...>
4844 auto __f = [&]<typename _It>(_It& __i) {
4845 __i += iter_difference_t<_It>(__x);
4847 __detail::__tuple_for_each(__f, _M_current);
4851 constexpr _Iterator&
4852 operator-=(difference_type __x)
4853 requires __detail::__all_random_access<_Const, _Vs...>
4855 auto __f = [&]<typename _It>(_It& __i) {
4856 __i -= iter_difference_t<_It>(__x);
4858 __detail::__tuple_for_each(__f, _M_current);
4863 operator[](difference_type __n) const
4864 requires __detail::__all_random_access<_Const, _Vs...>
4866 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4867 return __i[iter_difference_t<_It>(__n)];
4869 return __detail::__tuple_transform(__f, _M_current);
4872 friend constexpr bool
4873 operator==(const _Iterator& __x, const _Iterator& __y)
4874 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4876 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4877 return __x._M_current == __y._M_current;
4879 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4880 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4881 }(make_index_sequence<sizeof...(_Vs)>{});
4884 friend constexpr auto
4885 operator<=>(const _Iterator& __x, const _Iterator& __y)
4886 requires __detail::__all_random_access<_Const, _Vs...>
4887 { return __x._M_current <=> __y._M_current; }
4889 friend constexpr _Iterator
4890 operator+(const _Iterator& __i, difference_type __n)
4891 requires __detail::__all_random_access<_Const, _Vs...>
4898 friend constexpr _Iterator
4899 operator+(difference_type __n, const _Iterator& __i)
4900 requires __detail::__all_random_access<_Const, _Vs...>
4907 friend constexpr _Iterator
4908 operator-(const _Iterator& __i, difference_type __n)
4909 requires __detail::__all_random_access<_Const, _Vs...>
4916 friend constexpr difference_type
4917 operator-(const _Iterator& __x, const _Iterator& __y)
4918 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4919 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4921 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4922 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4923 - std::get<_Is>(__y._M_current))...},
4925 [](difference_type __i) {
4926 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4928 }(make_index_sequence<sizeof...(_Vs)>{});
4931 friend constexpr auto
4932 iter_move(const _Iterator& __i)
4933 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4935 friend constexpr void
4936 iter_swap(const _Iterator& __l, const _Iterator& __r)
4937 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4939 [&]<size_t... _Is>(index_sequence<_Is...>) {
4940 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4941 }(make_index_sequence<sizeof...(_Vs)>{});
4944 friend class zip_view;
4947 template<input_range... _Vs>
4948 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4949 template<bool _Const>
4950 class zip_view<_Vs...>::_Sentinel
4952 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4955 _Sentinel(decltype(_M_end) __end)
4959 friend class zip_view;
4962 _Sentinel() = default;
4965 _Sentinel(_Sentinel<!_Const> __i)
4967 && (convertible_to<sentinel_t<_Vs>,
4968 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4969 : _M_end(std::move(__i._M_end))
4972 template<bool _OtherConst>
4973 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4974 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4975 friend constexpr bool
4976 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4978 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4979 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4980 }(make_index_sequence<sizeof...(_Vs)>{});
4983 template<bool _OtherConst>
4984 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4985 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4986 friend constexpr auto
4987 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4990 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4991 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4992 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4995 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4997 }(make_index_sequence<sizeof...(_Vs)>{});
5000 template<bool _OtherConst>
5001 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5002 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5003 friend constexpr auto
5004 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5005 { return -(__x - __y); }
5012 template<typename... _Ts>
5013 concept __can_zip_view
5014 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
5019 template<typename... _Ts>
5020 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5022 operator() [[nodiscard]] (_Ts&&... __ts) const
5024 if constexpr (sizeof...(_Ts) == 0)
5025 return views::empty<tuple<>>;
5027 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
5031 inline constexpr _Zip zip;
5036 template<typename _Range, bool _Const>
5037 using __range_iter_cat
5038 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5041 template<move_constructible _Fp, input_range... _Vs>
5042 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5043 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5044 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5045 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
5047 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5048 zip_view<_Vs...> _M_zip;
5050 using _InnerView = zip_view<_Vs...>;
5052 template<bool _Const>
5053 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5055 template<bool _Const>
5056 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5058 template<bool _Const>
5059 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5061 template<bool _Const>
5065 template<bool _Const>
5066 requires forward_range<_Base<_Const>>
5067 struct __iter_cat<_Const>
5073 using __detail::__maybe_const_t;
5074 using __detail::__range_iter_cat;
5075 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5076 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5077 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5078 // 3798. Rvalue reference and iterator_category
5079 if constexpr (!is_reference_v<_Res>)
5080 return input_iterator_tag{};
5081 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5082 random_access_iterator_tag> && ...))
5083 return random_access_iterator_tag{};
5084 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5085 bidirectional_iterator_tag> && ...))
5086 return bidirectional_iterator_tag{};
5087 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5088 forward_iterator_tag> && ...))
5089 return forward_iterator_tag{};
5091 return input_iterator_tag{};
5094 using iterator_category = decltype(_S_iter_cat());
5097 template<bool> class _Iterator;
5098 template<bool> class _Sentinel;
5101 zip_transform_view() = default;
5104 zip_transform_view(_Fp __fun, _Vs... __views)
5105 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5110 { return _Iterator<false>(*this, _M_zip.begin()); }
5114 requires range<const _InnerView>
5115 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5116 { return _Iterator<true>(*this, _M_zip.begin()); }
5121 if constexpr (common_range<_InnerView>)
5122 return _Iterator<false>(*this, _M_zip.end());
5124 return _Sentinel<false>(_M_zip.end());
5129 requires range<const _InnerView>
5130 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5132 if constexpr (common_range<const _InnerView>)
5133 return _Iterator<true>(*this, _M_zip.end());
5135 return _Sentinel<true>(_M_zip.end());
5139 size() requires sized_range<_InnerView>
5140 { return _M_zip.size(); }
5143 size() const requires sized_range<const _InnerView>
5144 { return _M_zip.size(); }
5147 template<class _Fp, class... Rs>
5148 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5150 template<move_constructible _Fp, input_range... _Vs>
5151 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5152 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5153 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5154 template<bool _Const>
5155 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5157 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5159 _Parent* _M_parent = nullptr;
5160 __ziperator<_Const> _M_inner;
5163 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5164 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5167 friend class zip_transform_view;
5170 // iterator_category defined in zip_transform_view::__iter_cat
5171 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
5173 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5174 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5175 using difference_type = range_difference_t<_Base<_Const>>;
5177 _Iterator() = default;
5180 _Iterator(_Iterator<!_Const> __i)
5181 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5182 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5185 constexpr decltype(auto)
5188 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5189 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5190 }, _M_inner._M_current);
5193 constexpr _Iterator&
5205 operator++(int) requires forward_range<_Base<_Const>>
5212 constexpr _Iterator&
5213 operator--() requires bidirectional_range<_Base<_Const>>
5220 operator--(int) requires bidirectional_range<_Base<_Const>>
5227 constexpr _Iterator&
5228 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5234 constexpr _Iterator&
5235 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5241 constexpr decltype(auto)
5242 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5244 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5245 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5246 }, _M_inner._M_current);
5249 friend constexpr bool
5250 operator==(const _Iterator& __x, const _Iterator& __y)
5251 requires equality_comparable<__ziperator<_Const>>
5252 { return __x._M_inner == __y._M_inner; }
5254 friend constexpr auto
5255 operator<=>(const _Iterator& __x, const _Iterator& __y)
5256 requires random_access_range<_Base<_Const>>
5257 { return __x._M_inner <=> __y._M_inner; }
5259 friend constexpr _Iterator
5260 operator+(const _Iterator& __i, difference_type __n)
5261 requires random_access_range<_Base<_Const>>
5262 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5264 friend constexpr _Iterator
5265 operator+(difference_type __n, const _Iterator& __i)
5266 requires random_access_range<_Base<_Const>>
5267 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5269 friend constexpr _Iterator
5270 operator-(const _Iterator& __i, difference_type __n)
5271 requires random_access_range<_Base<_Const>>
5272 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5274 friend constexpr difference_type
5275 operator-(const _Iterator& __x, const _Iterator& __y)
5276 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5277 { return __x._M_inner - __y._M_inner; }
5280 template<move_constructible _Fp, input_range... _Vs>
5281 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5282 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5283 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5284 template<bool _Const>
5285 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5287 __zentinel<_Const> _M_inner;
5290 _Sentinel(__zentinel<_Const> __inner)
5294 friend class zip_transform_view;
5297 _Sentinel() = default;
5300 _Sentinel(_Sentinel<!_Const> __i)
5301 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5302 : _M_inner(std::move(__i._M_inner))
5305 template<bool _OtherConst>
5306 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5307 friend constexpr bool
5308 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5309 { return __x._M_inner == __y._M_inner; }
5311 template<bool _OtherConst>
5312 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5313 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5314 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5315 { return __x._M_inner - __y._M_inner; }
5317 template<bool _OtherConst>
5318 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5319 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5320 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5321 { return __x._M_inner - __y._M_inner; }
5328 template<typename _Fp, typename... _Ts>
5329 concept __can_zip_transform_view
5330 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5333 struct _ZipTransform
5335 template<typename _Fp>
5336 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
5337 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
5339 operator() [[nodiscard]] (_Fp&&) const
5341 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5344 template<typename _Fp, typename... _Ts>
5345 requires (sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
5347 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5349 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5353 inline constexpr _ZipTransform zip_transform;
5356 template<forward_range _Vp, size_t _Nm>
5357 requires view<_Vp> && (_Nm > 0)
5358 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5360 _Vp _M_base = _Vp();
5362 template<bool> class _Iterator;
5363 template<bool> class _Sentinel;
5365 struct __as_sentinel
5369 adjacent_view() requires default_initializable<_Vp> = default;
5372 adjacent_view(_Vp __base)
5373 : _M_base(std::move(__base))
5376 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5377 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5379 base() const & requires copy_constructible<_Vp>
5384 { return std::move(_M_base); }
5387 begin() requires (!__detail::__simple_view<_Vp>)
5388 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5391 begin() const requires range<const _Vp>
5392 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5395 end() requires (!__detail::__simple_view<_Vp>)
5397 if constexpr (common_range<_Vp>)
5398 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5400 return _Sentinel<false>(ranges::end(_M_base));
5404 end() const requires range<const _Vp>
5406 if constexpr (common_range<const _Vp>)
5407 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5409 return _Sentinel<true>(ranges::end(_M_base));
5413 size() requires sized_range<_Vp>
5415 using _ST = decltype(ranges::size(_M_base));
5416 using _CT = common_type_t<_ST, size_t>;
5417 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5418 __sz -= std::min<_CT>(__sz, _Nm - 1);
5419 return static_cast<_ST>(__sz);
5423 size() const requires sized_range<const _Vp>
5425 using _ST = decltype(ranges::size(_M_base));
5426 using _CT = common_type_t<_ST, size_t>;
5427 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5428 __sz -= std::min<_CT>(__sz, _Nm - 1);
5429 return static_cast<_ST>(__sz);
5433 template<typename _Vp, size_t _Nm>
5434 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5435 = enable_borrowed_range<_Vp>;
5439 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5440 template<typename _Tp, size_t _Nm>
5441 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5443 // For a functor F that is callable with N arguments, the expression
5444 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5445 template<typename _Fp, size_t _Nm>
5448 template<typename... _Ts>
5449 static invoke_result_t<_Fp, _Ts...>
5450 __tuple_apply(const tuple<_Ts...>&); // not defined
5452 template<typename _Tp>
5453 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5454 operator()(_Tp&&); // not defined
5458 template<forward_range _Vp, size_t _Nm>
5459 requires view<_Vp> && (_Nm > 0)
5460 template<bool _Const>
5461 class adjacent_view<_Vp, _Nm>::_Iterator
5463#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
5466 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5467 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5470 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5472 for (auto& __i : _M_current)
5475 ranges::advance(__first, 1, __last);
5480 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5482 if constexpr (!bidirectional_range<_Base>)
5483 for (auto& __it : _M_current)
5486 for (size_t __i = 0; __i < _Nm; ++__i)
5488 _M_current[_Nm - 1 - __i] = __last;
5489 ranges::advance(__last, -1, __first);
5496 if constexpr (random_access_range<_Base>)
5497 return random_access_iterator_tag{};
5498 else if constexpr (bidirectional_range<_Base>)
5499 return bidirectional_iterator_tag{};
5501 return forward_iterator_tag{};
5504 friend class adjacent_view;
5506#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
5507 template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
5508 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5509 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5510 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5511 range_reference_t<_Wp>>>
5512 friend class adjacent_transform_view;
5516 using iterator_category = input_iterator_tag;
5517 using iterator_concept = decltype(_S_iter_concept());
5518 using value_type = conditional_t<_Nm == 2,
5519 pair<range_value_t<_Base>, range_value_t<_Base>>,
5520 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5521 using difference_type = range_difference_t<_Base>;
5523 _Iterator() = default;
5526 _Iterator(_Iterator<!_Const> __i)
5527 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5529 for (size_t __j = 0; __j < _Nm; ++__j)
5530 _M_current[__j] = std::move(__i._M_current[__j]);
5536 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5537 return __detail::__tuple_transform(__f, _M_current);
5540 constexpr _Iterator&
5543 for (auto& __i : _M_current)
5556 constexpr _Iterator&
5557 operator--() requires bidirectional_range<_Base>
5559 for (auto& __i : _M_current)
5565 operator--(int) requires bidirectional_range<_Base>
5572 constexpr _Iterator&
5573 operator+=(difference_type __x)
5574 requires random_access_range<_Base>
5576 for (auto& __i : _M_current)
5581 constexpr _Iterator&
5582 operator-=(difference_type __x)
5583 requires random_access_range<_Base>
5585 for (auto& __i : _M_current)
5591 operator[](difference_type __n) const
5592 requires random_access_range<_Base>
5594 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5595 return __detail::__tuple_transform(__f, _M_current);
5598 friend constexpr bool
5599 operator==(const _Iterator& __x, const _Iterator& __y)
5600 { return __x._M_current.back() == __y._M_current.back(); }
5602 friend constexpr bool
5603 operator<(const _Iterator& __x, const _Iterator& __y)
5604 requires random_access_range<_Base>
5605 { return __x._M_current.back() < __y._M_current.back(); }
5607 friend constexpr bool
5608 operator>(const _Iterator& __x, const _Iterator& __y)
5609 requires random_access_range<_Base>
5610 { return __y < __x; }
5612 friend constexpr bool
5613 operator<=(const _Iterator& __x, const _Iterator& __y)
5614 requires random_access_range<_Base>
5615 { return !(__y < __x); }
5617 friend constexpr bool
5618 operator>=(const _Iterator& __x, const _Iterator& __y)
5619 requires random_access_range<_Base>
5620 { return !(__x < __y); }
5622 friend constexpr auto
5623 operator<=>(const _Iterator& __x, const _Iterator& __y)
5624 requires random_access_range<_Base>
5625 && three_way_comparable<iterator_t<_Base>>
5626 { return __x._M_current.back() <=> __y._M_current.back(); }
5628 friend constexpr _Iterator
5629 operator+(const _Iterator& __i, difference_type __n)
5630 requires random_access_range<_Base>
5637 friend constexpr _Iterator
5638 operator+(difference_type __n, const _Iterator& __i)
5639 requires random_access_range<_Base>
5646 friend constexpr _Iterator
5647 operator-(const _Iterator& __i, difference_type __n)
5648 requires random_access_range<_Base>
5655 friend constexpr difference_type
5656 operator-(const _Iterator& __x, const _Iterator& __y)
5657 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5658 { return __x._M_current.back() - __y._M_current.back(); }
5660 friend constexpr auto
5661 iter_move(const _Iterator& __i)
5662 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5664 friend constexpr void
5665 iter_swap(const _Iterator& __l, const _Iterator& __r)
5666 requires indirectly_swappable<iterator_t<_Base>>
5668 for (size_t __i = 0; __i < _Nm; __i++)
5669 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5673 template<forward_range _Vp, size_t _Nm>
5674 requires view<_Vp> && (_Nm > 0)
5675 template<bool _Const>
5676 class adjacent_view<_Vp, _Nm>::_Sentinel
5678 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5680 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5683 _Sentinel(sentinel_t<_Base> __end)
5687 friend class adjacent_view;
5690 _Sentinel() = default;
5693 _Sentinel(_Sentinel<!_Const> __i)
5694 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5695 : _M_end(std::move(__i._M_end))
5698 template<bool _OtherConst>
5699 requires sentinel_for<sentinel_t<_Base>,
5700 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5701 friend constexpr bool
5702 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5703 { return __x._M_current.back() == __y._M_end; }
5705 template<bool _OtherConst>
5706 requires sized_sentinel_for<sentinel_t<_Base>,
5707 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5708 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5709 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5710 { return __x._M_current.back() - __y._M_end; }
5712 template<bool _OtherConst>
5713 requires sized_sentinel_for<sentinel_t<_Base>,
5714 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5715 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5716 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5717 { return __y._M_end - __x._M_current.back(); }
5724 template<size_t _Nm, typename _Range>
5725 concept __can_adjacent_view
5726 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5729 template<size_t _Nm>
5730 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5732 template<viewable_range _Range>
5733 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5735 operator() [[nodiscard]] (_Range&& __r) const
5737 if constexpr (_Nm == 0)
5738 return views::empty<tuple<>>;
5740 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5744 template<size_t _Nm>
5745 inline constexpr _Adjacent<_Nm> adjacent;
5747 inline constexpr auto pairwise = adjacent<2>;
5750 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5751 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5752 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5753 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5754 range_reference_t<_Vp>>>
5755 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5757 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5758 adjacent_view<_Vp, _Nm> _M_inner;
5760 using _InnerView = adjacent_view<_Vp, _Nm>;
5762 template<bool _Const>
5763 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5765 template<bool _Const>
5766 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5768 template<bool> class _Iterator;
5769 template<bool> class _Sentinel;
5772 adjacent_transform_view() = default;
5775 adjacent_transform_view(_Vp __base, _Fp __fun)
5776 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5779 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5780 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5781 // 3947. Unexpected constraints on adjacent_transform_view::base()
5783 base() const & requires copy_constructible<_Vp>
5784 { return _M_inner.base(); }
5788 { return std::move(_M_inner.base()); }
5792 { return _Iterator<false>(*this, _M_inner.begin()); }
5796 requires range<const _InnerView>
5797 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5798 range_reference_t<const _Vp>>
5799 { return _Iterator<true>(*this, _M_inner.begin()); }
5804 if constexpr (common_range<_InnerView>)
5805 return _Iterator<false>(*this, _M_inner.end());
5807 return _Sentinel<false>(_M_inner.end());
5812 requires range<const _InnerView>
5813 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5814 range_reference_t<const _Vp>>
5816 if constexpr (common_range<const _InnerView>)
5817 return _Iterator<true>(*this, _M_inner.end());
5819 return _Sentinel<true>(_M_inner.end());
5823 size() requires sized_range<_InnerView>
5824 { return _M_inner.size(); }
5827 size() const requires sized_range<const _InnerView>
5828 { return _M_inner.size(); }
5831 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5832 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5833 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5834 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5835 range_reference_t<_Vp>>>
5836 template<bool _Const>
5837 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5839 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5840 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5842 _Parent* _M_parent = nullptr;
5843 _InnerIter<_Const> _M_inner;
5846 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5847 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5853 using __detail::__maybe_const_t;
5854 using __detail::__unarize;
5855 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5856 range_reference_t<_Base>>;
5857 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5858 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5859 // 3798. Rvalue reference and iterator_category
5860 if constexpr (!is_reference_v<_Res>)
5861 return input_iterator_tag{};
5862 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5863 return random_access_iterator_tag{};
5864 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5865 return bidirectional_iterator_tag{};
5866 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5867 return forward_iterator_tag{};
5869 return input_iterator_tag{};
5872 friend class adjacent_transform_view;
5875 using iterator_category = decltype(_S_iter_cat());
5876 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5878 = remove_cvref_t<invoke_result_t
5879 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5880 range_reference_t<_Base>>>;
5881 using difference_type = range_difference_t<_Base>;
5883 _Iterator() = default;
5886 _Iterator(_Iterator<!_Const> __i)
5887 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5888 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5891 constexpr decltype(auto)
5894 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5895 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5896 }, _M_inner._M_current);
5899 constexpr _Iterator&
5914 constexpr _Iterator&
5915 operator--() requires bidirectional_range<_Base>
5922 operator--(int) requires bidirectional_range<_Base>
5929 constexpr _Iterator&
5930 operator+=(difference_type __x) requires random_access_range<_Base>
5936 constexpr _Iterator&
5937 operator-=(difference_type __x) requires random_access_range<_Base>
5943 constexpr decltype(auto)
5944 operator[](difference_type __n) const requires random_access_range<_Base>
5946 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5947 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5948 }, _M_inner._M_current);
5951 friend constexpr bool
5952 operator==(const _Iterator& __x, const _Iterator& __y)
5953 { return __x._M_inner == __y._M_inner; }
5955 friend constexpr bool
5956 operator<(const _Iterator& __x, const _Iterator& __y)
5957 requires random_access_range<_Base>
5958 { return __x._M_inner < __y._M_inner; }
5960 friend constexpr bool
5961 operator>(const _Iterator& __x, const _Iterator& __y)
5962 requires random_access_range<_Base>
5963 { return __x._M_inner > __y._M_inner; }
5965 friend constexpr bool
5966 operator<=(const _Iterator& __x, const _Iterator& __y)
5967 requires random_access_range<_Base>
5968 { return __x._M_inner <= __y._M_inner; }
5970 friend constexpr bool
5971 operator>=(const _Iterator& __x, const _Iterator& __y)
5972 requires random_access_range<_Base>
5973 { return __x._M_inner >= __y._M_inner; }
5975 friend constexpr auto
5976 operator<=>(const _Iterator& __x, const _Iterator& __y)
5977 requires random_access_range<_Base> &&
5978 three_way_comparable<_InnerIter<_Const>>
5979 { return __x._M_inner <=> __y._M_inner; }
5981 friend constexpr _Iterator
5982 operator+(const _Iterator& __i, difference_type __n)
5983 requires random_access_range<_Base>
5984 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5986 friend constexpr _Iterator
5987 operator+(difference_type __n, const _Iterator& __i)
5988 requires random_access_range<_Base>
5989 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5991 friend constexpr _Iterator
5992 operator-(const _Iterator& __i, difference_type __n)
5993 requires random_access_range<_Base>
5994 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5996 friend constexpr difference_type
5997 operator-(const _Iterator& __x, const _Iterator& __y)
5998 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5999 { return __x._M_inner - __y._M_inner; }
6002 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
6003 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
6004 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
6005 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6006 range_reference_t<_Vp>>>
6007 template<bool _Const>
6008 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
6010 _InnerSent<_Const> _M_inner;
6013 _Sentinel(_InnerSent<_Const> __inner)
6017 friend class adjacent_transform_view;
6020 _Sentinel() = default;
6023 _Sentinel(_Sentinel<!_Const> __i)
6024 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6025 : _M_inner(std::move(__i._M_inner))
6028 template<bool _OtherConst>
6029 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6030 friend constexpr bool
6031 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6032 { return __x._M_inner == __y._M_inner; }
6034 template<bool _OtherConst>
6035 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6036 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6037 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6038 { return __x._M_inner - __y._M_inner; }
6040 template<bool _OtherConst>
6041 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6042 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6043 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
6044 { return __x._M_inner - __y._M_inner; }
6051 template<size_t _Nm, typename _Range, typename _Fp>
6052 concept __can_adjacent_transform_view
6053 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6054 (std::declval<_Range>(), std::declval<_Fp>()); };
6057 template<size_t _Nm>
6058 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6060 template<viewable_range _Range, typename _Fp>
6061 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6063 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
6065 if constexpr (_Nm == 0)
6066 return zip_transform(std::forward<_Fp>(__f));
6068 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6069 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6072 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6073 static constexpr int _S_arity = 2;
6074 static constexpr bool _S_has_simple_extra_args = true;
6077 template<size_t _Nm>
6078 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6080 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6082#endif // __cpp_lib_ranges_zip
6084#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6087 template<typename _Tp>
6088 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6090 _Tp __r = __num / __denom;
6091 if (__num % __denom)
6098 requires input_range<_Vp>
6099 class chunk_view : public view_interface<chunk_view<_Vp>>
6102 range_difference_t<_Vp> _M_n;
6103 range_difference_t<_Vp> _M_remainder = 0;
6104 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6111 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6112 : _M_base(std::move(__base)), _M_n(__n)
6113 { __glibcxx_assert(__n >= 0); }
6116 base() const & requires copy_constructible<_Vp>
6121 { return std::move(_M_base); }
6123 constexpr _OuterIter
6126 _M_current = ranges::begin(_M_base);
6127 _M_remainder = _M_n;
6128 return _OuterIter(*this);
6131 constexpr default_sentinel_t
6132 end() const noexcept
6133 { return default_sentinel; }
6136 size() requires sized_range<_Vp>
6138 return __detail::__to_unsigned_like(__detail::__div_ceil
6139 (ranges::distance(_M_base), _M_n));
6143 size() const requires sized_range<const _Vp>
6145 return __detail::__to_unsigned_like(__detail::__div_ceil
6146 (ranges::distance(_M_base), _M_n));
6150 template<typename _Range>
6151 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6154 requires input_range<_Vp>
6155 class chunk_view<_Vp>::_OuterIter
6157 chunk_view* _M_parent;
6160 _OuterIter(chunk_view& __parent) noexcept
6161 : _M_parent(std::__addressof(__parent))
6167 using iterator_concept = input_iterator_tag;
6168 using difference_type = range_difference_t<_Vp>;
6172 _OuterIter(_OuterIter&&) = default;
6173 _OuterIter& operator=(_OuterIter&&) = default;
6175 constexpr value_type
6178 __glibcxx_assert(*this != default_sentinel);
6179 return value_type(*_M_parent);
6182 constexpr _OuterIter&
6185 __glibcxx_assert(*this != default_sentinel);
6186 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6187 ranges::end(_M_parent->_M_base));
6188 _M_parent->_M_remainder = _M_parent->_M_n;
6196 friend constexpr bool
6197 operator==(const _OuterIter& __x, default_sentinel_t)
6199 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6200 && __x._M_parent->_M_remainder != 0;
6203 friend constexpr difference_type
6204 operator-(default_sentinel_t, const _OuterIter& __x)
6205 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6207 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6209 if (__dist < __x._M_parent->_M_remainder)
6210 return __dist == 0 ? 0 : 1;
6212 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6213 __x._M_parent->_M_n);
6216 friend constexpr difference_type
6217 operator-(const _OuterIter& __x, default_sentinel_t __y)
6218 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6219 { return -(__y - __x); }
6223 requires input_range<_Vp>
6224 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6227 chunk_view* _M_parent;
6230 value_type(chunk_view& __parent) noexcept
6231 : _M_parent(std::__addressof(__parent))
6237 constexpr _InnerIter
6238 begin() const noexcept
6239 { return _InnerIter(*_M_parent); }
6241 constexpr default_sentinel_t
6242 end() const noexcept
6243 { return default_sentinel; }
6247 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6249 return __detail::__to_unsigned_like
6250 (ranges::min(_M_parent->_M_remainder,
6251 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6256 requires input_range<_Vp>
6257 class chunk_view<_Vp>::_InnerIter
6259 chunk_view* _M_parent;
6262 _InnerIter(chunk_view& __parent) noexcept
6263 : _M_parent(std::__addressof(__parent))
6266 friend _OuterIter::value_type;
6269 using iterator_concept = input_iterator_tag;
6270 using difference_type = range_difference_t<_Vp>;
6271 using value_type = range_value_t<_Vp>;
6273 _InnerIter(_InnerIter&&) = default;
6274 _InnerIter& operator=(_InnerIter&&) = default;
6276 constexpr const iterator_t<_Vp>&
6278 { return *_M_parent->_M_current; }
6280 constexpr range_reference_t<_Vp>
6283 __glibcxx_assert(*this != default_sentinel);
6284 return **_M_parent->_M_current;
6287 constexpr _InnerIter&
6290 __glibcxx_assert(*this != default_sentinel);
6291 ++*_M_parent->_M_current;
6292 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6293 _M_parent->_M_remainder = 0;
6295 --_M_parent->_M_remainder;
6303 friend constexpr bool
6304 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6305 { return __x._M_parent->_M_remainder == 0; }
6307 friend constexpr difference_type
6308 operator-(default_sentinel_t, const _InnerIter& __x)
6309 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6311 return ranges::min(__x._M_parent->_M_remainder,
6312 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6315 friend constexpr difference_type
6316 operator-(const _InnerIter& __x, default_sentinel_t __y)
6317 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6318 { return -(__y - __x); }
6320 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6321 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
6322 friend constexpr range_rvalue_reference_t<_Vp>
6323 iter_move(const _InnerIter& __i)
6324 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6325 { return ranges::iter_move(*__i._M_parent->_M_current); }
6327 friend constexpr void
6328 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
6329 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6330 *__x._M_parent->_M_current)))
6331 requires indirectly_swappable<iterator_t<_Vp>>
6332 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6336 requires forward_range<_Vp>
6337 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6340 range_difference_t<_Vp> _M_n;
6341 template<bool> class _Iterator;
6345 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6346 : _M_base(std::move(__base)), _M_n(__n)
6347 { __glibcxx_assert(__n > 0); }
6350 base() const & requires copy_constructible<_Vp>
6355 { return std::move(_M_base); }
6358 begin() requires (!__detail::__simple_view<_Vp>)
6359 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6362 begin() const requires forward_range<const _Vp>
6363 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6366 end() requires (!__detail::__simple_view<_Vp>)
6368 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6370 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6371 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6373 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6374 return _Iterator<false>(this, ranges::end(_M_base));
6376 return default_sentinel;
6380 end() const requires forward_range<const _Vp>
6382 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6384 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6385 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6387 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6388 return _Iterator<true>(this, ranges::end(_M_base));
6390 return default_sentinel;
6394 size() requires sized_range<_Vp>
6396 return __detail::__to_unsigned_like(__detail::__div_ceil
6397 (ranges::distance(_M_base), _M_n));
6401 size() const requires sized_range<const _Vp>
6403 return __detail::__to_unsigned_like(__detail::__div_ceil
6404 (ranges::distance(_M_base), _M_n));
6408 template<typename _Vp>
6409 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6410 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6413 requires forward_range<_Vp>
6414 template<bool _Const>
6415 class chunk_view<_Vp>::_Iterator
6417 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6418 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6420 iterator_t<_Base> _M_current = iterator_t<_Base>();
6421 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6422 range_difference_t<_Base> _M_n = 0;
6423 range_difference_t<_Base> _M_missing = 0;
6426 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6427 range_difference_t<_Base> __missing = 0)
6428 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6429 _M_n(__parent->_M_n), _M_missing(__missing)
6435 if constexpr (random_access_range<_Base>)
6436 return random_access_iterator_tag{};
6437 else if constexpr (bidirectional_range<_Base>)
6438 return bidirectional_iterator_tag{};
6440 return forward_iterator_tag{};
6446 using iterator_category = input_iterator_tag;
6447 using iterator_concept = decltype(_S_iter_cat());
6448 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6449 using difference_type = range_difference_t<_Base>;
6451 _Iterator() = default;
6453 constexpr _Iterator(_Iterator<!_Const> __i)
6455 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6456 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6457 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6458 _M_n(__i._M_n), _M_missing(__i._M_missing)
6461 constexpr iterator_t<_Base>
6463 { return _M_current; }
6465 constexpr value_type
6468 __glibcxx_assert(_M_current != _M_end);
6469 return views::take(subrange(_M_current, _M_end), _M_n);
6472 constexpr _Iterator&
6475 __glibcxx_assert(_M_current != _M_end);
6476 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6488 constexpr _Iterator&
6489 operator--() requires bidirectional_range<_Base>
6491 ranges::advance(_M_current, _M_missing - _M_n);
6497 operator--(int) requires bidirectional_range<_Base>
6504 constexpr _Iterator&
6505 operator+=(difference_type __x)
6506 requires random_access_range<_Base>
6510 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6511 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6515 ranges::advance(_M_current, _M_n * __x + _M_missing);
6521 constexpr _Iterator&
6522 operator-=(difference_type __x)
6523 requires random_access_range<_Base>
6524 { return *this += -__x; }
6526 constexpr value_type
6527 operator[](difference_type __n) const
6528 requires random_access_range<_Base>
6529 { return *(*this + __n); }
6531 friend constexpr bool
6532 operator==(const _Iterator& __x, const _Iterator& __y)
6533 { return __x._M_current == __y._M_current; }
6535 friend constexpr bool
6536 operator==(const _Iterator& __x, default_sentinel_t)
6537 { return __x._M_current == __x._M_end; }
6539 friend constexpr bool
6540 operator<(const _Iterator& __x, const _Iterator& __y)
6541 requires random_access_range<_Base>
6542 { return __x._M_current > __y._M_current; }
6544 friend constexpr bool
6545 operator>(const _Iterator& __x, const _Iterator& __y)
6546 requires random_access_range<_Base>
6547 { return __y < __x; }
6549 friend constexpr bool
6550 operator<=(const _Iterator& __x, const _Iterator& __y)
6551 requires random_access_range<_Base>
6552 { return !(__y < __x); }
6554 friend constexpr bool
6555 operator>=(const _Iterator& __x, const _Iterator& __y)
6556 requires random_access_range<_Base>
6557 { return !(__x < __y); }
6559 friend constexpr auto
6560 operator<=>(const _Iterator& __x, const _Iterator& __y)
6561 requires random_access_range<_Base>
6562 && three_way_comparable<iterator_t<_Base>>
6563 { return __x._M_current <=> __y._M_current; }
6565 friend constexpr _Iterator
6566 operator+(const _Iterator& __i, difference_type __n)
6567 requires random_access_range<_Base>
6574 friend constexpr _Iterator
6575 operator+(difference_type __n, const _Iterator& __i)
6576 requires random_access_range<_Base>
6583 friend constexpr _Iterator
6584 operator-(const _Iterator& __i, difference_type __n)
6585 requires random_access_range<_Base>
6592 friend constexpr difference_type
6593 operator-(const _Iterator& __x, const _Iterator& __y)
6594 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6596 return (__x._M_current - __y._M_current
6597 + __x._M_missing - __y._M_missing) / __x._M_n;
6600 friend constexpr difference_type
6601 operator-(default_sentinel_t, const _Iterator& __x)
6602 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6603 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6605 friend constexpr difference_type
6606 operator-(const _Iterator& __x, default_sentinel_t __y)
6607 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6608 { return -(__y - __x); }
6615 template<typename _Range, typename _Dp>
6616 concept __can_chunk_view
6617 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6620 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6622 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6623 requires __detail::__can_chunk_view<_Range, _Dp>
6625 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6626 { return chunk_view(std::forward<_Range>(__r), __n); }
6628 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6629 static constexpr int _S_arity = 2;
6630 static constexpr bool _S_has_simple_extra_args = true;
6633 inline constexpr _Chunk chunk;
6635#endif // __cpp_lib_ranges_chunk
6637#ifdef __cpp_lib_ranges_slide // C++ >= 23
6640 template<typename _Vp>
6641 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6643 template<typename _Vp>
6644 concept __slide_caches_last
6645 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6647 template<typename _Vp>
6648 concept __slide_caches_first
6649 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6652 template<forward_range _Vp>
6654 class slide_view : public view_interface<slide_view<_Vp>>
6657 range_difference_t<_Vp> _M_n;
6658 [[no_unique_address]]
6659 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6660 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6661 [[no_unique_address]]
6662 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6663 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6665 template<bool> class _Iterator;
6670 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6671 : _M_base(std::move(__base)), _M_n(__n)
6672 { __glibcxx_assert(__n > 0); }
6674 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6675 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
6677 base() const & requires copy_constructible<_Vp>
6682 { return std::move(_M_base); }
6685 begin() requires (!(__detail::__simple_view<_Vp>
6686 && __detail::__slide_caches_nothing<const _Vp>))
6688 if constexpr (__detail::__slide_caches_first<_Vp>)
6690 iterator_t<_Vp> __it;
6691 if (_M_cached_begin._M_has_value())
6692 __it = _M_cached_begin._M_get(_M_base);
6695 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6696 _M_cached_begin._M_set(_M_base, __it);
6698 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6701 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6705 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6706 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6709 end() requires (!(__detail::__simple_view<_Vp>
6710 && __detail::__slide_caches_nothing<const _Vp>))
6712 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6713 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6715 else if constexpr (__detail::__slide_caches_last<_Vp>)
6717 iterator_t<_Vp> __it;
6718 if (_M_cached_end._M_has_value())
6719 __it = _M_cached_end._M_get(_M_base);
6722 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6723 _M_cached_end._M_set(_M_base, __it);
6725 return _Iterator<false>(std::move(__it), _M_n);
6727 else if constexpr (common_range<_Vp>)
6728 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6730 return _Sentinel(ranges::end(_M_base));
6734 end() const requires __detail::__slide_caches_nothing<const _Vp>
6735 { return begin() + range_difference_t<const _Vp>(size()); }
6738 size() requires sized_range<_Vp>
6740 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6743 return __detail::__to_unsigned_like(__sz);
6747 size() const requires sized_range<const _Vp>
6749 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6752 return __detail::__to_unsigned_like(__sz);
6756 template<typename _Range>
6757 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6759 template<typename _Vp>
6760 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6761 = enable_borrowed_range<_Vp>;
6763 template<forward_range _Vp>
6765 template<bool _Const>
6766 class slide_view<_Vp>::_Iterator
6768 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6769 static constexpr bool _S_last_elt_present
6770 = __detail::__slide_caches_first<_Base>;
6772 iterator_t<_Base> _M_current = iterator_t<_Base>();
6773 [[no_unique_address]]
6774 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6775 _M_last_elt = decltype(_M_last_elt)();
6776 range_difference_t<_Base> _M_n = 0;
6779 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6780 requires (!_S_last_elt_present)
6781 : _M_current(__current), _M_n(__n)
6785 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6786 range_difference_t<_Base> __n)
6787 requires _S_last_elt_present
6788 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6794 if constexpr (random_access_range<_Base>)
6795 return random_access_iterator_tag{};
6796 else if constexpr (bidirectional_range<_Base>)
6797 return bidirectional_iterator_tag{};
6799 return forward_iterator_tag{};
6803 friend slide_view::_Sentinel;
6806 using iterator_category = input_iterator_tag;
6807 using iterator_concept = decltype(_S_iter_concept());
6808 using value_type = decltype(views::counted(_M_current, _M_n));
6809 using difference_type = range_difference_t<_Base>;
6811 _Iterator() = default;
6814 _Iterator(_Iterator<!_Const> __i)
6815 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6816 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6821 { return views::counted(_M_current, _M_n); }
6823 constexpr _Iterator&
6827 if constexpr (_S_last_elt_present)
6840 constexpr _Iterator&
6841 operator--() requires bidirectional_range<_Base>
6844 if constexpr (_S_last_elt_present)
6850 operator--(int) requires bidirectional_range<_Base>
6857 constexpr _Iterator&
6858 operator+=(difference_type __x)
6859 requires random_access_range<_Base>
6862 if constexpr (_S_last_elt_present)
6867 constexpr _Iterator&
6868 operator-=(difference_type __x)
6869 requires random_access_range<_Base>
6872 if constexpr (_S_last_elt_present)
6878 operator[](difference_type __n) const
6879 requires random_access_range<_Base>
6880 { return views::counted(_M_current + __n, _M_n); }
6882 friend constexpr bool
6883 operator==(const _Iterator& __x, const _Iterator& __y)
6885 if constexpr (_S_last_elt_present)
6886 return __x._M_last_elt == __y._M_last_elt;
6888 return __x._M_current == __y._M_current;
6891 friend constexpr bool
6892 operator<(const _Iterator& __x, const _Iterator& __y)
6893 requires random_access_range<_Base>
6894 { return __x._M_current < __y._M_current; }
6896 friend constexpr bool
6897 operator>(const _Iterator& __x, const _Iterator& __y)
6898 requires random_access_range<_Base>
6899 { return __y < __x; }
6901 friend constexpr bool
6902 operator<=(const _Iterator& __x, const _Iterator& __y)
6903 requires random_access_range<_Base>
6904 { return !(__y < __x); }
6906 friend constexpr bool
6907 operator>=(const _Iterator& __x, const _Iterator& __y)
6908 requires random_access_range<_Base>
6909 { return !(__x < __y); }
6911 friend constexpr auto
6912 operator<=>(const _Iterator& __x, const _Iterator& __y)
6913 requires random_access_range<_Base>
6914 && three_way_comparable<iterator_t<_Base>>
6915 { return __x._M_current <=> __y._M_current; }
6917 friend constexpr _Iterator
6918 operator+(const _Iterator& __i, difference_type __n)
6919 requires random_access_range<_Base>
6926 friend constexpr _Iterator
6927 operator+(difference_type __n, const _Iterator& __i)
6928 requires random_access_range<_Base>
6935 friend constexpr _Iterator
6936 operator-(const _Iterator& __i, difference_type __n)
6937 requires random_access_range<_Base>
6944 friend constexpr difference_type
6945 operator-(const _Iterator& __x, const _Iterator& __y)
6946 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6948 if constexpr (_S_last_elt_present)
6949 return __x._M_last_elt - __y._M_last_elt;
6951 return __x._M_current - __y._M_current;
6955 template<forward_range _Vp>
6957 class slide_view<_Vp>::_Sentinel
6959 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6962 _Sentinel(sentinel_t<_Vp> __end)
6969 _Sentinel() = default;
6971 friend constexpr bool
6972 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6973 { return __x._M_last_elt == __y._M_end; }
6975 friend constexpr range_difference_t<_Vp>
6976 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6977 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6978 { return __x._M_last_elt - __y._M_end; }
6980 friend constexpr range_difference_t<_Vp>
6981 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6982 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6983 { return __y._M_end -__x._M_last_elt; }
6990 template<typename _Range, typename _Dp>
6991 concept __can_slide_view
6992 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6995 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6997 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6998 requires __detail::__can_slide_view<_Range, _Dp>
7000 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
7001 { return slide_view(std::forward<_Range>(__r), __n); }
7003 using __adaptor::_RangeAdaptor<_Slide>::operator();
7004 static constexpr int _S_arity = 2;
7005 static constexpr bool _S_has_simple_extra_args = true;
7008 inline constexpr _Slide slide;
7010#endif // __cpp_lib_ranges_slide
7012#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
7013 template<forward_range _Vp,
7014 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7015 requires view<_Vp> && is_object_v<_Pred>
7016 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
7018 _Vp _M_base = _Vp();
7019 __detail::__box<_Pred> _M_pred;
7020 __detail::_CachedPosition<_Vp> _M_cached_begin;
7022 constexpr iterator_t<_Vp>
7023 _M_find_next(iterator_t<_Vp> __current)
7025 __glibcxx_assert(_M_pred.has_value());
7026 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
7027 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
7029 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7030 return ranges::next(__it, 1, ranges::end(_M_base));
7033 constexpr iterator_t<_Vp>
7034 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
7036 __glibcxx_assert(_M_pred.has_value());
7037 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
7038 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
7040 auto __rbegin = std::make_reverse_iterator(__current);
7041 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
7042 __glibcxx_assert(__rbegin != __rend);
7043 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7044 return ranges::prev(__it, 1, ranges::begin(_M_base));
7050 chunk_by_view() requires (default_initializable<_Vp>
7051 && default_initializable<_Pred>)
7055 chunk_by_view(_Vp __base, _Pred __pred)
7056 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
7060 base() const & requires copy_constructible<_Vp>
7065 { return std::move(_M_base); }
7067 constexpr const _Pred&
7069 { return *_M_pred; }
7074 __glibcxx_assert(_M_pred.has_value());
7075 iterator_t<_Vp> __it;
7076 if (_M_cached_begin._M_has_value())
7077 __it = _M_cached_begin._M_get(_M_base);
7080 __it = _M_find_next(ranges::begin(_M_base));
7081 _M_cached_begin._M_set(_M_base, __it);
7083 return _Iterator(*this, ranges::begin(_M_base), __it);
7089 if constexpr (common_range<_Vp>)
7090 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
7092 return default_sentinel;
7096 template<typename _Range, typename _Pred>
7097 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7099 template<forward_range _Vp,
7100 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7101 requires view<_Vp> && is_object_v<_Pred>
7102 class chunk_by_view<_Vp, _Pred>::_Iterator
7104 chunk_by_view* _M_parent = nullptr;
7105 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7106 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7109 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7110 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7116 if constexpr (bidirectional_range<_Vp>)
7117 return bidirectional_iterator_tag{};
7119 return forward_iterator_tag{};
7122 friend chunk_by_view;
7125 using value_type = subrange<iterator_t<_Vp>>;
7126 using difference_type = range_difference_t<_Vp>;
7127 using iterator_category = input_iterator_tag;
7128 using iterator_concept = decltype(_S_iter_concept());
7130 _Iterator() = default;
7132 constexpr value_type
7135 __glibcxx_assert(_M_current != _M_next);
7136 return ranges::subrange(_M_current, _M_next);
7139 constexpr _Iterator&
7142 __glibcxx_assert(_M_current != _M_next);
7143 _M_current = _M_next;
7144 _M_next = _M_parent->_M_find_next(_M_current);
7156 constexpr _Iterator&
7157 operator--() requires bidirectional_range<_Vp>
7159 _M_next = _M_current;
7160 _M_current = _M_parent->_M_find_prev(_M_next);
7165 operator--(int) requires bidirectional_range<_Vp>
7172 friend constexpr bool
7173 operator==(const _Iterator& __x, const _Iterator& __y)
7174 { return __x._M_current == __y._M_current; }
7176 friend constexpr bool
7177 operator==(const _Iterator& __x, default_sentinel_t)
7178 { return __x._M_current == __x._M_next; }
7185 template<typename _Range, typename _Pred>
7186 concept __can_chunk_by_view
7187 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7190 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7192 template<viewable_range _Range, typename _Pred>
7193 requires __detail::__can_chunk_by_view<_Range, _Pred>
7195 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7196 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7198 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7199 static constexpr int _S_arity = 2;
7200 static constexpr bool _S_has_simple_extra_args = true;
7203 inline constexpr _ChunkBy chunk_by;
7205#endif // __cpp_lib_ranges_chunk_by
7207#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7210 template<typename _Range, typename _Pattern>
7211 concept __compatible_joinable_ranges
7212 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7213 && common_reference_with<range_reference_t<_Range>,
7214 range_reference_t<_Pattern>>
7215 && common_reference_with<range_rvalue_reference_t<_Range>,
7216 range_rvalue_reference_t<_Pattern>>;
7218 template<typename _Range>
7219 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7222 template<input_range _Vp, forward_range _Pattern>
7223 requires view<_Vp> && view<_Pattern>
7224 && input_range<range_reference_t<_Vp>>
7225 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7226 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7228 using _InnerRange = range_reference_t<_Vp>;
7230 _Vp _M_base = _Vp();
7231 [[no_unique_address]]
7232 __detail::__maybe_present_t<!forward_range<_Vp>,
7233 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7234 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7235 _Pattern _M_pattern = _Pattern();
7237 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7238 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7239 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7241 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7242 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7243 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7245 template<bool _Const>
7246 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7248 template<bool _Const>
7252 template<bool _Const>
7253 requires _S_ref_is_glvalue<_Const>
7254 && forward_range<_Base<_Const>>
7255 && forward_range<_InnerBase<_Const>>
7256 struct __iter_cat<_Const>
7262 using _OuterIter = join_with_view::_OuterIter<_Const>;
7263 using _InnerIter = join_with_view::_InnerIter<_Const>;
7264 using _PatternIter = join_with_view::_PatternIter<_Const>;
7265 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7266 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7267 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7268 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7269 // 3798. Rvalue reference and iterator_category
7270 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7271 iter_reference_t<_PatternIter>>>)
7272 return input_iterator_tag{};
7273 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7274 && derived_from<_InnerCat, bidirectional_iterator_tag>
7275 && derived_from<_PatternCat, bidirectional_iterator_tag>
7276 && common_range<_InnerBase<_Const>>
7277 && common_range<_PatternBase<_Const>>)
7278 return bidirectional_iterator_tag{};
7279 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7280 && derived_from<_InnerCat, forward_iterator_tag>
7281 && derived_from<_PatternCat, forward_iterator_tag>)
7282 return forward_iterator_tag{};
7284 return input_iterator_tag{};
7287 using iterator_category = decltype(_S_iter_cat());
7290 template<bool> class _Iterator;
7291 template<bool> class _Sentinel;
7294 join_with_view() requires (default_initializable<_Vp>
7295 && default_initializable<_Pattern>)
7299 join_with_view(_Vp __base, _Pattern __pattern)
7300 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7303 template<input_range _Range>
7304 requires constructible_from<_Vp, views::all_t<_Range>>
7305 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7307 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7308 : _M_base(views::all(std::forward<_Range>(__r))),
7309 _M_pattern(views::single(std::move(__e)))
7313 base() const& requires copy_constructible<_Vp>
7318 { return std::move(_M_base); }
7323 if constexpr (forward_range<_Vp>)
7325 constexpr bool __use_const = is_reference_v<_InnerRange>
7326 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7327 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7331 _M_outer_it = ranges::begin(_M_base);
7332 return _Iterator<false>{*this};
7338 requires forward_range<const _Vp>
7339 && forward_range<const _Pattern>
7340 && is_reference_v<range_reference_t<const _Vp>>
7341 && input_range<range_reference_t<const _Vp>>
7342 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7347 constexpr bool __use_const
7348 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7349 if constexpr (is_reference_v<_InnerRange>
7350 && forward_range<_Vp> && common_range<_Vp>
7351 && forward_range<_InnerRange> && common_range<_InnerRange>)
7352 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7354 return _Sentinel<__use_const>{*this};
7359 requires forward_range<const _Vp>
7360 && forward_range<const _Pattern>
7361 && is_reference_v<range_reference_t<const _Vp>>
7362 && input_range<range_reference_t<const _Vp>>
7364 using _InnerConstRange = range_reference_t<const _Vp>;
7365 if constexpr (forward_range<_InnerConstRange>
7366 && common_range<const _Vp>
7367 && common_range<_InnerConstRange>)
7368 return _Iterator<true>{*this, ranges::end(_M_base)};
7370 return _Sentinel<true>{*this};
7374 template<typename _Range, typename _Pattern>
7375 join_with_view(_Range&&, _Pattern&&)
7376 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7378 template<input_range _Range>
7379 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7380 -> join_with_view<views::all_t<_Range>,
7381 single_view<range_value_t<range_reference_t<_Range>>>>;
7383 template<input_range _Vp, forward_range _Pattern>
7384 requires view<_Vp> && view<_Pattern>
7385 && input_range<range_reference_t<_Vp>>
7386 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7387 template<bool _Const>
7388 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7390 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7391 using _Base = join_with_view::_Base<_Const>;
7392 using _InnerBase = join_with_view::_InnerBase<_Const>;
7393 using _PatternBase = join_with_view::_PatternBase<_Const>;
7395 using _OuterIter = join_with_view::_OuterIter<_Const>;
7396 using _InnerIter = join_with_view::_InnerIter<_Const>;
7397 using _PatternIter = join_with_view::_PatternIter<_Const>;
7399 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7401 _Parent* _M_parent = nullptr;
7402 [[no_unique_address]]
7403 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it;
7404 variant<_PatternIter, _InnerIter> _M_inner_it;
7406 constexpr _OuterIter&
7409 if constexpr (forward_range<_Base>)
7412 return *_M_parent->_M_outer_it;
7415 constexpr const _OuterIter&
7416 _M_get_outer() const
7418 if constexpr (forward_range<_Base>)
7421 return *_M_parent->_M_outer_it;
7425 _Iterator(_Parent& __parent, _OuterIter __outer)
7426 requires forward_range<_Base>
7427 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7429 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7431 auto&& __inner = _M_update_inner();
7432 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7438 _Iterator(_Parent& __parent)
7439 requires (!forward_range<_Base>)
7440 : _M_parent(std::__addressof(__parent))
7442 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7444 auto&& __inner = _M_update_inner();
7445 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7453 _OuterIter& __outer = _M_get_outer();
7454 if constexpr (_S_ref_is_glvalue)
7455 return __detail::__as_lvalue(*__outer);
7457 return _M_parent->_M_inner._M_emplace_deref(__outer);
7463 if constexpr (_S_ref_is_glvalue)
7464 return __detail::__as_lvalue(*_M_get_outer());
7466 return *_M_parent->_M_inner;
7474 if (_M_inner_it.index() == 0)
7476 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7479 auto&& __inner = _M_update_inner();
7480 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7484 auto&& __inner = _M_get_inner();
7485 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7488 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7490 if constexpr (_S_ref_is_glvalue)
7491 _M_inner_it.template emplace<0>();
7495 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7503 if constexpr (_S_ref_is_glvalue
7504 && bidirectional_range<_Base>
7505 && __detail::__bidirectional_common<_InnerBase>
7506 && __detail::__bidirectional_common<_PatternBase>)
7507 return bidirectional_iterator_tag{};
7508 else if constexpr (_S_ref_is_glvalue
7509 && forward_range<_Base>
7510 && forward_range<_InnerBase>)
7511 return forward_iterator_tag{};
7513 return input_iterator_tag{};
7516 friend join_with_view;
7519 using iterator_concept = decltype(_S_iter_concept());
7520 // iterator_category defined in join_with_view::__iter_cat
7521 using value_type = common_type_t<iter_value_t<_InnerIter>,
7522 iter_value_t<_PatternIter>>;
7523 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7524 iter_difference_t<_InnerIter>,
7525 iter_difference_t<_PatternIter>>;
7527 _Iterator() = default;
7530 _Iterator(_Iterator<!_Const> __i)
7532 && convertible_to<iterator_t<_Vp>, _OuterIter>
7533 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7534 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7535 : _M_parent(__i._M_parent),
7536 _M_outer_it(std::move(__i._M_outer_it))
7538 if (__i._M_inner_it.index() == 0)
7539 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7541 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7544 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7545 iter_reference_t<_PatternIter>>
7548 if (_M_inner_it.index() == 0)
7549 return *std::get<0>(_M_inner_it);
7551 return *std::get<1>(_M_inner_it);
7554 constexpr _Iterator&
7557 if (_M_inner_it.index() == 0)
7558 ++std::get<0>(_M_inner_it);
7560 ++std::get<1>(_M_inner_it);
7571 requires _S_ref_is_glvalue
7572 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7574 _Iterator __tmp = *this;
7579 constexpr _Iterator&
7581 requires _S_ref_is_glvalue
7582 && bidirectional_range<_Base>
7583 && __detail::__bidirectional_common<_InnerBase>
7584 && __detail::__bidirectional_common<_PatternBase>
7586 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7588 auto&& __inner = *--_M_outer_it;
7589 _M_inner_it.template emplace<1>(ranges::end(__inner));
7594 if (_M_inner_it.index() == 0)
7596 auto& __it = std::get<0>(_M_inner_it);
7597 if (__it == ranges::begin(_M_parent->_M_pattern))
7599 auto&& __inner = *--_M_outer_it;
7600 _M_inner_it.template emplace<1>(ranges::end(__inner));
7607 auto& __it = std::get<1>(_M_inner_it);
7608 auto&& __inner = *_M_outer_it;
7609 if (__it == ranges::begin(__inner))
7610 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7616 if (_M_inner_it.index() == 0)
7617 --std::get<0>(_M_inner_it);
7619 --std::get<1>(_M_inner_it);
7625 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7626 && __detail::__bidirectional_common<_InnerBase>
7627 && __detail::__bidirectional_common<_PatternBase>
7629 _Iterator __tmp = *this;
7634 friend constexpr bool
7635 operator==(const _Iterator& __x, const _Iterator& __y)
7636 requires _S_ref_is_glvalue
7637 && forward_range<_Base> && equality_comparable<_InnerIter>
7638 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7640 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7641 iter_rvalue_reference_t<_PatternIter>>
7642 iter_move(const _Iterator& __x)
7644 if (__x._M_inner_it.index() == 0)
7645 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7647 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7650 friend constexpr void
7651 iter_swap(const _Iterator& __x, const _Iterator& __y)
7652 requires indirectly_swappable<_InnerIter, _PatternIter>
7654 if (__x._M_inner_it.index() == 0)
7656 if (__y._M_inner_it.index() == 0)
7657 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7659 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7663 if (__y._M_inner_it.index() == 0)
7664 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7666 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7671 template<input_range _Vp, forward_range _Pattern>
7672 requires view<_Vp> && view<_Pattern>
7673 && input_range<range_reference_t<_Vp>>
7674 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7675 template<bool _Const>
7676 class join_with_view<_Vp, _Pattern>::_Sentinel
7678 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7679 using _Base = join_with_view::_Base<_Const>;
7681 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7684 _Sentinel(_Parent& __parent)
7685 : _M_end(ranges::end(__parent._M_base))
7688 friend join_with_view;
7691 _Sentinel() = default;
7694 _Sentinel(_Sentinel<!_Const> __s)
7695 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7696 : _M_end(std::move(__s._M_end))
7699 template<bool _OtherConst>
7700 requires sentinel_for<sentinel_t<_Base>,
7701 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7702 friend constexpr bool
7703 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7704 { return __x._M_get_outer() == __y._M_end; }
7711 template<typename _Range, typename _Pattern>
7712 concept __can_join_with_view
7713 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7714 } // namespace __detail
7716 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7718 template<viewable_range _Range, typename _Pattern>
7719 requires __detail::__can_join_with_view<_Range, _Pattern>
7721 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7723 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7726 using _RangeAdaptor<_JoinWith>::operator();
7727 static constexpr int _S_arity = 2;
7728 template<typename _Pattern>
7729 static constexpr bool _S_has_simple_extra_args
7730 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7733 inline constexpr _JoinWith join_with;
7734 } // namespace views
7735#endif // __cpp_lib_ranges_join_with
7737#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7738 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7739 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7740 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7741 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7743 __detail::__box<_Tp> _M_value;
7744 [[no_unique_address]] _Bound _M_bound = _Bound();
7748 template<typename _Range>
7749 friend constexpr auto
7750 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7752 template<typename _Range>
7753 friend constexpr auto
7754 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7757 repeat_view() requires default_initializable<_Tp> = default;
7760 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7761 requires copy_constructible<_Tp>
7762 : _M_value(__value), _M_bound(__bound)
7764 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7765 __glibcxx_assert(__bound >= 0);
7769 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7770 : _M_value(std::move(__value)), _M_bound(__bound)
7773 template<typename... _Args, typename... _BoundArgs>
7774 requires constructible_from<_Tp, _Args...>
7775 && constructible_from<_Bound, _BoundArgs...>
7777 repeat_view(piecewise_construct_t,
7778 tuple<_Args...> __args,
7779 tuple<_BoundArgs...> __bound_args = tuple<>{})
7780 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7781 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7786 { return _Iterator(std::__addressof(*_M_value)); }
7789 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7790 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7792 constexpr unreachable_sentinel_t
7793 end() const noexcept
7794 { return unreachable_sentinel; }
7797 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7798 { return __detail::__to_unsigned_like(_M_bound); }
7801 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7802 // 4053. Unary call to std::views::repeat does not decay the argument
7803 template<typename _Tp, typename _Bound = unreachable_sentinel_t>
7804 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7806 template<move_constructible _Tp, semiregular _Bound>
7807 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7808 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7809 class repeat_view<_Tp, _Bound>::_Iterator
7812 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7814 const _Tp* _M_value = nullptr;
7815 __index_type _M_current = __index_type();
7818 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7819 : _M_value(__value), _M_current(__bound)
7821 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7822 __glibcxx_assert(__bound >= 0);
7828 using iterator_concept = random_access_iterator_tag;
7829 using iterator_category = random_access_iterator_tag;
7830 using value_type = _Tp;
7831 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7833 __detail::__iota_diff_t<__index_type>>;
7835 _Iterator() = default;
7837 constexpr const _Tp&
7838 operator*() const noexcept
7839 { return *_M_value; }
7841 constexpr _Iterator&
7856 constexpr _Iterator&
7859 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7860 __glibcxx_assert(_M_current > 0);
7873 constexpr _Iterator&
7874 operator+=(difference_type __n)
7876 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7877 __glibcxx_assert(_M_current + __n >= 0);
7882 constexpr _Iterator&
7883 operator-=(difference_type __n)
7885 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7886 __glibcxx_assert(_M_current - __n >= 0);
7891 constexpr const _Tp&
7892 operator[](difference_type __n) const noexcept
7893 { return *(*this + __n); }
7895 friend constexpr bool
7896 operator==(const _Iterator& __x, const _Iterator& __y)
7897 { return __x._M_current == __y._M_current; }
7899 friend constexpr auto
7900 operator<=>(const _Iterator& __x, const _Iterator& __y)
7901 { return __x._M_current <=> __y._M_current; }
7903 friend constexpr _Iterator
7904 operator+(_Iterator __i, difference_type __n)
7910 friend constexpr _Iterator
7911 operator+(difference_type __n, _Iterator __i)
7912 { return __i + __n; }
7914 friend constexpr _Iterator
7915 operator-(_Iterator __i, difference_type __n)
7921 friend constexpr difference_type
7922 operator-(const _Iterator& __x, const _Iterator& __y)
7924 return (static_cast<difference_type>(__x._M_current)
7925 - static_cast<difference_type>(__y._M_current));
7933 template<typename _Tp, typename _Bound>
7934 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7936 template<typename _Tp>
7937 concept __can_repeat_view
7938 = requires { repeat_view(std::declval<_Tp>()); };
7940 template<typename _Tp, typename _Bound>
7941 concept __can_bounded_repeat_view
7942 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7947 template<typename _Tp>
7948 requires __detail::__can_repeat_view<_Tp>
7950 operator() [[nodiscard]] (_Tp&& __value) const
7952 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7953 // 4054. Repeating a repeat_view should repeat the view
7954 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7957 template<typename _Tp, typename _Bound>
7958 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7960 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7961 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7964 inline constexpr _Repeat repeat;
7968 template<typename _Range>
7970 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7972 using _Tp = remove_cvref_t<_Range>;
7973 static_assert(__is_repeat_view<_Tp>);
7974 if constexpr (sized_range<_Tp>)
7975 return views::repeat(*std::forward<_Range>(__r)._M_value,
7976 std::min(ranges::distance(__r), __n));
7978 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7981 template<typename _Range>
7983 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7985 using _Tp = remove_cvref_t<_Range>;
7986 static_assert(__is_repeat_view<_Tp>);
7987 if constexpr (sized_range<_Tp>)
7989 auto __sz = ranges::distance(__r);
7990 return views::repeat(*std::forward<_Range>(__r)._M_value,
7991 __sz - std::min(__sz, __n));
7998#endif // __cpp_lib_ranges_repeat
8000#ifdef __cpp_lib_ranges_stride // C++ >= 23
8001 template<input_range _Vp>
8003 class stride_view : public view_interface<stride_view<_Vp>>
8006 range_difference_t<_Vp> _M_stride;
8008 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
8010 template<bool _Const>
8014 template<bool _Const>
8015 requires forward_range<_Base<_Const>>
8016 struct __iter_cat<_Const>
8022 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8023 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8024 return random_access_iterator_tag{};
8029 using iterator_category = decltype(_S_iter_cat());
8032 template<bool> class _Iterator;
8036 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8037 : _M_base(std::move(__base)), _M_stride(__stride)
8038 { __glibcxx_assert(__stride > 0); }
8041 base() const& requires copy_constructible<_Vp>
8046 { return std::move(_M_base); }
8048 constexpr range_difference_t<_Vp>
8049 stride() const noexcept
8050 { return _M_stride; }
8053 begin() requires (!__detail::__simple_view<_Vp>)
8054 { return _Iterator<false>(this, ranges::begin(_M_base)); }
8057 begin() const requires range<const _Vp>
8058 { return _Iterator<true>(this, ranges::begin(_M_base)); }
8061 end() requires (!__detail::__simple_view<_Vp>)
8063 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8065 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8066 return _Iterator<false>(this, ranges::end(_M_base), __missing);
8068 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8069 return _Iterator<false>(this, ranges::end(_M_base));
8071 return default_sentinel;
8075 end() const requires range<const _Vp>
8077 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8078 && forward_range<const _Vp>)
8080 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8081 return _Iterator<true>(this, ranges::end(_M_base), __missing);
8083 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8084 return _Iterator<true>(this, ranges::end(_M_base));
8086 return default_sentinel;
8090 size() requires sized_range<_Vp>
8092 return __detail::__to_unsigned_like
8093 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8097 size() const requires sized_range<const _Vp>
8099 return __detail::__to_unsigned_like
8100 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8104 template<typename _Range>
8105 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8107 template<typename _Vp>
8108 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8109 = enable_borrowed_range<_Vp>;
8111 template<input_range _Vp>
8113 template<bool _Const>
8114 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8116 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8117 using _Base = stride_view::_Base<_Const>;
8119 iterator_t<_Base> _M_current = iterator_t<_Base>();
8120 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8121 range_difference_t<_Base> _M_stride = 0;
8122 range_difference_t<_Base> _M_missing = 0;
8125 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8126 range_difference_t<_Base> __missing = 0)
8127 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8128 _M_stride(__parent->_M_stride), _M_missing(__missing)
8134 if constexpr (random_access_range<_Base>)
8135 return random_access_iterator_tag{};
8136 else if constexpr (bidirectional_range<_Base>)
8137 return bidirectional_iterator_tag{};
8138 else if constexpr (forward_range<_Base>)
8139 return forward_iterator_tag{};
8141 return input_iterator_tag{};
8147 using difference_type = range_difference_t<_Base>;
8148 using value_type = range_value_t<_Base>;
8149 using iterator_concept = decltype(_S_iter_concept());
8150 // iterator_category defined in stride_view::__iter_cat
8152 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8155 _Iterator(_Iterator<!_Const> __other)
8157 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8158 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8159 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8160 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8163 constexpr iterator_t<_Base>
8165 { return std::move(_M_current); }
8167 constexpr const iterator_t<_Base>&
8168 base() const & noexcept
8169 { return _M_current; }
8171 constexpr decltype(auto)
8173 { return *_M_current; }
8175 constexpr _Iterator&
8178 __glibcxx_assert(_M_current != _M_end);
8179 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8188 operator++(int) requires forward_range<_Base>
8195 constexpr _Iterator&
8196 operator--() requires bidirectional_range<_Base>
8198 ranges::advance(_M_current, _M_missing - _M_stride);
8204 operator--(int) requires bidirectional_range<_Base>
8211 constexpr _Iterator&
8212 operator+=(difference_type __n) requires random_access_range<_Base>
8216 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8217 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8221 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8227 constexpr _Iterator&
8228 operator-=(difference_type __n) requires random_access_range<_Base>
8229 { return *this += -__n; }
8231 constexpr decltype(auto) operator[](difference_type __n) const
8232 requires random_access_range<_Base>
8233 { return *(*this + __n); }
8235 friend constexpr bool
8236 operator==(const _Iterator& __x, default_sentinel_t)
8237 { return __x._M_current == __x._M_end; }
8239 friend constexpr bool
8240 operator==(const _Iterator& __x, const _Iterator& __y)
8241 requires equality_comparable<iterator_t<_Base>>
8242 { return __x._M_current == __y._M_current; }
8244 friend constexpr bool
8245 operator<(const _Iterator& __x, const _Iterator& __y)
8246 requires random_access_range<_Base>
8247 { return __x._M_current < __y._M_current; }
8249 friend constexpr bool
8250 operator>(const _Iterator& __x, const _Iterator& __y)
8251 requires random_access_range<_Base>
8252 { return __y._M_current < __x._M_current; }
8254 friend constexpr bool
8255 operator<=(const _Iterator& __x, const _Iterator& __y)
8256 requires random_access_range<_Base>
8257 { return !(__y._M_current < __x._M_current); }
8259 friend constexpr bool
8260 operator>=(const _Iterator& __x, const _Iterator& __y)
8261 requires random_access_range<_Base>
8262 { return !(__x._M_current < __y._M_current); }
8264 friend constexpr auto
8265 operator<=>(const _Iterator& __x, const _Iterator& __y)
8266 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8267 { return __x._M_current <=> __y._M_current; }
8269 friend constexpr _Iterator
8270 operator+(const _Iterator& __i, difference_type __n)
8271 requires random_access_range<_Base>
8278 friend constexpr _Iterator
8279 operator+(difference_type __n, const _Iterator& __i)
8280 requires random_access_range<_Base>
8281 { return __i + __n; }
8283 friend constexpr _Iterator
8284 operator-(const _Iterator& __i, difference_type __n)
8285 requires random_access_range<_Base>
8292 friend constexpr difference_type
8293 operator-(const _Iterator& __x, const _Iterator& __y)
8294 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8296 auto __n = __x._M_current - __y._M_current;
8297 if constexpr (forward_range<_Base>)
8298 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8300 return -__detail::__div_ceil(-__n, __x._M_stride);
8302 return __detail::__div_ceil(__n, __x._M_stride);
8305 friend constexpr difference_type
8306 operator-(default_sentinel_t, const _Iterator& __x)
8307 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8308 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8310 friend constexpr difference_type
8311 operator-(const _Iterator& __x, default_sentinel_t __y)
8312 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8313 { return -(__y - __x); }
8315 friend constexpr range_rvalue_reference_t<_Base>
8316 iter_move(const _Iterator& __i)
8317 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8318 { return ranges::iter_move(__i._M_current); }
8320 friend constexpr void
8321 iter_swap(const _Iterator& __x, const _Iterator& __y)
8322 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8323 requires indirectly_swappable<iterator_t<_Base>>
8324 { ranges::iter_swap(__x._M_current, __y._M_current); }
8331 template<typename _Range, typename _Dp>
8332 concept __can_stride_view
8333 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8336 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8338 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8339 requires __detail::__can_stride_view<_Range, _Dp>
8341 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8342 { return stride_view(std::forward<_Range>(__r), __n); }
8344 using __adaptor::_RangeAdaptor<_Stride>::operator();
8345 static constexpr int _S_arity = 2;
8346 static constexpr bool _S_has_simple_extra_args = true;
8349 inline constexpr _Stride stride;
8351#endif // __cpp_lib_ranges_stride
8353#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8356 template<bool _Const, typename _First, typename... _Vs>
8357 concept __cartesian_product_is_random_access
8358 = (random_access_range<__maybe_const_t<_Const, _First>>
8360 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8361 && sized_range<__maybe_const_t<_Const, _Vs>>));
8363 template<typename _Range>
8364 concept __cartesian_product_common_arg
8365 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8367 template<bool _Const, typename _First, typename... _Vs>
8368 concept __cartesian_product_is_bidirectional
8369 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8371 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8372 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8374 template<typename _First, typename... _Vs>
8375 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8377 template<typename... _Vs>
8378 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8380 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8381 concept __cartesian_is_sized_sentinel
8382 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8383 iterator_t<__maybe_const_t<_Const, _First>>>
8385 && (sized_range<__maybe_const_t<_Const, _Vs>>
8386 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8387 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8389 template<__cartesian_product_common_arg _Range>
8391 __cartesian_common_arg_end(_Range& __r)
8393 if constexpr (common_range<_Range>)
8394 return ranges::end(__r);
8396 return ranges::begin(__r) + ranges::distance(__r);
8398 } // namespace __detail
8400 template<input_range _First, forward_range... _Vs>
8401 requires (view<_First> && ... && view<_Vs>)
8402 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8404 tuple<_First, _Vs...> _M_bases;
8406 template<bool> class _Iterator;
8409 _S_difference_type()
8411 // TODO: Implement the recommended practice of using the smallest
8412 // sufficiently wide type according to the maximum sizes of the
8413 // underlying ranges?
8414 return common_type_t<ptrdiff_t,
8415 range_difference_t<_First>,
8416 range_difference_t<_Vs>...>{};
8420 cartesian_product_view() = default;
8423 cartesian_product_view(_First __first, _Vs... __rest)
8424 : _M_bases(std::move(__first), std::move(__rest)...)
8427 constexpr _Iterator<false>
8428 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8429 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8431 constexpr _Iterator<true>
8432 begin() const requires (range<const _First> && ... && range<const _Vs>)
8433 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8435 constexpr _Iterator<false>
8436 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8437 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8439 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8440 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8441 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8442 auto& __first = std::get<0>(_M_bases);
8443 return _Ret{(__empty_tail
8444 ? ranges::begin(__first)
8445 : __detail::__cartesian_common_arg_end(__first)),
8446 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8447 }(make_index_sequence<sizeof...(_Vs)>{});
8449 return _Iterator<false>{*this, std::move(__its)};
8452 constexpr _Iterator<true>
8453 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8455 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8456 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8457 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8458 auto& __first = std::get<0>(_M_bases);
8459 return _Ret{(__empty_tail
8460 ? ranges::begin(__first)
8461 : __detail::__cartesian_common_arg_end(__first)),
8462 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8463 }(make_index_sequence<sizeof...(_Vs)>{});
8465 return _Iterator<true>{*this, std::move(__its)};
8468 constexpr default_sentinel_t
8469 end() const noexcept
8470 { return default_sentinel; }
8473 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8475 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8476 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8477 auto __size = static_cast<_ST>(1);
8478#ifdef _GLIBCXX_ASSERTIONS
8479 if constexpr (integral<_ST>)
8482 = (__builtin_mul_overflow(__size,
8483 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8486 __glibcxx_assert(!__overflow);
8490 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8492 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8496 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8498 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8499 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8500 auto __size = static_cast<_ST>(1);
8501#ifdef _GLIBCXX_ASSERTIONS
8502 if constexpr (integral<_ST>)
8505 = (__builtin_mul_overflow(__size,
8506 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8509 __glibcxx_assert(!__overflow);
8513 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8515 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8519 template<typename... _Vs>
8520 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8522 template<input_range _First, forward_range... _Vs>
8523 requires (view<_First> && ... && view<_Vs>)
8524 template<bool _Const>
8525 class cartesian_product_view<_First, _Vs...>::_Iterator
8527 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8528 _Parent* _M_parent = nullptr;
8529 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8530 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8533 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8534 : _M_parent(std::__addressof(__parent)),
8535 _M_current(std::move(__current))
8541 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8542 return random_access_iterator_tag{};
8543 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8544 return bidirectional_iterator_tag{};
8545 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8546 return forward_iterator_tag{};
8548 return input_iterator_tag{};
8551 friend cartesian_product_view;
8554 using iterator_category = input_iterator_tag;
8555 using iterator_concept = decltype(_S_iter_concept());
8557 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8558 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8560 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8561 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8562 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8564 _Iterator() = default;
8567 _Iterator(_Iterator<!_Const> __i)
8569 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8570 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8571 : _M_parent(std::__addressof(__i._M_parent)),
8572 _M_current(std::move(__i._M_current))
8578 auto __f = [](auto& __i) -> decltype(auto) {
8581 return __detail::__tuple_transform(__f, _M_current);
8584 constexpr _Iterator&
8596 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8603 constexpr _Iterator&
8605 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8613 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8620 constexpr _Iterator&
8621 operator+=(difference_type __x)
8622 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8628 constexpr _Iterator&
8629 operator-=(difference_type __x)
8630 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8631 { return *this += -__x; }
8634 operator[](difference_type __n) const
8635 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8636 { return *((*this) + __n); }
8638 friend constexpr bool
8639 operator==(const _Iterator& __x, const _Iterator& __y)
8640 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8641 { return __x._M_current == __y._M_current; }
8643 friend constexpr bool
8644 operator==(const _Iterator& __x, default_sentinel_t)
8646 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8647 return ((std::get<_Is>(__x._M_current)
8648 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8650 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8653 friend constexpr auto
8654 operator<=>(const _Iterator& __x, const _Iterator& __y)
8655 requires __detail::__all_random_access<_Const, _First, _Vs...>
8656 { return __x._M_current <=> __y._M_current; }
8658 friend constexpr _Iterator
8659 operator+(_Iterator __x, difference_type __y)
8660 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8661 { return __x += __y; }
8663 friend constexpr _Iterator
8664 operator+(difference_type __x, _Iterator __y)
8665 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8666 { return __y += __x; }
8668 friend constexpr _Iterator
8669 operator-(_Iterator __x, difference_type __y)
8670 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8671 { return __x -= __y; }
8673 friend constexpr difference_type
8674 operator-(const _Iterator& __x, const _Iterator& __y)
8675 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8676 { return __x._M_distance_from(__y._M_current); }
8678 friend constexpr difference_type
8679 operator-(const _Iterator& __i, default_sentinel_t)
8680 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8682 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8683 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8684 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8685 }(make_index_sequence<sizeof...(_Vs)>{});
8686 return __i._M_distance_from(__end_tuple);
8689 friend constexpr difference_type
8690 operator-(default_sentinel_t, const _Iterator& __i)
8691 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8692 { return -(__i - default_sentinel); }
8694 friend constexpr auto
8695 iter_move(const _Iterator& __i)
8696 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8698 friend constexpr void
8699 iter_swap(const _Iterator& __l, const _Iterator& __r)
8700 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8702 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8704 [&]<size_t... _Is>(index_sequence<_Is...>) {
8705 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8706 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8710 template<size_t _Nm = sizeof...(_Vs)>
8714 auto& __it = std::get<_Nm>(_M_current);
8716 if constexpr (_Nm > 0)
8717 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8719 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8724 template<size_t _Nm = sizeof...(_Vs)>
8728 auto& __it = std::get<_Nm>(_M_current);
8729 if constexpr (_Nm > 0)
8730 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8732 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8738 template<size_t _Nm = sizeof...(_Vs)>
8740 _M_advance(difference_type __x)
8741 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8749 // Constant time iterator advancement.
8750 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8751 auto& __it = std::get<_Nm>(_M_current);
8752 if constexpr (_Nm == 0)
8754#ifdef _GLIBCXX_ASSERTIONS
8755 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8757 auto __size = ranges::ssize(__r);
8758 auto __begin = ranges::begin(__r);
8759 auto __offset = __it - __begin;
8760 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8767 auto __size = ranges::ssize(__r);
8768 auto __begin = ranges::begin(__r);
8769 auto __offset = __it - __begin;
8771 __x = __offset / __size;
8775 __offset = __size + __offset;
8778 __it = __begin + __offset;
8779 _M_advance<_Nm - 1>(__x);
8784 template<typename _Tuple>
8785 constexpr difference_type
8786 _M_distance_from(const _Tuple& __t) const
8788 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8789 auto __sum = static_cast<difference_type>(0);
8790#ifdef _GLIBCXX_ASSERTIONS
8791 if constexpr (integral<difference_type>)
8794 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8796 __glibcxx_assert(!__overflow);
8800 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8802 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8805 template<size_t _Nm, typename _Tuple>
8806 constexpr difference_type
8807 _M_scaled_distance(const _Tuple& __t) const
8809 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8810 - std::get<_Nm>(__t));
8811#ifdef _GLIBCXX_ASSERTIONS
8812 if constexpr (integral<difference_type>)
8814 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8815 __glibcxx_assert(!__overflow);
8819 __dist *= _M_scaled_size<_Nm+1>();
8823 template<size_t _Nm>
8824 constexpr difference_type
8825 _M_scaled_size() const
8827 if constexpr (_Nm <= sizeof...(_Vs))
8829 auto __size = static_cast<difference_type>(ranges::size
8830 (std::get<_Nm>(_M_parent->_M_bases)));
8831#ifdef _GLIBCXX_ASSERTIONS
8832 if constexpr (integral<difference_type>)
8834 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8835 __glibcxx_assert(!__overflow);
8839 __size *= _M_scaled_size<_Nm+1>();
8843 return static_cast<difference_type>(1);
8851 template<typename... _Ts>
8852 concept __can_cartesian_product_view
8853 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8856 struct _CartesianProduct
8858 template<typename... _Ts>
8859 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8861 operator() [[nodiscard]] (_Ts&&... __ts) const
8863 if constexpr (sizeof...(_Ts) == 0)
8864 return views::single(tuple{});
8866 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8870 inline constexpr _CartesianProduct cartesian_product;
8872#endif // __cpp_lib_ranges_cartesian_product
8874#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8875 template<input_range _Vp>
8877 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8879 _Vp _M_base = _Vp();
8882 as_rvalue_view() requires default_initializable<_Vp> = default;
8885 as_rvalue_view(_Vp __base)
8886 : _M_base(std::move(__base))
8890 base() const& requires copy_constructible<_Vp>
8895 { return std::move(_M_base); }
8898 begin() requires (!__detail::__simple_view<_Vp>)
8899 { return move_iterator(ranges::begin(_M_base)); }
8902 begin() const requires range<const _Vp>
8903 { return move_iterator(ranges::begin(_M_base)); }
8906 end() requires (!__detail::__simple_view<_Vp>)
8908 if constexpr (common_range<_Vp>)
8909 return move_iterator(ranges::end(_M_base));
8911 return move_sentinel(ranges::end(_M_base));
8915 end() const requires range<const _Vp>
8917 if constexpr (common_range<const _Vp>)
8918 return move_iterator(ranges::end(_M_base));
8920 return move_sentinel(ranges::end(_M_base));
8924 size() requires sized_range<_Vp>
8925 { return ranges::size(_M_base); }
8928 size() const requires sized_range<const _Vp>
8929 { return ranges::size(_M_base); }
8932 template<typename _Range>
8933 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8935 template<typename _Tp>
8936 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8937 = enable_borrowed_range<_Tp>;
8943 template<typename _Tp>
8944 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8947 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8949 template<viewable_range _Range>
8950 requires __detail::__can_as_rvalue_view<_Range>
8952 operator() [[nodiscard]] (_Range&& __r) const
8954 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8955 range_reference_t<_Range>>)
8956 return views::all(std::forward<_Range>(__r));
8958 return as_rvalue_view(std::forward<_Range>(__r));
8962 inline constexpr _AsRvalue as_rvalue;
8964#endif // __cpp_lib_as_rvalue
8966#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8969 template<typename _Range>
8970 concept __range_with_movable_reference = input_range<_Range>
8971 && move_constructible<range_reference_t<_Range>>
8972 && move_constructible<range_rvalue_reference_t<_Range>>;
8976 requires __detail::__range_with_movable_reference<_Vp>
8977 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8979 _Vp _M_base = _Vp();
8981 template<bool _Const> class _Iterator;
8982 template<bool _Const> class _Sentinel;
8985 enumerate_view() requires default_initializable<_Vp> = default;
8988 enumerate_view(_Vp __base)
8989 : _M_base(std::move(__base))
8993 begin() requires (!__detail::__simple_view<_Vp>)
8994 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8997 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8998 { return _Iterator<true>(ranges::begin(_M_base), 0); }
9001 end() requires (!__detail::__simple_view<_Vp>)
9003 if constexpr (common_range<_Vp> && sized_range<_Vp>)
9004 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
9006 return _Sentinel<false>(ranges::end(_M_base));
9010 end() const requires __detail::__range_with_movable_reference<const _Vp>
9012 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9013 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9015 return _Sentinel<true>(ranges::end(_M_base));
9019 size() requires sized_range<_Vp>
9020 { return ranges::size(_M_base); }
9023 size() const requires sized_range<const _Vp>
9024 { return ranges::size(_M_base); }
9027 base() const & requires copy_constructible<_Vp>
9032 { return std::move(_M_base); }
9035 template<typename _Range>
9036 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9038 template<typename _Tp>
9039 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9040 = enable_borrowed_range<_Tp>;
9043 requires __detail::__range_with_movable_reference<_Vp>
9044 template<bool _Const>
9045 class enumerate_view<_Vp>::_Iterator
9047 using _Base = __maybe_const_t<_Const, _Vp>;
9052 if constexpr (random_access_range<_Base>)
9053 return random_access_iterator_tag{};
9054 else if constexpr (bidirectional_range<_Base>)
9055 return bidirectional_iterator_tag{};
9056 else if constexpr (forward_range<_Base>)
9057 return forward_iterator_tag{};
9059 return input_iterator_tag{};
9062 friend enumerate_view;
9065 using iterator_category = input_iterator_tag;
9066 using iterator_concept = decltype(_S_iter_concept());
9067 using difference_type = range_difference_t<_Base>;
9068 using value_type = tuple<difference_type, range_value_t<_Base>>;
9071 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9073 iterator_t<_Base> _M_current = iterator_t<_Base>();
9074 difference_type _M_pos = 0;
9077 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9078 : _M_current(std::move(__current)), _M_pos(__pos)
9082 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
9085 _Iterator(_Iterator<!_Const> __i)
9086 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9087 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9090 constexpr const iterator_t<_Base> &
9091 base() const & noexcept
9092 { return _M_current; }
9094 constexpr iterator_t<_Base>
9096 { return std::move(_M_current); }
9098 constexpr difference_type
9099 index() const noexcept
9104 { return __reference_type(_M_pos, *_M_current); }
9106 constexpr _Iterator&
9119 operator++(int) requires forward_range<_Base>
9126 constexpr _Iterator&
9127 operator--() requires bidirectional_range<_Base>
9135 operator--(int) requires bidirectional_range<_Base>
9142 constexpr _Iterator&
9143 operator+=(difference_type __n) requires random_access_range<_Base>
9150 constexpr _Iterator&
9151 operator-=(difference_type __n) requires random_access_range<_Base>
9159 operator[](difference_type __n) const requires random_access_range<_Base>
9160 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9162 friend constexpr bool
9163 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9164 { return __x._M_pos == __y._M_pos; }
9166 friend constexpr strong_ordering
9167 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9168 { return __x._M_pos <=> __y._M_pos; }
9170 friend constexpr _Iterator
9171 operator+(const _Iterator& __x, difference_type __y)
9172 requires random_access_range<_Base>
9173 { return (auto(__x) += __y); }
9175 friend constexpr _Iterator
9176 operator+(difference_type __x, const _Iterator& __y)
9177 requires random_access_range<_Base>
9178 { return auto(__y) += __x; }
9180 friend constexpr _Iterator
9181 operator-(const _Iterator& __x, difference_type __y)
9182 requires random_access_range<_Base>
9183 { return auto(__x) -= __y; }
9185 friend constexpr difference_type
9186 operator-(const _Iterator& __x, const _Iterator& __y) noexcept
9187 { return __x._M_pos - __y._M_pos; }
9189 friend constexpr auto
9190 iter_move(const _Iterator& __i)
9191 noexcept(noexcept(ranges::iter_move(__i._M_current))
9192 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9194 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9195 (__i._M_pos, ranges::iter_move(__i._M_current));
9200 requires __detail::__range_with_movable_reference<_Vp>
9201 template<bool _Const>
9202 class enumerate_view<_Vp>::_Sentinel
9204 using _Base = __maybe_const_t<_Const, _Vp>;
9206 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9209 _Sentinel(sentinel_t<_Base> __end)
9210 : _M_end(std::move(__end))
9213 friend enumerate_view;
9216 _Sentinel() = default;
9219 _Sentinel(_Sentinel<!_Const> __other)
9220 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9221 : _M_end(std::move(__other._M_end))
9224 constexpr sentinel_t<_Base>
9228 template<bool _OtherConst>
9229 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9230 friend constexpr bool
9231 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9232 { return __x._M_current == __y._M_end; }
9234 template<bool _OtherConst>
9235 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9236 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9237 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9238 { return __x._M_current - __y._M_end; }
9240 template<bool _OtherConst>
9241 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9242 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9243 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9244 { return __x._M_end - __y._M_current; }
9251 template<typename _Tp>
9252 concept __can_enumerate_view
9253 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9256 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9258 template<viewable_range _Range>
9259 requires __detail::__can_enumerate_view<_Range>
9261 operator() [[nodiscard]] (_Range&& __r) const
9262 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9265 inline constexpr _Enumerate enumerate;
9267#endif // __cpp_lib_ranges_enumerate
9269#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9271 requires input_range<_Vp>
9272 class as_const_view : public view_interface<as_const_view<_Vp>>
9274 _Vp _M_base = _Vp();
9277 as_const_view() requires default_initializable<_Vp> = default;
9280 as_const_view(_Vp __base)
9281 noexcept(is_nothrow_move_constructible_v<_Vp>)
9282 : _M_base(std::move(__base))
9287 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9288 requires copy_constructible<_Vp>
9293 noexcept(is_nothrow_move_constructible_v<_Vp>)
9294 { return std::move(_M_base); }
9297 begin() requires (!__detail::__simple_view<_Vp>)
9298 { return ranges::cbegin(_M_base); }
9301 begin() const requires range<const _Vp>
9302 { return ranges::cbegin(_M_base); }
9305 end() requires (!__detail::__simple_view<_Vp>)
9306 { return ranges::cend(_M_base); }
9309 end() const requires range<const _Vp>
9310 { return ranges::cend(_M_base); }
9313 size() requires sized_range<_Vp>
9314 { return ranges::size(_M_base); }
9317 size() const requires sized_range<const _Vp>
9318 { return ranges::size(_M_base); }
9321 template<typename _Range>
9322 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9324 template<typename _Tp>
9325 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9326 = enable_borrowed_range<_Tp>;
9332 template<typename _Tp>
9333 inline constexpr bool __is_constable_ref_view = false;
9335 template<typename _Range>
9336 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9337 = constant_range<const _Range>;
9339 template<typename _Range>
9340 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9343 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9345 template<viewable_range _Range>
9347 operator()(_Range&& __r) const
9348 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9349 requires __detail::__can_as_const_view<_Range>
9351 using _Tp = remove_cvref_t<_Range>;
9352 using element_type = remove_reference_t<range_reference_t<_Range>>;
9353 if constexpr (constant_range<views::all_t<_Range>>)
9354 return views::all(std::forward<_Range>(__r));
9355 else if constexpr (__detail::__is_empty_view<_Tp>)
9356 return views::empty<const element_type>;
9357 else if constexpr (std::__detail::__is_span<_Tp>)
9358 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9359 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9360 return ref_view(std::as_const(std::forward<_Range>(__r).base()));
9361 else if constexpr (is_lvalue_reference_v<_Range>
9362 && constant_range<const _Tp>
9364 return ref_view(static_cast<const _Tp&>(__r));
9366 return as_const_view(std::forward<_Range>(__r));
9370 inline constexpr _AsConst as_const;
9372#endif // __cpp_lib_as_const
9373} // namespace ranges
9375 namespace views = ranges::views;
9377#if __cpp_lib_ranges_to_container // C++ >= 23
9380/// @cond undocumented
9383 template<typename _Container>
9384 constexpr bool __reservable_container
9385 = sized_range<_Container>
9386 && requires(_Container& __c, range_size_t<_Container> __n) {
9388 { __c.capacity() } -> same_as<decltype(__n)>;
9389 { __c.max_size() } -> same_as<decltype(__n)>;
9392 template<typename _Cont, typename _Range>
9393 constexpr bool __toable = requires {
9394 requires (!input_range<_Cont>
9395 || convertible_to<range_reference_t<_Range>,
9396 range_value_t<_Cont>>);
9398} // namespace __detail
9401 /// Convert a range to a container.
9403 * @tparam _Cont A container type.
9404 * @param __r A range that models the `input_range` concept.
9405 * @param __args... Arguments to pass to the container constructor.
9408 * This function converts a range to the `_Cont` type.
9410 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9411 * will convert the view to `std::vector<int>`.
9413 * Additional constructor arguments for the container can be supplied after
9414 * the input range argument, e.g.
9415 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9417 template<typename _Cont, input_range _Rg, typename... _Args>
9418 requires (!view<_Cont>)
9420 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9422 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9423 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9425 if constexpr (__detail::__toable<_Cont, _Rg>)
9427 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9428 return _Cont(std::forward<_Rg>(__r),
9429 std::forward<_Args>(__args)...);
9430 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9431 return _Cont(from_range, std::forward<_Rg>(__r),
9432 std::forward<_Args>(__args)...);
9433 else if constexpr (requires { requires common_range<_Rg>;
9434 typename __iter_category_t<iterator_t<_Rg>>;
9435 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9436 input_iterator_tag>;
9437 requires constructible_from<_Cont, iterator_t<_Rg>,
9438 sentinel_t<_Rg>, _Args...>;
9440 return _Cont(ranges::begin(__r), ranges::end(__r),
9441 std::forward<_Args>(__args)...);
9444 static_assert(constructible_from<_Cont, _Args...>);
9445 _Cont __c(std::forward<_Args>(__args)...);
9446 if constexpr (sized_range<_Rg>
9447 && __detail::__reservable_container<_Cont>)
9448 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9449 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9450 // 4016. container-insertable checks do not match what
9451 // container-inserter does
9452 auto __it = ranges::begin(__r);
9453 const auto __sent = ranges::end(__r);
9454 while (__it != __sent)
9456 if constexpr (requires { __c.emplace_back(*__it); })
9457 __c.emplace_back(*__it);
9458 else if constexpr (requires { __c.push_back(*__it); })
9459 __c.push_back(*__it);
9460 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9461 __c.emplace(__c.end(), *__it);
9463 __c.insert(__c.end(), *__it);
9471 static_assert(input_range<range_reference_t<_Rg>>);
9472 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9473 // 3984. ranges::to's recursion branch may be ill-formed
9474 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9475 []<typename _Elt>(_Elt&& __elem) {
9476 using _ValT = range_value_t<_Cont>;
9477 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9478 }), std::forward<_Args>(__args)...);
9482/// @cond undocumented
9485 template<typename _Rg>
9488 using iterator_category = input_iterator_tag;
9489 using value_type = range_value_t<_Rg>;
9490 using difference_type = ptrdiff_t;
9491 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9492 using reference = range_reference_t<_Rg>;
9493 reference operator*() const;
9494 pointer operator->() const;
9495 _InputIter& operator++();
9496 _InputIter operator++(int);
9497 bool operator==(const _InputIter&) const;
9500 template<template<typename...> typename _Cont, input_range _Rg,
9503 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9505 template<template<typename...> typename _Cont, input_range _Rg,
9508 = decltype(_Cont(from_range, std::declval<_Rg>(),
9509 std::declval<_Args>()...));
9511 template<template<typename...> typename _Cont, input_range _Rg,
9514 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9515 std::declval<_InputIter<_Rg>>(),
9516 std::declval<_Args>()...));
9518} // namespace __detail
9521 template<template<typename...> typename _Cont, input_range _Rg,
9524 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9526 using __detail::_DeduceExpr1;
9527 using __detail::_DeduceExpr2;
9528 using __detail::_DeduceExpr3;
9529 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9530 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9531 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9532 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9533 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9534 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9535 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9536 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9537 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9539 static_assert(false); // Cannot deduce container specialization.
9542/// @cond undocumented
9545 template<typename _Cont>
9548 template<typename _Range, typename... _Args>
9549 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9550 std::declval<_Args>()...); }
9552 operator()(_Range&& __r, _Args&&... __args) const
9554 return ranges::to<_Cont>(std::forward<_Range>(__r),
9555 std::forward<_Args>(__args)...);
9558} // namespace __detail
9561 /// ranges::to adaptor for converting a range to a container type
9563 * @tparam _Cont A container type.
9564 * @param __args... Arguments to pass to the container constructor.
9567 * This range adaptor returns a range adaptor closure object that converts
9568 * a range to the `_Cont` type.
9570 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9571 * will convert the view to `std::vector<int>`.
9573 * Additional constructor arguments for the container can be supplied, e.g.
9574 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9576 template<typename _Cont, typename... _Args>
9577 requires (!view<_Cont>)
9579 to [[nodiscard]] (_Args&&... __args)
9581 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9582 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9584 using __detail::_To;
9585 using views::__adaptor::_Partial;
9586 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9589/// @cond undocumented
9592 template<template<typename...> typename _Cont>
9595 template<typename _Range, typename... _Args>
9596 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9597 std::declval<_Args>()...); }
9599 operator()(_Range&& __r, _Args&&... __args) const
9601 return ranges::to<_Cont>(std::forward<_Range>(__r),
9602 std::forward<_Args>(__args)...);
9605} // namespace __detail
9608 /// ranges::to adaptor for converting a range to a deduced container type.
9610 * @tparam _Cont A container template.
9611 * @param __args... Arguments to pass to the container constructor.
9614 * This range adaptor returns a range adaptor closure object that converts
9615 * a range to a specialization of the `_Cont` class template. The specific
9616 * specialization of `_Cont` to be used is deduced automatically.
9618 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9619 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9620 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9622 * Additional constructor arguments for the container can be supplied, e.g.
9623 * `r | std::ranges::to<std::vector>(an_allocator)`.
9625 template<template<typename...> typename _Cont, typename... _Args>
9627 to [[nodiscard]] (_Args&&... __args)
9629 using __detail::_To2;
9630 using views::__adaptor::_Partial;
9631 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9634} // namespace ranges
9635#endif // __cpp_lib_ranges_to_container
9637#if __cpp_lib_ranges_concat // C++ >= C++26
9642 template<typename... _Rs>
9643 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9645 template<typename... _Rs>
9646 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9648 template<typename... _Rs>
9649 using __concat_rvalue_reference_t
9650 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9652 template<typename _Ref, typename _RRef, typename _It>
9653 concept __concat_indirectly_readable_impl = requires(const _It __it) {
9654 { *__it } -> convertible_to<_Ref>;
9655 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9658 template<typename... _Rs>
9659 concept __concat_indirectly_readable
9660 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9661 && common_reference_with<__concat_reference_t<_Rs...>&&,
9662 __concat_rvalue_reference_t<_Rs...>&&>
9663 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9664 __concat_value_t<_Rs...> const&>
9665 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9666 __concat_rvalue_reference_t<_Rs...>,
9670 template<typename... _Rs>
9671 concept __concatable = requires {
9672 typename __concat_reference_t<_Rs...>;
9673 typename __concat_value_t<_Rs...>;
9674 typename __concat_rvalue_reference_t<_Rs...>;
9675 } && __concat_indirectly_readable<_Rs...>;
9677 template<bool _Const, typename _Range, typename... _Rs>
9678 struct __all_but_last_common
9680 static inline constexpr bool value
9681 = requires { requires (common_range<__maybe_const_t<_Const, _Range>>
9682 && __all_but_last_common<_Const, _Rs...>::value); };
9685 template<bool _Const, typename _Range>
9686 struct __all_but_last_common<_Const, _Range>
9687 { static inline constexpr bool value = true; };
9689 template<bool _Const, typename... _Rs>
9690 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9691 && __all_but_last_common<_Const, _Rs...>::value;
9693 template<bool _Const, typename... _Rs>
9694 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9695 && __all_but_last_common<_Const, _Rs...>::value;
9697 template<typename _Range, typename... _Rs>
9698 struct __all_but_first_sized
9699 { static inline constexpr bool value = (sized_range<_Rs> && ...); };
9700 } // namespace __detail
9702 template<input_range... _Vs>
9703 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9704 class concat_view : public view_interface<concat_view<_Vs...>>
9706 tuple<_Vs...> _M_views;
9708 template<bool _Const> class _Iterator;
9711 constexpr concat_view() = default;
9714 concat_view(_Vs... __views)
9715 : _M_views(std::move(__views)...)
9718 constexpr _Iterator<false>
9719 begin() requires (!(__detail::__simple_view<_Vs> && ...))
9721 _Iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9722 __it.template _M_satisfy<0>();
9726 constexpr _Iterator<true>
9727 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9729 _Iterator<true> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9730 __it.template _M_satisfy<0>();
9735 end() requires (!(__detail::__simple_view<_Vs> && ...))
9737 constexpr auto __n = sizeof...(_Vs);
9738 if constexpr (__detail::__all_forward<false, _Vs...>
9739 && common_range<_Vs...[__n - 1]>)
9740 return _Iterator<false>(this, in_place_index<__n - 1>,
9741 ranges::end(std::get<__n - 1>(_M_views)));
9743 return default_sentinel;
9747 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9749 constexpr auto __n = sizeof...(_Vs);
9750 if constexpr (__detail::__all_forward<true, _Vs...>
9751 && common_range<const _Vs...[__n - 1]>)
9752 return _Iterator<true>(this, in_place_index<__n - 1>,
9753 ranges::end(std::get<__n - 1>(_M_views)));
9755 return default_sentinel;
9759 size() requires (sized_range<_Vs>&&...)
9761 return std::apply([](auto... __sizes) {
9762 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9763 return (_CT(__sizes) + ...);
9764 }, __detail::__tuple_transform(ranges::size, _M_views));
9768 size() const requires (sized_range<const _Vs>&&...)
9770 return std::apply([](auto... __sizes) {
9771 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9772 return (_CT(__sizes) + ...);
9773 }, __detail::__tuple_transform(ranges::size, _M_views));
9777 template<typename... _Rs>
9778 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9782 template<bool _Const, typename... _Vs>
9783 struct __concat_view_iter_cat
9786 template<bool _Const, typename... _Vs>
9787 requires __detail::__all_forward<_Const, _Vs...>
9788 struct __concat_view_iter_cat<_Const, _Vs...>
9793 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9794 return input_iterator_tag{};
9796 return []<typename... _Cats>(_Cats... __cats) {
9797 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9798 && __concat_is_random_access<_Const, _Vs...>)
9799 return random_access_iterator_tag{};
9800 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9801 && __concat_is_bidirectional<_Const, _Vs...>)
9802 return bidirectional_iterator_tag{};
9803 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9804 return forward_iterator_tag{};
9806 return input_iterator_tag{};
9807 }(typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9808 ::iterator_category{}...);
9813 template<input_range... _Vs>
9814 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9815 template<bool _Const>
9816 class concat_view<_Vs...>::_Iterator
9817 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9822 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9823 return random_access_iterator_tag{};
9824 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9825 return bidirectional_iterator_tag{};
9826 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9827 return forward_iterator_tag{};
9829 return input_iterator_tag{};
9833 friend _Iterator<!_Const>;
9836 // iterator_category defined in __concat_view_iter_cat
9837 using iterator_concept = decltype(_S_iter_concept());
9838 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9839 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9842 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9844 __maybe_const_t<_Const, concat_view>* _M_parent = nullptr;
9847 template<size_t _Nm>
9851 if constexpr (_Nm < (sizeof...(_Vs) - 1))
9853 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9855 _M_it.template emplace<_Nm + 1>(ranges::begin
9856 (std::get<_Nm + 1>(_M_parent->_M_views)));
9857 _M_satisfy<_Nm + 1>();
9862 template<size_t _Nm>
9866 if constexpr (_Nm == 0)
9867 --std::get<0>(_M_it);
9870 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
9872 _M_it.template emplace<_Nm - 1>(ranges::end
9873 (std::get<_Nm - 1>(_M_parent->_M_views)));
9877 --std::get<_Nm>(_M_it);
9881 template<size_t _Nm>
9883 _M_advance_fwd(difference_type __offset, difference_type __steps)
9885 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9886 if constexpr (_Nm == sizeof...(_Vs) - 1)
9887 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9890 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
9891 if (__offset + __steps < __n_size)
9892 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9895 _M_it.template emplace<_Nm + 1>(ranges::begin
9896 (std::get<_Nm + 1>(_M_parent->_M_views)));
9897 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
9902 template<size_t _Nm>
9904 _M_advance_bwd(difference_type __offset, difference_type __steps)
9906 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9907 if constexpr (_Nm == 0)
9908 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9910 if (__offset >= __steps)
9911 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9914 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
9915 _M_it.template emplace<_Nm - 1>(ranges::end
9916 (std::get<_Nm - 1>(_M_parent->_M_views)));
9917 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
9922 // Invoke the function object __f, which has a call operator with a size_t
9923 // template parameter (corresponding to an index into the pack of views),
9924 // using the runtime value of __index as the template argument.
9925 template<typename _Fp>
9926 static constexpr auto
9927 _S_invoke_with_runtime_index(_Fp&& __f, size_t __index)
9929 return [&__f, __index]<size_t _Idx>(this auto&& __self) {
9930 if (_Idx == __index)
9931 return __f.template operator()<_Idx>();
9932 if constexpr (_Idx + 1 < sizeof...(_Vs))
9933 return __self.template operator()<_Idx + 1>();
9934 __builtin_unreachable();
9935 }.template operator()<0>();
9938 template<typename _Fp>
9940 _M_invoke_with_runtime_index(_Fp&& __f)
9941 { return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); }
9943 template<typename... _Args>
9945 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
9946 requires constructible_from<__base_iter, _Args&&...>
9947 : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...)
9951 _Iterator() = default;
9954 _Iterator(_Iterator<!_Const> __it)
9955 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
9956 : _M_parent(__it._M_parent),
9957 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
9958 return __base_iter(in_place_index<_Idx>,
9959 std::get<_Idx>(std::move(__it._M_it)));
9960 }, __it._M_it.index()))
9963 constexpr decltype(auto)
9966 __glibcxx_assert(!_M_it.valueless_by_exception());
9967 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
9968 return std::visit([](auto&& __it) -> reference { return *__it; }, _M_it);
9971 constexpr _Iterator&
9974 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9975 ++std::get<_Idx>(_M_it);
9987 requires __detail::__all_forward<_Const, _Vs...>
9994 constexpr _Iterator&
9996 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9998 __glibcxx_assert(!_M_it.valueless_by_exception());
9999 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
10005 constexpr _Iterator
10007 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10009 auto __tmp = *this;
10014 constexpr _Iterator&
10015 operator+=(difference_type __n)
10016 requires __detail::__concat_is_random_access<_Const, _Vs...>
10018 __glibcxx_assert(!_M_it.valueless_by_exception());
10019 _M_invoke_with_runtime_index([this, __n]<size_t _Idx>() {
10020 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10022 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10024 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10029 constexpr _Iterator&
10030 operator-=(difference_type __n)
10031 requires __detail::__concat_is_random_access<_Const, _Vs...>
10037 constexpr decltype(auto)
10038 operator[](difference_type __n) const
10039 requires __detail::__concat_is_random_access<_Const, _Vs...>
10040 { return *((*this) + __n); }
10042 friend constexpr bool
10043 operator==(const _Iterator& __x, const _Iterator& __y)
10044 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10046 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10047 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10048 return __x._M_it == __y._M_it;
10051 friend constexpr bool
10052 operator==(const _Iterator& __it, default_sentinel_t)
10054 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10055 constexpr auto __last_idx = sizeof...(_Vs) - 1;
10056 return (__it._M_it.index() == __last_idx
10057 && (std::get<__last_idx>(__it._M_it)
10058 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10061 friend constexpr bool
10062 operator<(const _Iterator& __x, const _Iterator& __y)
10063 requires __detail::__all_random_access<_Const, _Vs...>
10064 { return __x._M_it < __y._M_it; }
10066 friend constexpr bool
10067 operator>(const _Iterator& __x, const _Iterator& __y)
10068 requires __detail::__all_random_access<_Const, _Vs...>
10069 { return __x._M_it > __y._M_it; }
10071 friend constexpr bool
10072 operator<=(const _Iterator& __x, const _Iterator& __y)
10073 requires __detail::__all_random_access<_Const, _Vs...>
10074 { return __x._M_it <= __y._M_it; }
10076 friend constexpr bool
10077 operator>=(const _Iterator& __x, const _Iterator& __y)
10078 requires __detail::__all_random_access<_Const, _Vs...>
10079 { return __x._M_it >= __y._M_it; }
10081 friend constexpr auto
10082 operator<=>(const _Iterator& __x, const _Iterator& __y)
10083 requires __detail::__all_random_access<_Const, _Vs...>
10084 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10085 { return __x._M_it <=> __y._M_it; }
10087 friend constexpr _Iterator
10088 operator+(const _Iterator& __it, difference_type __n)
10089 requires __detail::__concat_is_random_access<_Const, _Vs...>
10090 { return auto(__it) += __n; }
10092 friend constexpr _Iterator
10093 operator+(difference_type __n, const _Iterator& __it)
10094 requires __detail::__concat_is_random_access<_Const, _Vs...>
10095 { return __it + __n; }
10097 friend constexpr _Iterator
10098 operator-(const _Iterator& __it, difference_type __n)
10099 requires __detail::__concat_is_random_access<_Const, _Vs...>
10100 { return auto(__it) -= __n; }
10102 friend constexpr difference_type
10103 operator-(const _Iterator& __x, const _Iterator& __y)
10104 requires __detail::__concat_is_random_access<_Const, _Vs...>
10106 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10107 return _S_invoke_with_runtime_index([&]<size_t _Iy>() -> difference_type {
10108 if constexpr (_Ix > _Iy)
10110 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10111 ranges::end(std::get<_Iy>(__y._M_parent
10113 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10115 std::get<_Ix>(__x._M_it));
10116 difference_type __s = 0;
10117 [&]<size_t _Idx = _Iy + 1>(this auto&& __self) {
10118 if constexpr (_Idx < _Ix)
10120 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10121 __self.template operator()<_Idx + 1>();
10124 return __dy + __s + __dx;
10126 else if constexpr (_Ix < _Iy)
10127 return -(__y - __x);
10129 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10130 }, __y._M_it.index());
10131 }, __x._M_it.index());
10134 friend constexpr difference_type
10135 operator-(const _Iterator& __x, default_sentinel_t)
10136 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10137 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10138 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10140 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10141 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10142 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10143 difference_type __s = 0;
10144 [&]<size_t _Idx = _Ix + 1>(this auto&& __self) {
10145 if constexpr (_Idx < sizeof...(_Vs))
10147 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10148 __self.template operator()<_Idx + 1>();
10151 return -(__dx + __s);
10152 }, __x._M_it.index());
10155 friend constexpr difference_type
10156 operator-(default_sentinel_t, const _Iterator& __x)
10157 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10158 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10159 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10160 { return -(__x - default_sentinel); }
10162 friend constexpr decltype(auto)
10163 iter_move(const _Iterator& __it)
10165 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10166 return std::visit([](const auto& __i) -> _Res {
10167 return ranges::iter_move(__i);
10171 friend constexpr void
10172 iter_swap(const _Iterator& __x, const _Iterator& __y)
10173 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10174 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10176 std::visit([&]<typename _Tp, typename _Up>(const _Tp& __it1, const _Up& __it2) {
10177 if constexpr (is_same_v<_Tp, _Up>)
10178 ranges::iter_swap(__it1, __it2);
10180 ranges::swap(*__it1, *__it2);
10181 }, __x._M_it, __y._M_it);
10189 template<typename... _Ts>
10190 concept __can_concat_view = requires { concat_view(std::declval<_Ts>()...); };
10195 template<typename... _Ts>
10196 requires __detail::__can_concat_view<_Ts...>
10198 operator() [[nodiscard]] (_Ts&&... __ts) const
10199 { return concat_view(std::forward<_Ts>(__ts)...); }
10201 template<input_range _Range>
10203 operator() [[nodiscard]] (_Range&& __t) const
10204 { return views::all(std::forward<_Range>(__t)); }
10207 inline constexpr _Concat concat;
10210} // namespace ranges
10211#endif // __cpp_lib_ranges_concat
10213#if __cpp_lib_ranges_cache_latest // C++ >= 26
10216 template<input_range _Vp>
10218 class cache_latest_view : public view_interface<cache_latest_view<_Vp>>
10220 _Vp _M_base = _Vp();
10222 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10223 add_pointer_t<range_reference_t<_Vp>>,
10224 range_reference_t<_Vp>>;
10225 __detail::__non_propagating_cache<__cache_t> _M_cache;
10231 cache_latest_view() requires default_initializable<_Vp> = default;
10234 cache_latest_view(_Vp __base)
10235 : _M_base(std::move(__base))
10239 base() const & requires copy_constructible<_Vp>
10240 { return _M_base; }
10244 { return std::move(_M_base); }
10248 { return _Iterator(*this); }
10252 { return _Sentinel(*this); }
10255 size() requires sized_range<_Vp>
10256 { return ranges::size(_M_base); }
10259 size() const requires sized_range<const _Vp>
10260 { return ranges::size(_M_base); }
10263 template<typename _Range>
10264 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10266 template<input_range _Vp>
10268 class cache_latest_view<_Vp>::_Iterator
10270 cache_latest_view* _M_parent;
10271 iterator_t<_Vp> _M_current;
10274 _Iterator(cache_latest_view& __parent)
10275 : _M_parent(std::__addressof(__parent)),
10276 _M_current(ranges::begin(__parent._M_base))
10279 friend class cache_latest_view;
10282 using difference_type = range_difference_t<_Vp>;
10283 using value_type = range_value_t<_Vp>;
10284 using iterator_concept = input_iterator_tag;
10286 _Iterator(_Iterator&&) = default;
10289 operator=(_Iterator&&) = default;
10291 constexpr iterator_t<_Vp>
10293 { return std::move(_M_current); }
10295 constexpr const iterator_t<_Vp>&
10296 base() const & noexcept
10297 { return _M_current; }
10299 constexpr range_reference_t<_Vp>&
10302 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10304 if (!_M_parent->_M_cache)
10305 _M_parent->_M_cache = std::__addressof(__detail::__as_lvalue(*_M_current));
10306 return **_M_parent->_M_cache;
10310 if (!_M_parent->_M_cache)
10311 _M_parent->_M_cache._M_emplace_deref(_M_current);
10312 return *_M_parent->_M_cache;
10316 constexpr _Iterator&
10319 _M_parent->_M_cache._M_reset();
10328 friend constexpr range_rvalue_reference_t<_Vp>
10329 iter_move(const _Iterator& __i)
10330 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10331 { return ranges::iter_move(__i._M_current); }
10333 friend constexpr void
10334 iter_swap(const _Iterator& __x, const _Iterator& __y)
10335 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10336 requires indirectly_swappable<iterator_t<_Vp>>
10337 { ranges::iter_swap(__x._M_current, __y._M_current); }
10340 template<input_range _Vp>
10342 class cache_latest_view<_Vp>::_Sentinel
10344 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10347 _Sentinel(cache_latest_view& __parent)
10348 : _M_end(ranges::end(__parent._M_base))
10351 friend class cache_latest_view;
10354 _Sentinel() = default;
10356 constexpr sentinel_t<_Vp>
10360 friend constexpr bool
10361 operator==(const _Iterator& __x, const _Sentinel& __y)
10362 { return __x._M_current == __y._M_end; }
10364 friend constexpr range_difference_t<_Vp>
10365 operator-(const _Iterator& __x, const _Sentinel& __y)
10366 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10367 { return __x._M_current - __y._M_end; }
10369 friend constexpr range_difference_t<_Vp>
10370 operator-(const _Sentinel& __x, const _Iterator& __y)
10371 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10372 { return __x._M_end - __y._M_current; }
10379 template<typename _Tp>
10380 concept __can_cache_latest = requires { cache_latest_view(std::declval<_Tp>()); };
10383 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10385 template<viewable_range _Range>
10386 requires __detail::__can_cache_latest<_Range>
10388 operator() [[nodiscard]] (_Range&& __r) const
10389 { return cache_latest_view(std::forward<_Range>(__r)); }
10391 static constexpr bool _S_has_simple_call_op = true;
10394 inline constexpr _CacheLatest cache_latest;
10396} // namespace ranges
10397#endif // __cpp_lib_ranges_cache_latest
10399#if __cpp_lib_ranges_to_input // C++ >= 26
10402 template<input_range _Vp>
10404 class to_input_view : public view_interface<to_input_view<_Vp>>
10406 _Vp _M_base = _Vp();
10408 template<bool _Const>
10412 to_input_view() requires default_initializable<_Vp> = default;
10415 to_input_view(_Vp __base)
10416 : _M_base(std::move(__base))
10420 base() const & requires copy_constructible<_Vp>
10421 { return _M_base; }
10425 { return std::move(_M_base); }
10428 begin() requires (!__detail::__simple_view<_Vp>)
10429 { return _Iterator<false>(ranges::begin(_M_base)); }
10432 begin() const requires range<const _Vp>
10433 { return _Iterator<true>(ranges::begin(_M_base)); }
10436 end() requires (!__detail::__simple_view<_Vp>)
10437 { return ranges::end(_M_base); }
10440 end() const requires range<const _Vp>
10441 { return ranges::end(_M_base); }
10444 size() requires sized_range<_Vp>
10445 { return ranges::size(_M_base); }
10448 size() const requires sized_range<const _Vp>
10449 { return ranges::size(_M_base); }
10452 template<typename _Range>
10453 to_input_view(_Range&&) -> to_input_view<views::all_t<_Range>>;
10455 template<input_range _Vp>
10457 template<bool _Const>
10458 class to_input_view<_Vp>::_Iterator
10460 using _Base = __maybe_const_t<_Const, _Vp>;
10462 iterator_t<_Base> _M_current = iterator_t<_Base>();
10465 _Iterator(iterator_t<_Base> __current)
10466 : _M_current(std::move(__current))
10469 friend to_input_view;
10470 friend _Iterator<!_Const>;
10473 using difference_type = range_difference_t<_Base>;
10474 using value_type = range_value_t<_Base>;
10475 using iterator_concept = input_iterator_tag;
10477 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
10479 _Iterator(_Iterator&&) = default;
10480 _Iterator& operator=(_Iterator&&) = default;
10483 _Iterator(_Iterator<!_Const> __i)
10484 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10485 : _M_current(std::move(__i._M_current))
10488 constexpr iterator_t<_Base>
10490 { return std::move(_M_current); }
10492 constexpr const iterator_t<_Base>&
10493 base() const & noexcept
10494 { return _M_current; }
10496 constexpr decltype(auto)
10498 { return *_M_current; }
10500 constexpr _Iterator&
10511 friend constexpr bool
10512 operator==(const _Iterator& __x, const sentinel_t<_Base>& __y)
10513 { return __x._M_current == __y; }
10515 friend constexpr difference_type
10516 operator-(const sentinel_t<_Base>& __y, const _Iterator& __x)
10517 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10518 { return __y - __x._M_current; }
10520 friend constexpr difference_type
10521 operator-(const _Iterator& __x, const sentinel_t<_Base>& __y)
10522 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10523 { return __x._M_current - __y; }
10525 friend constexpr range_rvalue_reference_t<_Base>
10526 iter_move(const _Iterator& __i)
10527 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10528 { return ranges::iter_move(__i._M_current); }
10530 friend constexpr void
10531 iter_swap(const _Iterator& __x, const _Iterator& __y)
10532 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10533 requires indirectly_swappable<iterator_t<_Base>>
10534 { ranges::iter_swap(__x._M_current, __y._M_current); }
10541 template<typename _Tp>
10542 concept __can_to_input = requires { to_input_view(std::declval<_Tp>()); };
10545 struct _ToInput : __adaptor::_RangeAdaptorClosure<_ToInput>
10547 template<viewable_range _Range>
10548 requires __detail::__can_to_input<_Range>
10550 operator() [[nodiscard]] (_Range&& __r) const
10552 if constexpr (input_range<_Range>
10553 && !common_range<_Range>
10554 && !forward_range<_Range>)
10555 return views::all(std::forward<_Range>(__r));
10557 return to_input_view(std::forward<_Range>(__r));
10560 static constexpr bool _S_has_simple_call_op = true;
10563 inline constexpr _ToInput to_input;
10565} // namespace ranges
10566#endif // __cpp_lib_ranges_to_input
10568_GLIBCXX_END_NAMESPACE_VERSION
10570#endif // library concepts
10572#endif /* _GLIBCXX_RANGES */