3// Copyright (C) 2019-2024 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
35#pragma GCC system_header
42#include <initializer_list>
48#if __cplusplus > 202002L
51#include <bits/ranges_util.h>
52#include <bits/refwrap.h>
54#define __glibcxx_want_ranges
55#define __glibcxx_want_ranges_as_const
56#define __glibcxx_want_ranges_as_rvalue
57#define __glibcxx_want_ranges_cartesian_product
58#define __glibcxx_want_ranges_chunk
59#define __glibcxx_want_ranges_chunk_by
60#define __glibcxx_want_ranges_enumerate
61#define __glibcxx_want_ranges_iota
62#define __glibcxx_want_ranges_join_with
63#define __glibcxx_want_ranges_repeat
64#define __glibcxx_want_ranges_slide
65#define __glibcxx_want_ranges_stride
66#define __glibcxx_want_ranges_to_container
67#define __glibcxx_want_ranges_zip
68#include <bits/version.h>
70#ifdef __glibcxx_generator // C++ >= 23 && __glibcxx_coroutine
71# include <bits/elements_of.h>
75 * @defgroup ranges Ranges
77 * Components for dealing with ranges of elements.
80namespace std _GLIBCXX_VISIBILITY(default)
82_GLIBCXX_BEGIN_NAMESPACE_VERSION
85 // [range.access] customization point objects
86 // [range.req] range and view concepts
87 // [range.dangling] dangling iterator handling
88 // Defined in <bits/ranges_base.h>
90 // [view.interface] View interface
91 // [range.subrange] Sub-ranges
92 // Defined in <bits/ranges_util.h>
94 // C++20 24.6 [range.factories] Range factories
96 /// A view that contains no elements.
97 template<typename _Tp> requires is_object_v<_Tp>
99 : public view_interface<empty_view<_Tp>>
102 static constexpr _Tp* begin() noexcept { return nullptr; }
103 static constexpr _Tp* end() noexcept { return nullptr; }
104 static constexpr _Tp* data() noexcept { return nullptr; }
105 static constexpr size_t size() noexcept { return 0; }
106 static constexpr bool empty() noexcept { return true; }
109 template<typename _Tp>
110 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
114#if __cpp_lib_ranges >= 202207L // C++ >= 23
115 // P2494R2 Relaxing range adaptors to allow for move only types
116 template<typename _Tp>
117 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
119 template<typename _Tp>
120 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
123 template<__boxable _Tp>
124 struct __box : std::optional<_Tp>
126 using std::optional<_Tp>::optional;
130 noexcept(is_nothrow_default_constructible_v<_Tp>)
131 requires default_initializable<_Tp>
132 : std::optional<_Tp>{std::in_place}
135 __box(const __box&) = default;
136 __box(__box&&) = default;
138 using std::optional<_Tp>::operator=;
140 // _GLIBCXX_RESOLVE_LIB_DEFECTS
141 // 3477. Simplify constraints for semiregular-box
142 // 3572. copyable-box should be fully constexpr
144 operator=(const __box& __that)
145 noexcept(is_nothrow_copy_constructible_v<_Tp>)
146 requires (!copyable<_Tp>) && copy_constructible<_Tp>
148 if (this != std::__addressof(__that))
151 this->emplace(*__that);
159 operator=(__box&& __that)
160 noexcept(is_nothrow_move_constructible_v<_Tp>)
161 requires (!movable<_Tp>)
163 if (this != std::__addressof(__that))
166 this->emplace(std::move(*__that));
174 template<typename _Tp>
175 concept __boxable_copyable
176 = copy_constructible<_Tp>
177 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
178 && is_nothrow_copy_constructible_v<_Tp>));
179 template<typename _Tp>
180 concept __boxable_movable
181 = (!copy_constructible<_Tp>)
182 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
184 // For types which are already copyable (or since C++23, movable)
185 // this specialization of the box wrapper stores the object directly
186 // without going through std::optional. It provides just the subset of
187 // the primary template's API that we currently use.
188 template<__boxable _Tp>
189 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
193 [[no_unique_address]] _Tp _M_value = _Tp();
196 __box() requires default_initializable<_Tp> = default;
199 __box(const _Tp& __t)
200 noexcept(is_nothrow_copy_constructible_v<_Tp>)
201 requires copy_constructible<_Tp>
207 noexcept(is_nothrow_move_constructible_v<_Tp>)
208 : _M_value(std::move(__t))
211 template<typename... _Args>
212 requires constructible_from<_Tp, _Args...>
214 __box(in_place_t, _Args&&... __args)
215 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
216 : _M_value(std::forward<_Args>(__args)...)
219 __box(const __box&) = default;
220 __box(__box&&) = default;
221 __box& operator=(const __box&) requires copyable<_Tp> = default;
222 __box& operator=(__box&&) requires movable<_Tp> = default;
224 // When _Tp is nothrow_copy_constructible but not copy_assignable,
225 // copy assignment is implemented via destroy-then-copy-construct.
227 operator=(const __box& __that) noexcept
228 requires (!copyable<_Tp>) && copy_constructible<_Tp>
230 static_assert(is_nothrow_copy_constructible_v<_Tp>);
231 if (this != std::__addressof(__that))
234 std::construct_at(std::__addressof(_M_value), *__that);
239 // Likewise for move assignment.
241 operator=(__box&& __that) noexcept
242 requires (!movable<_Tp>)
244 static_assert(is_nothrow_move_constructible_v<_Tp>);
245 if (this != std::__addressof(__that))
248 std::construct_at(std::__addressof(_M_value), std::move(*__that));
254 has_value() const noexcept
258 operator*() & noexcept
262 operator*() const & noexcept
266 operator*() && noexcept
267 { return std::move(_M_value); }
269 constexpr const _Tp&&
270 operator*() const && noexcept
271 { return std::move(_M_value); }
274 operator->() noexcept
275 { return std::__addressof(_M_value); }
278 operator->() const noexcept
279 { return std::__addressof(_M_value); }
281 } // namespace __detail
283 /// A view that contains exactly one element.
284#if __cpp_lib_ranges >= 202207L // C++ >= 23
285 template<move_constructible _Tp>
287 template<copy_constructible _Tp>
289 requires is_object_v<_Tp>
290 class single_view : public view_interface<single_view<_Tp>>
293 single_view() requires default_initializable<_Tp> = default;
296 single_view(const _Tp& __t)
297 noexcept(is_nothrow_copy_constructible_v<_Tp>)
298 requires copy_constructible<_Tp>
303 single_view(_Tp&& __t)
304 noexcept(is_nothrow_move_constructible_v<_Tp>)
305 : _M_value(std::move(__t))
308 // _GLIBCXX_RESOLVE_LIB_DEFECTS
309 // 3428. single_view's in place constructor should be explicit
310 template<typename... _Args>
311 requires constructible_from<_Tp, _Args...>
313 single_view(in_place_t, _Args&&... __args)
314 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
315 : _M_value{in_place, std::forward<_Args>(__args)...}
323 begin() const noexcept
328 { return data() + 1; }
332 { return data() + 1; }
334 // _GLIBCXX_RESOLVE_LIB_DEFECTS
335 // 4035. single_view should provide empty
336 static constexpr bool
340 static constexpr size_t
346 { return _M_value.operator->(); }
349 data() const noexcept
350 { return _M_value.operator->(); }
353 [[no_unique_address]] __detail::__box<_Tp> _M_value;
356 template<typename _Tp>
357 single_view(_Tp) -> single_view<_Tp>;
361 template<typename _Wp>
362 constexpr auto __to_signed_like(_Wp __w) noexcept
364 if constexpr (!integral<_Wp>)
365 return iter_difference_t<_Wp>();
366 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
367 return iter_difference_t<_Wp>(__w);
368 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
369 return ptrdiff_t(__w);
370 else if constexpr (sizeof(long long) > sizeof(_Wp))
371 return (long long)(__w);
372#ifdef __SIZEOF_INT128__
373 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
374 return __int128(__w);
377 return __max_diff_type(__w);
380 template<typename _Wp>
381 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
383 template<typename _It>
384 concept __decrementable = incrementable<_It>
387 { --__i } -> same_as<_It&>;
388 { __i-- } -> same_as<_It>;
391 template<typename _It>
392 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
393 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
395 { __i += __n } -> same_as<_It&>;
396 { __i -= __n } -> same_as<_It&>;
400 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
403 template<typename _Winc>
404 struct __iota_view_iter_cat
407 template<incrementable _Winc>
408 struct __iota_view_iter_cat<_Winc>
409 { using iterator_category = input_iterator_tag; };
410 } // namespace __detail
412 template<weakly_incrementable _Winc,
413 semiregular _Bound = unreachable_sentinel_t>
414 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
416 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
421 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
427 using namespace __detail;
428 if constexpr (__advanceable<_Winc>)
429 return random_access_iterator_tag{};
430 else if constexpr (__decrementable<_Winc>)
431 return bidirectional_iterator_tag{};
432 else if constexpr (incrementable<_Winc>)
433 return forward_iterator_tag{};
435 return input_iterator_tag{};
439 using iterator_concept = decltype(_S_iter_concept());
440 // iterator_category defined in __iota_view_iter_cat
441 using value_type = _Winc;
442 using difference_type = __detail::__iota_diff_t<_Winc>;
444 _Iterator() requires default_initializable<_Winc> = default;
447 _Iterator(_Winc __value)
448 : _M_value(__value) { }
451 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
466 operator++(int) requires incrementable<_Winc>
474 operator--() requires __detail::__decrementable<_Winc>
481 operator--(int) requires __detail::__decrementable<_Winc>
489 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
491 using __detail::__is_integer_like;
492 using __detail::__is_signed_integer_like;
493 if constexpr (__is_integer_like<_Winc>
494 && !__is_signed_integer_like<_Winc>)
496 if (__n >= difference_type(0))
497 _M_value += static_cast<_Winc>(__n);
499 _M_value -= static_cast<_Winc>(-__n);
507 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
509 using __detail::__is_integer_like;
510 using __detail::__is_signed_integer_like;
511 if constexpr (__is_integer_like<_Winc>
512 && !__is_signed_integer_like<_Winc>)
514 if (__n >= difference_type(0))
515 _M_value -= static_cast<_Winc>(__n);
517 _M_value += static_cast<_Winc>(-__n);
525 operator[](difference_type __n) const
526 requires __detail::__advanceable<_Winc>
527 { return _Winc(_M_value + __n); }
529 friend constexpr bool
530 operator==(const _Iterator& __x, const _Iterator& __y)
531 requires equality_comparable<_Winc>
532 { return __x._M_value == __y._M_value; }
534 friend constexpr bool
535 operator<(const _Iterator& __x, const _Iterator& __y)
536 requires totally_ordered<_Winc>
537 { return __x._M_value < __y._M_value; }
539 friend constexpr bool
540 operator>(const _Iterator& __x, const _Iterator& __y)
541 requires totally_ordered<_Winc>
542 { return __y < __x; }
544 friend constexpr bool
545 operator<=(const _Iterator& __x, const _Iterator& __y)
546 requires totally_ordered<_Winc>
547 { return !(__y < __x); }
549 friend constexpr bool
550 operator>=(const _Iterator& __x, const _Iterator& __y)
551 requires totally_ordered<_Winc>
552 { return !(__x < __y); }
554#ifdef __cpp_lib_three_way_comparison
555 friend constexpr auto
556 operator<=>(const _Iterator& __x, const _Iterator& __y)
557 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
558 { return __x._M_value <=> __y._M_value; }
561 friend constexpr _Iterator
562 operator+(_Iterator __i, difference_type __n)
563 requires __detail::__advanceable<_Winc>
569 friend constexpr _Iterator
570 operator+(difference_type __n, _Iterator __i)
571 requires __detail::__advanceable<_Winc>
572 { return __i += __n; }
574 friend constexpr _Iterator
575 operator-(_Iterator __i, difference_type __n)
576 requires __detail::__advanceable<_Winc>
582 friend constexpr difference_type
583 operator-(const _Iterator& __x, const _Iterator& __y)
584 requires __detail::__advanceable<_Winc>
586 using __detail::__is_integer_like;
587 using __detail::__is_signed_integer_like;
588 using _Dt = difference_type;
589 if constexpr (__is_integer_like<_Winc>)
591 if constexpr (__is_signed_integer_like<_Winc>)
592 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
594 return (__y._M_value > __x._M_value)
595 ? _Dt(-_Dt(__y._M_value - __x._M_value))
596 : _Dt(__x._M_value - __y._M_value);
599 return __x._M_value - __y._M_value;
603 _Winc _M_value = _Winc();
613 _M_equal(const _Iterator& __x) const
614 { return __x._M_value == _M_bound; }
617 _M_distance_from(const _Iterator& __x) const
618 { return _M_bound - __x._M_value; }
620 _Bound _M_bound = _Bound();
623 _Sentinel() = default;
626 _Sentinel(_Bound __bound)
627 : _M_bound(__bound) { }
629 friend constexpr bool
630 operator==(const _Iterator& __x, const _Sentinel& __y)
631 { return __y._M_equal(__x); }
633 friend constexpr iter_difference_t<_Winc>
634 operator-(const _Iterator& __x, const _Sentinel& __y)
635 requires sized_sentinel_for<_Bound, _Winc>
636 { return -__y._M_distance_from(__x); }
638 friend constexpr iter_difference_t<_Winc>
639 operator-(const _Sentinel& __x, const _Iterator& __y)
640 requires sized_sentinel_for<_Bound, _Winc>
641 { return __x._M_distance_from(__y); }
646 _Winc _M_value = _Winc();
647 [[no_unique_address]] _Bound _M_bound = _Bound();
650 iota_view() requires default_initializable<_Winc> = default;
653 iota_view(_Winc __value)
658 iota_view(type_identity_t<_Winc> __value,
659 type_identity_t<_Bound> __bound)
660 : _M_value(__value), _M_bound(__bound)
662 if constexpr (totally_ordered_with<_Winc, _Bound>)
663 __glibcxx_assert( bool(__value <= __bound) );
667 iota_view(_Iterator __first, _Iterator __last)
668 requires same_as<_Winc, _Bound>
669 : iota_view(__first._M_value, __last._M_value)
673 iota_view(_Iterator __first, unreachable_sentinel_t __last)
674 requires same_as<_Bound, unreachable_sentinel_t>
675 : iota_view(__first._M_value, __last)
679 iota_view(_Iterator __first, _Sentinel __last)
680 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
681 : iota_view(__first._M_value, __last._M_bound)
685 begin() const { return _Iterator{_M_value}; }
690 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
691 return unreachable_sentinel;
693 return _Sentinel{_M_bound};
697 end() const requires same_as<_Winc, _Bound>
698 { return _Iterator{_M_bound}; }
700 // _GLIBCXX_RESOLVE_LIB_DEFECTS
701 // 4001. iota_view should provide empty
704 { return _M_value == _M_bound; }
708 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
709 || (integral<_Winc> && integral<_Bound>)
710 || sized_sentinel_for<_Bound, _Winc>
712 using __detail::__is_integer_like;
713 using __detail::__to_unsigned_like;
714 if constexpr (integral<_Winc> && integral<_Bound>)
716 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
717 return _Up(_M_bound) - _Up(_M_value);
719 else if constexpr (__is_integer_like<_Winc>)
720 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
722 return __to_unsigned_like(_M_bound - _M_value);
726 template<typename _Winc, typename _Bound>
727 requires (!__detail::__is_integer_like<_Winc>
728 || !__detail::__is_integer_like<_Bound>
729 || (__detail::__is_signed_integer_like<_Winc>
730 == __detail::__is_signed_integer_like<_Bound>))
731 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
733 template<typename _Winc, typename _Bound>
734 inline constexpr bool
735 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
739 template<typename _Tp>
740 inline constexpr empty_view<_Tp> empty{};
744 template<typename _Tp>
745 concept __can_single_view
746 = requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
747 } // namespace __detail
751 template<__detail::__can_single_view _Tp>
753 operator() [[nodiscard]] (_Tp&& __e) const
754 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
755 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
758 inline constexpr _Single single{};
762 template<typename... _Args>
763 concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); };
764 } // namespace __detail
768 template<__detail::__can_iota_view _Tp>
770 operator() [[nodiscard]] (_Tp&& __e) const
771 { return iota_view(std::forward<_Tp>(__e)); }
773 template<typename _Tp, typename _Up>
774 requires __detail::__can_iota_view<_Tp, _Up>
776 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const
777 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
780 inline constexpr _Iota iota{};
786 template<typename _Val, typename _CharT, typename _Traits>
787 concept __stream_extractable
788 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
789 } // namespace __detail
791 template<movable _Val, typename _CharT,
792 typename _Traits = char_traits<_CharT>>
793 requires default_initializable<_Val>
794 && __detail::__stream_extractable<_Val, _CharT, _Traits>
795 class basic_istream_view
796 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
800 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
801 : _M_stream(std::__addressof(__stream))
807 *_M_stream >> _M_object;
808 return _Iterator{this};
811 constexpr default_sentinel_t
813 { return default_sentinel; }
816 basic_istream<_CharT, _Traits>* _M_stream;
817 _Val _M_object = _Val();
822 using iterator_concept = input_iterator_tag;
823 using difference_type = ptrdiff_t;
824 using value_type = _Val;
827 _Iterator(basic_istream_view* __parent) noexcept
828 : _M_parent(__parent)
831 _Iterator(const _Iterator&) = delete;
832 _Iterator(_Iterator&&) = default;
833 _Iterator& operator=(const _Iterator&) = delete;
834 _Iterator& operator=(_Iterator&&) = default;
839 *_M_parent->_M_stream >> _M_parent->_M_object;
849 { return _M_parent->_M_object; }
852 operator==(const _Iterator& __x, default_sentinel_t)
853 { return __x._M_at_end(); }
856 basic_istream_view* _M_parent;
860 { return !*_M_parent->_M_stream; }
866 template<typename _Val>
867 using istream_view = basic_istream_view<_Val, char>;
869 template<typename _Val>
870 using wistream_view = basic_istream_view<_Val, wchar_t>;
876 template<typename _Tp, typename _Up>
877 concept __can_istream_view = requires (_Up __e) {
878 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
880 } // namespace __detail
882 template<typename _Tp>
885 template<typename _CharT, typename _Traits>
887 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
888 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
889 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
892 template<typename _Tp>
893 inline constexpr _Istream<_Tp> istream;
897 // C++20 24.7 [range.adaptors] Range adaptors
901 template<typename _Tp, int _Disc>
904 // Alias for a type that is conditionally present
905 // (and is an empty type otherwise).
906 // Data members using this alias should use [[no_unique_address]] so that
907 // they take no space when not needed.
908 // The optional template parameter _Disc is for discriminating two otherwise
909 // equivalent absent types so that even they can overlap.
910 template<bool _Present, typename _Tp, int _Disc = 0>
911 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
913 // Alias for a type that is conditionally const.
914 template<bool _Const, typename _Tp>
915 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
917} // namespace __detail
919// Shorthand for __detail::__maybe_const_t.
920using __detail::__maybe_const_t;
922namespace views::__adaptor
924 // True if the range adaptor _Adaptor can be applied with _Args.
925 template<typename _Adaptor, typename... _Args>
926 concept __adaptor_invocable
927 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
929 // True if the range adaptor non-closure _Adaptor can be partially applied
931 template<typename _Adaptor, typename... _Args>
932 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
933 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
934 && (constructible_from<decay_t<_Args>, _Args> && ...);
936 template<typename _Adaptor, typename... _Args>
939 template<typename _Lhs, typename _Rhs>
942 // The base class of every range adaptor closure.
944 // The derived class should define the optional static data member
945 // _S_has_simple_call_op to true if the behavior of this adaptor is
946 // independent of the constness/value category of the adaptor object.
947 template<typename _Derived>
948 struct _RangeAdaptorClosure
951 template<typename _Tp, typename _Up>
952 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
953 void __is_range_adaptor_closure_fn
954 (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined
956 template<typename _Tp>
957 concept __is_range_adaptor_closure
958 = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
960#pragma GCC diagnostic push
961#pragma GCC diagnostic ignored "-Wdangling-reference"
962 // range | adaptor is equivalent to adaptor(range).
963 template<typename _Self, typename _Range>
964 requires __is_range_adaptor_closure<_Self>
965 && __adaptor_invocable<_Self, _Range>
967 operator|(_Range&& __r, _Self&& __self)
968 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
970 // Compose the adaptors __lhs and __rhs into a pipeline, returning
971 // another range adaptor closure object.
972 template<typename _Lhs, typename _Rhs>
973 requires __is_range_adaptor_closure<_Lhs>
974 && __is_range_adaptor_closure<_Rhs>
976 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
978 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
979 std::forward<_Rhs>(__rhs)};
981#pragma GCC diagnostic pop
983 // The base class of every range adaptor non-closure.
985 // The static data member _Derived::_S_arity must contain the total number of
986 // arguments that the adaptor takes, and the class _Derived must introduce
987 // _RangeAdaptor::operator() into the class scope via a using-declaration.
989 // The optional static data member _Derived::_S_has_simple_extra_args should
990 // be defined to true if the behavior of this adaptor is independent of the
991 // constness/value category of the extra arguments. This data member could
992 // also be defined as a variable template parameterized by the types of the
994 template<typename _Derived>
997 // Partially apply the arguments __args to the range adaptor _Derived,
998 // returning a range adaptor closure object.
999 template<typename... _Args>
1000 requires __adaptor_partial_app_viable<_Derived, _Args...>
1002 operator()(_Args&&... __args) const
1004 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
1008 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
1009 // one that's not overloaded according to constness or value category of the
1011 template<typename _Adaptor>
1012 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1014 // True if the behavior of the range adaptor non-closure _Adaptor is
1015 // independent of the value category of its extra arguments _Args.
1016 template<typename _Adaptor, typename... _Args>
1017 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1018 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1020 // A range adaptor closure that represents partial application of
1021 // the range adaptor _Adaptor with arguments _Args.
1022 template<typename _Adaptor, typename... _Args>
1023 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1025 tuple<_Args...> _M_args;
1027 // First parameter is to ensure this constructor is never used
1028 // instead of the copy/move constructor.
1029 template<typename... _Ts>
1031 _Partial(int, _Ts&&... __args)
1032 : _M_args(std::forward<_Ts>(__args)...)
1035 // Invoke _Adaptor with arguments __r, _M_args... according to the
1036 // value category of this _Partial object.
1037#if __cpp_explicit_this_parameter
1038 template<typename _Self, typename _Range>
1039 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1041 operator()(this _Self&& __self, _Range&& __r)
1043 auto __forwarder = [&__r] (auto&&... __args) {
1044 return _Adaptor{}(std::forward<_Range>(__r),
1045 std::forward<decltype(__args)>(__args)...);
1047 return std::apply(__forwarder, __like_t<_Self, _Partial>(__self)._M_args);
1050 template<typename _Range>
1051 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1053 operator()(_Range&& __r) const &
1055 auto __forwarder = [&__r] (const auto&... __args) {
1056 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1058 return std::apply(__forwarder, _M_args);
1061 template<typename _Range>
1062 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1064 operator()(_Range&& __r) &&
1066 auto __forwarder = [&__r] (auto&... __args) {
1067 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
1069 return std::apply(__forwarder, _M_args);
1072 template<typename _Range>
1074 operator()(_Range&& __r) const && = delete;
1078 // A lightweight specialization of the above primary template for
1079 // the common case where _Adaptor accepts a single extra argument.
1080 template<typename _Adaptor, typename _Arg>
1081 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1085 template<typename _Tp>
1087 _Partial(int, _Tp&& __arg)
1088 : _M_arg(std::forward<_Tp>(__arg))
1091#if __cpp_explicit_this_parameter
1092 template<typename _Self, typename _Range>
1093 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Arg>>
1095 operator()(this _Self&& __self, _Range&& __r)
1097 return _Adaptor{}(std::forward<_Range>(__r),
1098 __like_t<_Self, _Partial>(__self)._M_arg);
1101 template<typename _Range>
1102 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1104 operator()(_Range&& __r) const &
1105 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1107 template<typename _Range>
1108 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
1110 operator()(_Range&& __r) &&
1111 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
1113 template<typename _Range>
1115 operator()(_Range&& __r) const && = delete;
1119 // Partial specialization of the primary template for the case where the extra
1120 // arguments of the adaptor can always be safely and efficiently forwarded by
1121 // const reference. This lets us get away with a single operator() overload,
1122 // which makes overload resolution failure diagnostics more concise.
1123 template<typename _Adaptor, typename... _Args>
1124 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1125 && (is_trivially_copyable_v<_Args> && ...)
1126 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1128 tuple<_Args...> _M_args;
1130 template<typename... _Ts>
1132 _Partial(int, _Ts&&... __args)
1133 : _M_args(std::forward<_Ts>(__args)...)
1136 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1137 // of the value category of this _Partial object.
1138 template<typename _Range>
1139 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1141 operator()(_Range&& __r) const
1143 auto __forwarder = [&__r] (const auto&... __args) {
1144 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1146 return std::apply(__forwarder, _M_args);
1149 static constexpr bool _S_has_simple_call_op = true;
1152 // A lightweight specialization of the above template for the common case
1153 // where _Adaptor accepts a single extra argument.
1154 template<typename _Adaptor, typename _Arg>
1155 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1156 && is_trivially_copyable_v<_Arg>
1157 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1161 template<typename _Tp>
1163 _Partial(int, _Tp&& __arg)
1164 : _M_arg(std::forward<_Tp>(__arg))
1167 template<typename _Range>
1168 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1170 operator()(_Range&& __r) const
1171 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1173 static constexpr bool _S_has_simple_call_op = true;
1176 template<typename _Lhs, typename _Rhs, typename _Range>
1177 concept __pipe_invocable
1178 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1180 // A range adaptor closure that represents composition of the range
1181 // adaptor closures _Lhs and _Rhs.
1182 template<typename _Lhs, typename _Rhs>
1183 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1185 [[no_unique_address]] _Lhs _M_lhs;
1186 [[no_unique_address]] _Rhs _M_rhs;
1188 template<typename _Tp, typename _Up>
1190 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1191 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1194 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1195 // range adaptor closure object.
1196#if __cpp_explicit_this_parameter
1197 template<typename _Self, typename _Range>
1198 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1200 operator()(this _Self&& __self, _Range&& __r)
1202 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1203 (__like_t<_Self, _Pipe>(__self)._M_lhs
1204 (std::forward<_Range>(__r))));
1207 template<typename _Range>
1208 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1210 operator()(_Range&& __r) const &
1211 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1213 template<typename _Range>
1214 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1216 operator()(_Range&& __r) &&
1217 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1219 template<typename _Range>
1221 operator()(_Range&& __r) const && = delete;
1225 // A partial specialization of the above primary template for the case where
1226 // both adaptor operands have a simple operator(). This in turn lets us
1227 // implement composition using a single simple operator(), which makes
1228 // overload resolution failure diagnostics more concise.
1229 template<typename _Lhs, typename _Rhs>
1230 requires __closure_has_simple_call_op<_Lhs>
1231 && __closure_has_simple_call_op<_Rhs>
1232 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1234 [[no_unique_address]] _Lhs _M_lhs;
1235 [[no_unique_address]] _Rhs _M_rhs;
1237 template<typename _Tp, typename _Up>
1239 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1240 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1243 template<typename _Range>
1244 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1246 operator()(_Range&& __r) const
1247 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1249 static constexpr bool _S_has_simple_call_op = true;
1251} // namespace views::__adaptor
1253#if __cpp_lib_ranges >= 202202L
1254 // P2387R3 Pipe support for user-defined range adaptors
1255 template<typename _Derived>
1256 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1257 class range_adaptor_closure
1258 : public views::__adaptor::_RangeAdaptorClosure<_Derived>
1262 template<range _Range> requires is_object_v<_Range>
1263 class ref_view : public view_interface<ref_view<_Range>>
1268 static void _S_fun(_Range&); // not defined
1269 static void _S_fun(_Range&&) = delete;
1272 template<__detail::__different_from<ref_view> _Tp>
1273 requires convertible_to<_Tp, _Range&>
1274 && requires { _S_fun(declval<_Tp>()); }
1277 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1278 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1285 constexpr iterator_t<_Range>
1287 { return ranges::begin(*_M_r); }
1289 constexpr sentinel_t<_Range>
1291 { return ranges::end(*_M_r); }
1294 empty() const requires requires { ranges::empty(*_M_r); }
1295 { return ranges::empty(*_M_r); }
1298 size() const requires sized_range<_Range>
1299 { return ranges::size(*_M_r); }
1302 data() const requires contiguous_range<_Range>
1303 { return ranges::data(*_M_r); }
1306 template<typename _Range>
1307 ref_view(_Range&) -> ref_view<_Range>;
1309 template<typename _Tp>
1310 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1312 template<range _Range>
1313 requires movable<_Range>
1314 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1315 class owning_view : public view_interface<owning_view<_Range>>
1318 _Range _M_r = _Range();
1321 owning_view() requires default_initializable<_Range> = default;
1324 owning_view(_Range&& __t)
1325 noexcept(is_nothrow_move_constructible_v<_Range>)
1326 : _M_r(std::move(__t))
1329 owning_view(owning_view&&) = default;
1330 owning_view& operator=(owning_view&&) = default;
1336 constexpr const _Range&
1337 base() const& noexcept
1342 { return std::move(_M_r); }
1344 constexpr const _Range&&
1345 base() const&& noexcept
1346 { return std::move(_M_r); }
1348 constexpr iterator_t<_Range>
1350 { return ranges::begin(_M_r); }
1352 constexpr sentinel_t<_Range>
1354 { return ranges::end(_M_r); }
1357 begin() const requires range<const _Range>
1358 { return ranges::begin(_M_r); }
1361 end() const requires range<const _Range>
1362 { return ranges::end(_M_r); }
1365 empty() requires requires { ranges::empty(_M_r); }
1366 { return ranges::empty(_M_r); }
1369 empty() const requires requires { ranges::empty(_M_r); }
1370 { return ranges::empty(_M_r); }
1373 size() requires sized_range<_Range>
1374 { return ranges::size(_M_r); }
1377 size() const requires sized_range<const _Range>
1378 { return ranges::size(_M_r); }
1381 data() requires contiguous_range<_Range>
1382 { return ranges::data(_M_r); }
1385 data() const requires contiguous_range<const _Range>
1386 { return ranges::data(_M_r); }
1389 template<typename _Tp>
1390 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1391 = enable_borrowed_range<_Tp>;
1397 template<typename _Range>
1398 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1400 template<typename _Range>
1401 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1402 } // namespace __detail
1404 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1406 template<typename _Range>
1407 static constexpr bool
1410 if constexpr (view<decay_t<_Range>>)
1411 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1412 else if constexpr (__detail::__can_ref_view<_Range>)
1415 return noexcept(owning_view{std::declval<_Range>()});
1418 template<viewable_range _Range>
1419 requires view<decay_t<_Range>>
1420 || __detail::__can_ref_view<_Range>
1421 || __detail::__can_owning_view<_Range>
1423 operator() [[nodiscard]] (_Range&& __r) const
1424 noexcept(_S_noexcept<_Range>())
1426 if constexpr (view<decay_t<_Range>>)
1427 return std::forward<_Range>(__r);
1428 else if constexpr (__detail::__can_ref_view<_Range>)
1429 return ref_view{std::forward<_Range>(__r)};
1431 return owning_view{std::forward<_Range>(__r)};
1434 static constexpr bool _S_has_simple_call_op = true;
1437 inline constexpr _All all;
1439 template<viewable_range _Range>
1440 using all_t = decltype(all(std::declval<_Range>()));
1441 } // namespace views
1445 template<typename _Tp>
1446 struct __non_propagating_cache
1448 // When _Tp is not an object type (e.g. is a reference type), we make
1449 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1450 // users can easily conditionally declare data members with this type
1451 // (such as join_view::_M_inner).
1454 template<typename _Tp>
1455 requires is_object_v<_Tp>
1456 struct __non_propagating_cache<_Tp>
1457 : protected _Optional_base<_Tp>
1459 __non_propagating_cache() = default;
1462 __non_propagating_cache(const __non_propagating_cache&) noexcept
1466 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1467 { __other._M_reset(); }
1469 constexpr __non_propagating_cache&
1470 operator=(const __non_propagating_cache& __other) noexcept
1472 if (std::__addressof(__other) != this)
1477 constexpr __non_propagating_cache&
1478 operator=(__non_propagating_cache&& __other) noexcept
1485 constexpr __non_propagating_cache&
1486 operator=(_Tp __val)
1489 this->_M_payload._M_construct(std::move(__val));
1494 operator bool() const noexcept
1495 { return this->_M_is_engaged(); }
1498 operator*() noexcept
1499 { return this->_M_get(); }
1501 constexpr const _Tp&
1502 operator*() const noexcept
1503 { return this->_M_get(); }
1505 template<typename _Iter>
1507 _M_emplace_deref(const _Iter& __i)
1510 auto __f = [] (auto& __x) { return *__x; };
1511 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1512 return this->_M_get();
1516 template<range _Range>
1517 struct _CachedPosition
1520 _M_has_value() const
1523 constexpr iterator_t<_Range>
1524 _M_get(const _Range&) const
1526 __glibcxx_assert(false);
1527 __builtin_unreachable();
1531 _M_set(const _Range&, const iterator_t<_Range>&) const
1535 template<forward_range _Range>
1536 struct _CachedPosition<_Range>
1537 : protected __non_propagating_cache<iterator_t<_Range>>
1540 _M_has_value() const
1541 { return this->_M_is_engaged(); }
1543 constexpr iterator_t<_Range>
1544 _M_get(const _Range&) const
1546 __glibcxx_assert(_M_has_value());
1551 _M_set(const _Range&, const iterator_t<_Range>& __it)
1553 __glibcxx_assert(!_M_has_value());
1554 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1556 this->_M_payload._M_engaged = true;
1560 template<random_access_range _Range>
1561 requires (sizeof(range_difference_t<_Range>)
1562 <= sizeof(iterator_t<_Range>))
1563 struct _CachedPosition<_Range>
1566 range_difference_t<_Range> _M_offset = -1;
1569 _CachedPosition() = default;
1572 _CachedPosition(const _CachedPosition&) = default;
1575 _CachedPosition(_CachedPosition&& __other) noexcept
1576 { *this = std::move(__other); }
1578 constexpr _CachedPosition&
1579 operator=(const _CachedPosition&) = default;
1581 constexpr _CachedPosition&
1582 operator=(_CachedPosition&& __other) noexcept
1584 // Propagate the cached offset, but invalidate the source.
1585 _M_offset = __other._M_offset;
1586 __other._M_offset = -1;
1591 _M_has_value() const
1592 { return _M_offset >= 0; }
1594 constexpr iterator_t<_Range>
1595 _M_get(_Range& __r) const
1597 __glibcxx_assert(_M_has_value());
1598 return ranges::begin(__r) + _M_offset;
1602 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1604 __glibcxx_assert(!_M_has_value());
1605 _M_offset = __it - ranges::begin(__r);
1608 } // namespace __detail
1612 template<typename _Base>
1613 struct __filter_view_iter_cat
1616 template<forward_range _Base>
1617 struct __filter_view_iter_cat<_Base>
1623 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1624 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1625 return bidirectional_iterator_tag{};
1626 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1627 return forward_iterator_tag{};
1632 using iterator_category = decltype(_S_iter_cat());
1634 } // namespace __detail
1636 template<input_range _Vp,
1637 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1638 requires view<_Vp> && is_object_v<_Pred>
1639 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1644 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1647 static constexpr auto
1650 if constexpr (bidirectional_range<_Vp>)
1651 return bidirectional_iterator_tag{};
1652 else if constexpr (forward_range<_Vp>)
1653 return forward_iterator_tag{};
1655 return input_iterator_tag{};
1660 using _Vp_iter = iterator_t<_Vp>;
1662 _Vp_iter _M_current = _Vp_iter();
1663 filter_view* _M_parent = nullptr;
1666 using iterator_concept = decltype(_S_iter_concept());
1667 // iterator_category defined in __filter_view_iter_cat
1668 using value_type = range_value_t<_Vp>;
1669 using difference_type = range_difference_t<_Vp>;
1671 _Iterator() requires default_initializable<_Vp_iter> = default;
1674 _Iterator(filter_view* __parent, _Vp_iter __current)
1675 : _M_current(std::move(__current)),
1679 constexpr const _Vp_iter&
1680 base() const & noexcept
1681 { return _M_current; }
1685 { return std::move(_M_current); }
1687 constexpr range_reference_t<_Vp>
1689 { return *_M_current; }
1693 requires __detail::__has_arrow<_Vp_iter>
1694 && copyable<_Vp_iter>
1695 { return _M_current; }
1697 constexpr _Iterator&
1700 _M_current = ranges::find_if(std::move(++_M_current),
1701 ranges::end(_M_parent->_M_base),
1702 std::ref(*_M_parent->_M_pred));
1711 operator++(int) requires forward_range<_Vp>
1718 constexpr _Iterator&
1719 operator--() requires bidirectional_range<_Vp>
1723 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1728 operator--(int) requires bidirectional_range<_Vp>
1735 friend constexpr bool
1736 operator==(const _Iterator& __x, const _Iterator& __y)
1737 requires equality_comparable<_Vp_iter>
1738 { return __x._M_current == __y._M_current; }
1740 friend constexpr range_rvalue_reference_t<_Vp>
1741 iter_move(const _Iterator& __i)
1742 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1743 { return ranges::iter_move(__i._M_current); }
1745 friend constexpr void
1746 iter_swap(const _Iterator& __x, const _Iterator& __y)
1747 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1748 requires indirectly_swappable<_Vp_iter>
1749 { ranges::iter_swap(__x._M_current, __y._M_current); }
1755 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1758 __equal(const _Iterator& __i) const
1759 { return __i._M_current == _M_end; }
1762 _Sentinel() = default;
1765 _Sentinel(filter_view* __parent)
1766 : _M_end(ranges::end(__parent->_M_base))
1769 constexpr sentinel_t<_Vp>
1773 friend constexpr bool
1774 operator==(const _Iterator& __x, const _Sentinel& __y)
1775 { return __y.__equal(__x); }
1778 _Vp _M_base = _Vp();
1779 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1780 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1783 filter_view() requires (default_initializable<_Vp>
1784 && default_initializable<_Pred>)
1788 filter_view(_Vp __base, _Pred __pred)
1789 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1793 base() const& requires copy_constructible<_Vp>
1798 { return std::move(_M_base); }
1800 constexpr const _Pred&
1802 { return *_M_pred; }
1807 if (_M_cached_begin._M_has_value())
1808 return {this, _M_cached_begin._M_get(_M_base)};
1810 __glibcxx_assert(_M_pred.has_value());
1811 auto __it = ranges::find_if(ranges::begin(_M_base),
1812 ranges::end(_M_base),
1813 std::ref(*_M_pred));
1814 _M_cached_begin._M_set(_M_base, __it);
1815 return {this, std::move(__it)};
1821 if constexpr (common_range<_Vp>)
1822 return _Iterator{this, ranges::end(_M_base)};
1824 return _Sentinel{this};
1828 template<typename _Range, typename _Pred>
1829 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1835 template<typename _Range, typename _Pred>
1836 concept __can_filter_view
1837 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1838 } // namespace __detail
1840 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1842 template<viewable_range _Range, typename _Pred>
1843 requires __detail::__can_filter_view<_Range, _Pred>
1845 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1847 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1850 using _RangeAdaptor<_Filter>::operator();
1851 static constexpr int _S_arity = 2;
1852 static constexpr bool _S_has_simple_extra_args = true;
1855 inline constexpr _Filter filter;
1856 } // namespace views
1858#if __cpp_lib_ranges >= 202207L // C++ >= 23
1859 template<input_range _Vp, move_constructible _Fp>
1861 template<input_range _Vp, copy_constructible _Fp>
1863 requires view<_Vp> && is_object_v<_Fp>
1864 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1865 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1866 range_reference_t<_Vp>>>
1867 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1870 template<bool _Const>
1871 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1873 template<bool _Const>
1877 template<bool _Const>
1878 requires forward_range<_Base<_Const>>
1879 struct __iter_cat<_Const>
1885 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1886 // 3564. transform_view::iterator<true>::value_type and
1887 // iterator_category should use const F&
1888 using _Base = transform_view::_Base<_Const>;
1889 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1890 range_reference_t<_Base>>;
1891 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1892 // 3798. Rvalue reference and iterator_category
1893 if constexpr (is_reference_v<_Res>)
1896 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1897 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1898 return random_access_iterator_tag{};
1903 return input_iterator_tag{};
1906 using iterator_category = decltype(_S_iter_cat());
1909 template<bool _Const>
1912 template<bool _Const>
1913 struct _Iterator : __iter_cat<_Const>
1916 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1917 using _Base = transform_view::_Base<_Const>;
1922 if constexpr (random_access_range<_Base>)
1923 return random_access_iterator_tag{};
1924 else if constexpr (bidirectional_range<_Base>)
1925 return bidirectional_iterator_tag{};
1926 else if constexpr (forward_range<_Base>)
1927 return forward_iterator_tag{};
1929 return input_iterator_tag{};
1932 using _Base_iter = iterator_t<_Base>;
1934 _Base_iter _M_current = _Base_iter();
1935 _Parent* _M_parent = nullptr;
1938 using iterator_concept = decltype(_S_iter_concept());
1939 // iterator_category defined in __transform_view_iter_cat
1941 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1942 range_reference_t<_Base>>>;
1943 using difference_type = range_difference_t<_Base>;
1945 _Iterator() requires default_initializable<_Base_iter> = default;
1948 _Iterator(_Parent* __parent, _Base_iter __current)
1949 : _M_current(std::move(__current)),
1954 _Iterator(_Iterator<!_Const> __i)
1956 && convertible_to<iterator_t<_Vp>, _Base_iter>
1957 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1960 constexpr const _Base_iter&
1961 base() const & noexcept
1962 { return _M_current; }
1964 constexpr _Base_iter
1966 { return std::move(_M_current); }
1968 constexpr decltype(auto)
1970 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1971 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1973 constexpr _Iterator&
1985 operator++(int) requires forward_range<_Base>
1992 constexpr _Iterator&
1993 operator--() requires bidirectional_range<_Base>
2000 operator--(int) requires bidirectional_range<_Base>
2007 constexpr _Iterator&
2008 operator+=(difference_type __n) requires random_access_range<_Base>
2014 constexpr _Iterator&
2015 operator-=(difference_type __n) requires random_access_range<_Base>
2021 constexpr decltype(auto)
2022 operator[](difference_type __n) const
2023 requires random_access_range<_Base>
2024 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
2026 friend constexpr bool
2027 operator==(const _Iterator& __x, const _Iterator& __y)
2028 requires equality_comparable<_Base_iter>
2029 { return __x._M_current == __y._M_current; }
2031 friend constexpr bool
2032 operator<(const _Iterator& __x, const _Iterator& __y)
2033 requires random_access_range<_Base>
2034 { return __x._M_current < __y._M_current; }
2036 friend constexpr bool
2037 operator>(const _Iterator& __x, const _Iterator& __y)
2038 requires random_access_range<_Base>
2039 { return __y < __x; }
2041 friend constexpr bool
2042 operator<=(const _Iterator& __x, const _Iterator& __y)
2043 requires random_access_range<_Base>
2044 { return !(__y < __x); }
2046 friend constexpr bool
2047 operator>=(const _Iterator& __x, const _Iterator& __y)
2048 requires random_access_range<_Base>
2049 { return !(__x < __y); }
2051#ifdef __cpp_lib_three_way_comparison
2052 friend constexpr auto
2053 operator<=>(const _Iterator& __x, const _Iterator& __y)
2054 requires random_access_range<_Base>
2055 && three_way_comparable<_Base_iter>
2056 { return __x._M_current <=> __y._M_current; }
2059 friend constexpr _Iterator
2060 operator+(_Iterator __i, difference_type __n)
2061 requires random_access_range<_Base>
2062 { return {__i._M_parent, __i._M_current + __n}; }
2064 friend constexpr _Iterator
2065 operator+(difference_type __n, _Iterator __i)
2066 requires random_access_range<_Base>
2067 { return {__i._M_parent, __i._M_current + __n}; }
2069 friend constexpr _Iterator
2070 operator-(_Iterator __i, difference_type __n)
2071 requires random_access_range<_Base>
2072 { return {__i._M_parent, __i._M_current - __n}; }
2074 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2075 // 3483. transform_view::iterator's difference is overconstrained
2076 friend constexpr difference_type
2077 operator-(const _Iterator& __x, const _Iterator& __y)
2078 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2079 { return __x._M_current - __y._M_current; }
2081 friend constexpr decltype(auto)
2082 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
2084 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
2085 return std::move(*__i);
2090 friend _Iterator<!_Const>;
2091 template<bool> friend struct _Sentinel;
2094 template<bool _Const>
2098 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2099 using _Base = transform_view::_Base<_Const>;
2101 template<bool _Const2>
2103 __distance_from(const _Iterator<_Const2>& __i) const
2104 { return _M_end - __i._M_current; }
2106 template<bool _Const2>
2108 __equal(const _Iterator<_Const2>& __i) const
2109 { return __i._M_current == _M_end; }
2111 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2114 _Sentinel() = default;
2117 _Sentinel(sentinel_t<_Base> __end)
2122 _Sentinel(_Sentinel<!_Const> __i)
2124 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2125 : _M_end(std::move(__i._M_end))
2128 constexpr sentinel_t<_Base>
2132 template<bool _Const2>
2133 requires sentinel_for<sentinel_t<_Base>,
2134 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2135 friend constexpr bool
2136 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2137 { return __y.__equal(__x); }
2139 template<bool _Const2,
2140 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2141 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2142 friend constexpr range_difference_t<_Base2>
2143 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2144 { return -__y.__distance_from(__x); }
2146 template<bool _Const2,
2147 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2148 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2149 friend constexpr range_difference_t<_Base2>
2150 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2151 { return __y.__distance_from(__x); }
2153 friend _Sentinel<!_Const>;
2156 _Vp _M_base = _Vp();
2157 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2160 transform_view() requires (default_initializable<_Vp>
2161 && default_initializable<_Fp>)
2165 transform_view(_Vp __base, _Fp __fun)
2166 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2170 base() const& requires copy_constructible<_Vp>
2171 { return _M_base ; }
2175 { return std::move(_M_base); }
2177 constexpr _Iterator<false>
2179 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2181 constexpr _Iterator<true>
2183 requires range<const _Vp>
2184 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2185 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2187 constexpr _Sentinel<false>
2189 { return _Sentinel<false>{ranges::end(_M_base)}; }
2191 constexpr _Iterator<false>
2192 end() requires common_range<_Vp>
2193 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2195 constexpr _Sentinel<true>
2197 requires range<const _Vp>
2198 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2199 { return _Sentinel<true>{ranges::end(_M_base)}; }
2201 constexpr _Iterator<true>
2203 requires common_range<const _Vp>
2204 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2205 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2208 size() requires sized_range<_Vp>
2209 { return ranges::size(_M_base); }
2212 size() const requires sized_range<const _Vp>
2213 { return ranges::size(_M_base); }
2216 template<typename _Range, typename _Fp>
2217 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2223 template<typename _Range, typename _Fp>
2224 concept __can_transform_view
2225 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2226 } // namespace __detail
2228 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2230 template<viewable_range _Range, typename _Fp>
2231 requires __detail::__can_transform_view<_Range, _Fp>
2233 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2235 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2238 using _RangeAdaptor<_Transform>::operator();
2239 static constexpr int _S_arity = 2;
2240 static constexpr bool _S_has_simple_extra_args = true;
2243 inline constexpr _Transform transform;
2244 } // namespace views
2247 class take_view : public view_interface<take_view<_Vp>>
2250 template<bool _Const>
2251 using _CI = counted_iterator<
2252 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2254 template<bool _Const>
2258 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2259 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2262 _Sentinel() = default;
2265 _Sentinel(sentinel_t<_Base> __end)
2270 _Sentinel(_Sentinel<!_Const> __s)
2271 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2272 : _M_end(std::move(__s._M_end))
2275 constexpr sentinel_t<_Base>
2279 friend constexpr bool
2280 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2281 { return __y.count() == 0 || __y.base() == __x._M_end; }
2283 template<bool _OtherConst = !_Const,
2284 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2285 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2286 friend constexpr bool
2287 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2288 { return __y.count() == 0 || __y.base() == __x._M_end; }
2290 friend _Sentinel<!_Const>;
2293 _Vp _M_base = _Vp();
2294 range_difference_t<_Vp> _M_count = 0;
2297 take_view() requires default_initializable<_Vp> = default;
2300 take_view(_Vp __base, range_difference_t<_Vp> __count)
2301 : _M_base(std::move(__base)), _M_count(std::move(__count))
2305 base() const& requires copy_constructible<_Vp>
2310 { return std::move(_M_base); }
2313 begin() requires (!__detail::__simple_view<_Vp>)
2315 if constexpr (sized_range<_Vp>)
2317 if constexpr (random_access_range<_Vp>)
2318 return ranges::begin(_M_base);
2322 return counted_iterator(ranges::begin(_M_base), __sz);
2326 return counted_iterator(ranges::begin(_M_base), _M_count);
2330 begin() const requires range<const _Vp>
2332 if constexpr (sized_range<const _Vp>)
2334 if constexpr (random_access_range<const _Vp>)
2335 return ranges::begin(_M_base);
2339 return counted_iterator(ranges::begin(_M_base), __sz);
2343 return counted_iterator(ranges::begin(_M_base), _M_count);
2347 end() requires (!__detail::__simple_view<_Vp>)
2349 if constexpr (sized_range<_Vp>)
2351 if constexpr (random_access_range<_Vp>)
2352 return ranges::begin(_M_base) + size();
2354 return default_sentinel;
2357 return _Sentinel<false>{ranges::end(_M_base)};
2361 end() const requires range<const _Vp>
2363 if constexpr (sized_range<const _Vp>)
2365 if constexpr (random_access_range<const _Vp>)
2366 return ranges::begin(_M_base) + size();
2368 return default_sentinel;
2371 return _Sentinel<true>{ranges::end(_M_base)};
2375 size() requires sized_range<_Vp>
2377 auto __n = ranges::size(_M_base);
2378 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2382 size() const requires sized_range<const _Vp>
2384 auto __n = ranges::size(_M_base);
2385 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2389 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2390 // 3447. Deduction guides for take_view and drop_view have different
2392 template<typename _Range>
2393 take_view(_Range&&, range_difference_t<_Range>)
2394 -> take_view<views::all_t<_Range>>;
2396 template<typename _Tp>
2397 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2398 = enable_borrowed_range<_Tp>;
2404 template<typename _Range>
2405 inline constexpr bool __is_empty_view = false;
2407 template<typename _Tp>
2408 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2410 template<typename _Range>
2411 inline constexpr bool __is_basic_string_view = false;
2413 template<typename _CharT, typename _Traits>
2414 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2417 using ranges::__detail::__is_subrange;
2419 template<typename _Range>
2420 inline constexpr bool __is_iota_view = false;
2422 template<typename _Winc, typename _Bound>
2423 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2425 template<typename _Range>
2426 inline constexpr bool __is_repeat_view = false;
2428 template<typename _Range>
2430 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2432 template<typename _Range, typename _Dp>
2433 concept __can_take_view
2434 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2435 } // namespace __detail
2437 struct _Take : __adaptor::_RangeAdaptor<_Take>
2439 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2440 requires __detail::__can_take_view<_Range, _Dp>
2442 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2444 using _Tp = remove_cvref_t<_Range>;
2445 if constexpr (__detail::__is_empty_view<_Tp>)
2447 else if constexpr (random_access_range<_Tp>
2449 && (std::__detail::__is_span<_Tp>
2450 || __detail::__is_basic_string_view<_Tp>
2451 || __detail::__is_subrange<_Tp>
2452 || __detail::__is_iota_view<_Tp>))
2454 __n = std::min<_Dp>(ranges::distance(__r), __n);
2455 auto __begin = ranges::begin(__r);
2456 auto __end = __begin + __n;
2457 if constexpr (std::__detail::__is_span<_Tp>)
2458 return span<typename _Tp::element_type>(__begin, __end);
2459 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2460 return _Tp(__begin, __end);
2461 else if constexpr (__detail::__is_subrange<_Tp>)
2462 return subrange<iterator_t<_Tp>>(__begin, __end);
2464 return iota_view(*__begin, *__end);
2466 else if constexpr (__detail::__is_repeat_view<_Tp>)
2467 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2469 return take_view(std::forward<_Range>(__r), __n);
2472 using _RangeAdaptor<_Take>::operator();
2473 static constexpr int _S_arity = 2;
2474 // The count argument of views::take is not always simple -- it can be
2475 // e.g. a move-only class that's implicitly convertible to the difference
2476 // type. But an integer-like count argument is surely simple.
2477 template<typename _Tp>
2478 static constexpr bool _S_has_simple_extra_args
2479 = ranges::__detail::__is_integer_like<_Tp>;
2482 inline constexpr _Take take;
2483 } // namespace views
2485 template<view _Vp, typename _Pred>
2486 requires input_range<_Vp> && is_object_v<_Pred>
2487 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2488 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2490 template<bool _Const>
2494 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2496 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2497 const _Pred* _M_pred = nullptr;
2500 _Sentinel() = default;
2503 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2504 : _M_end(__end), _M_pred(__pred)
2508 _Sentinel(_Sentinel<!_Const> __s)
2509 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2510 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2513 constexpr sentinel_t<_Base>
2514 base() const { return _M_end; }
2516 friend constexpr bool
2517 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2518 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2520 template<bool _OtherConst = !_Const,
2521 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2522 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2523 friend constexpr bool
2524 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2525 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2527 friend _Sentinel<!_Const>;
2530 _Vp _M_base = _Vp();
2531 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2534 take_while_view() requires (default_initializable<_Vp>
2535 && default_initializable<_Pred>)
2539 take_while_view(_Vp __base, _Pred __pred)
2540 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2544 base() const& requires copy_constructible<_Vp>
2549 { return std::move(_M_base); }
2551 constexpr const _Pred&
2553 { return *_M_pred; }
2556 begin() requires (!__detail::__simple_view<_Vp>)
2557 { return ranges::begin(_M_base); }
2560 begin() const requires range<const _Vp>
2561 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2562 { return ranges::begin(_M_base); }
2565 end() requires (!__detail::__simple_view<_Vp>)
2566 { return _Sentinel<false>(ranges::end(_M_base),
2567 std::__addressof(*_M_pred)); }
2570 end() const requires range<const _Vp>
2571 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2572 { return _Sentinel<true>(ranges::end(_M_base),
2573 std::__addressof(*_M_pred)); }
2576 template<typename _Range, typename _Pred>
2577 take_while_view(_Range&&, _Pred)
2578 -> take_while_view<views::all_t<_Range>, _Pred>;
2584 template<typename _Range, typename _Pred>
2585 concept __can_take_while_view
2586 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2587 } // namespace __detail
2589 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2591 template<viewable_range _Range, typename _Pred>
2592 requires __detail::__can_take_while_view<_Range, _Pred>
2594 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2596 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2599 using _RangeAdaptor<_TakeWhile>::operator();
2600 static constexpr int _S_arity = 2;
2601 static constexpr bool _S_has_simple_extra_args = true;
2604 inline constexpr _TakeWhile take_while;
2605 } // namespace views
2608 class drop_view : public view_interface<drop_view<_Vp>>
2611 _Vp _M_base = _Vp();
2612 range_difference_t<_Vp> _M_count = 0;
2614 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2615 // both random_access_range and sized_range. Otherwise, cache its result.
2616 static constexpr bool _S_needs_cached_begin
2617 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2618 [[no_unique_address]]
2619 __detail::__maybe_present_t<_S_needs_cached_begin,
2620 __detail::_CachedPosition<_Vp>>
2624 drop_view() requires default_initializable<_Vp> = default;
2627 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2628 : _M_base(std::move(__base)), _M_count(__count)
2629 { __glibcxx_assert(__count >= 0); }
2632 base() const& requires copy_constructible<_Vp>
2637 { return std::move(_M_base); }
2639 // This overload is disabled for simple views with constant-time begin().
2642 requires (!(__detail::__simple_view<_Vp>
2643 && random_access_range<const _Vp>
2644 && sized_range<const _Vp>))
2646 if constexpr (_S_needs_cached_begin)
2647 if (_M_cached_begin._M_has_value())
2648 return _M_cached_begin._M_get(_M_base);
2650 auto __it = ranges::next(ranges::begin(_M_base),
2651 _M_count, ranges::end(_M_base));
2652 if constexpr (_S_needs_cached_begin)
2653 _M_cached_begin._M_set(_M_base, __it);
2657 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2658 // 3482. drop_view's const begin should additionally require sized_range
2661 requires random_access_range<const _Vp> && sized_range<const _Vp>
2663 return ranges::next(ranges::begin(_M_base), _M_count,
2664 ranges::end(_M_base));
2668 end() requires (!__detail::__simple_view<_Vp>)
2669 { return ranges::end(_M_base); }
2672 end() const requires range<const _Vp>
2673 { return ranges::end(_M_base); }
2676 size() requires sized_range<_Vp>
2678 const auto __s = ranges::size(_M_base);
2679 const auto __c = static_cast<decltype(__s)>(_M_count);
2680 return __s < __c ? 0 : __s - __c;
2684 size() const requires sized_range<const _Vp>
2686 const auto __s = ranges::size(_M_base);
2687 const auto __c = static_cast<decltype(__s)>(_M_count);
2688 return __s < __c ? 0 : __s - __c;
2692 template<typename _Range>
2693 drop_view(_Range&&, range_difference_t<_Range>)
2694 -> drop_view<views::all_t<_Range>>;
2696 template<typename _Tp>
2697 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2698 = enable_borrowed_range<_Tp>;
2704 template<typename _Range>
2706 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2708 template<typename _Range, typename _Dp>
2709 concept __can_drop_view
2710 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2711 } // namespace __detail
2713 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2715 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2716 requires __detail::__can_drop_view<_Range, _Dp>
2718 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2720 using _Tp = remove_cvref_t<_Range>;
2721 if constexpr (__detail::__is_empty_view<_Tp>)
2723 else if constexpr (random_access_range<_Tp>
2725 && (std::__detail::__is_span<_Tp>
2726 || __detail::__is_basic_string_view<_Tp>
2727 || __detail::__is_iota_view<_Tp>
2728 || __detail::__is_subrange<_Tp>))
2730 __n = std::min<_Dp>(ranges::distance(__r), __n);
2731 auto __begin = ranges::begin(__r) + __n;
2732 auto __end = ranges::end(__r);
2733 if constexpr (std::__detail::__is_span<_Tp>)
2734 return span<typename _Tp::element_type>(__begin, __end);
2735 else if constexpr (__detail::__is_subrange<_Tp>)
2737 if constexpr (_Tp::_S_store_size)
2739 using ranges::__detail::__to_unsigned_like;
2740 auto __m = ranges::distance(__r) - __n;
2741 return _Tp(__begin, __end, __to_unsigned_like(__m));
2744 return _Tp(__begin, __end);
2747 return _Tp(__begin, __end);
2749 else if constexpr (__detail::__is_repeat_view<_Tp>)
2750 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2752 return drop_view(std::forward<_Range>(__r), __n);
2755 using _RangeAdaptor<_Drop>::operator();
2756 static constexpr int _S_arity = 2;
2757 template<typename _Tp>
2758 static constexpr bool _S_has_simple_extra_args
2759 = _Take::_S_has_simple_extra_args<_Tp>;
2762 inline constexpr _Drop drop;
2763 } // namespace views
2765 template<view _Vp, typename _Pred>
2766 requires input_range<_Vp> && is_object_v<_Pred>
2767 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2768 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2771 _Vp _M_base = _Vp();
2772 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2773 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2776 drop_while_view() requires (default_initializable<_Vp>
2777 && default_initializable<_Pred>)
2781 drop_while_view(_Vp __base, _Pred __pred)
2782 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2786 base() const& requires copy_constructible<_Vp>
2791 { return std::move(_M_base); }
2793 constexpr const _Pred&
2795 { return *_M_pred; }
2800 if (_M_cached_begin._M_has_value())
2801 return _M_cached_begin._M_get(_M_base);
2803 __glibcxx_assert(_M_pred.has_value());
2804 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2805 ranges::end(_M_base),
2806 std::cref(*_M_pred));
2807 _M_cached_begin._M_set(_M_base, __it);
2813 { return ranges::end(_M_base); }
2816 template<typename _Range, typename _Pred>
2817 drop_while_view(_Range&&, _Pred)
2818 -> drop_while_view<views::all_t<_Range>, _Pred>;
2820 template<typename _Tp, typename _Pred>
2821 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2822 = enable_borrowed_range<_Tp>;
2828 template<typename _Range, typename _Pred>
2829 concept __can_drop_while_view
2830 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2831 } // namespace __detail
2833 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2835 template<viewable_range _Range, typename _Pred>
2836 requires __detail::__can_drop_while_view<_Range, _Pred>
2838 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2840 return drop_while_view(std::forward<_Range>(__r),
2841 std::forward<_Pred>(__p));
2844 using _RangeAdaptor<_DropWhile>::operator();
2845 static constexpr int _S_arity = 2;
2846 static constexpr bool _S_has_simple_extra_args = true;
2849 inline constexpr _DropWhile drop_while;
2850 } // namespace views
2854 template<typename _Tp>
2856 __as_lvalue(_Tp&& __t)
2857 { return static_cast<_Tp&>(__t); }
2858 } // namespace __detail
2860 template<input_range _Vp>
2861 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2862 class join_view : public view_interface<join_view<_Vp>>
2865 using _InnerRange = range_reference_t<_Vp>;
2867 template<bool _Const>
2868 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2870 template<bool _Const>
2871 using _Outer_iter = iterator_t<_Base<_Const>>;
2873 template<bool _Const>
2874 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2876 template<bool _Const>
2877 static constexpr bool _S_ref_is_glvalue
2878 = is_reference_v<range_reference_t<_Base<_Const>>>;
2880 template<bool _Const>
2884 template<bool _Const>
2885 requires _S_ref_is_glvalue<_Const>
2886 && forward_range<_Base<_Const>>
2887 && forward_range<range_reference_t<_Base<_Const>>>
2888 struct __iter_cat<_Const>
2891 static constexpr auto
2894 using _Outer_iter = join_view::_Outer_iter<_Const>;
2895 using _Inner_iter = join_view::_Inner_iter<_Const>;
2896 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2897 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2898 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2899 && derived_from<_InnerCat, bidirectional_iterator_tag>
2900 && common_range<range_reference_t<_Base<_Const>>>)
2901 return bidirectional_iterator_tag{};
2902 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2903 && derived_from<_InnerCat, forward_iterator_tag>)
2904 return forward_iterator_tag{};
2906 return input_iterator_tag{};
2909 using iterator_category = decltype(_S_iter_cat());
2912 template<bool _Const>
2915 template<bool _Const>
2916 struct _Iterator : __iter_cat<_Const>
2919 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2920 using _Base = join_view::_Base<_Const>;
2924 static constexpr bool _S_ref_is_glvalue
2925 = join_view::_S_ref_is_glvalue<_Const>;
2930 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2931 if constexpr (_S_ref_is_glvalue)
2934 return _M_parent->_M_inner._M_emplace_deref(__x);
2937 _Outer_iter& __outer = _M_get_outer();
2938 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2940 auto&& __inner = __update_inner(__outer);
2941 _M_inner = ranges::begin(__inner);
2942 if (_M_inner != ranges::end(__inner))
2946 if constexpr (_S_ref_is_glvalue)
2950 static constexpr auto
2953 if constexpr (_S_ref_is_glvalue
2954 && bidirectional_range<_Base>
2955 && bidirectional_range<range_reference_t<_Base>>
2956 && common_range<range_reference_t<_Base>>)
2957 return bidirectional_iterator_tag{};
2958 else if constexpr (_S_ref_is_glvalue
2959 && forward_range<_Base>
2960 && forward_range<range_reference_t<_Base>>)
2961 return forward_iterator_tag{};
2963 return input_iterator_tag{};
2966 using _Outer_iter = join_view::_Outer_iter<_Const>;
2967 using _Inner_iter = join_view::_Inner_iter<_Const>;
2969 constexpr _Outer_iter&
2972 if constexpr (forward_range<_Base>)
2975 return *_M_parent->_M_outer;
2978 constexpr const _Outer_iter&
2979 _M_get_outer() const
2981 if constexpr (forward_range<_Base>)
2984 return *_M_parent->_M_outer;
2988 _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base>
2989 : _M_outer(std::move(__outer)), _M_parent(__parent)
2993 _Iterator(_Parent* __parent) requires (!forward_range<_Base>)
2994 : _M_parent(__parent)
2997 [[no_unique_address]]
2998 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer;
2999 optional<_Inner_iter> _M_inner;
3000 _Parent* _M_parent = nullptr;
3003 using iterator_concept = decltype(_S_iter_concept());
3004 // iterator_category defined in __join_view_iter_cat
3005 using value_type = range_value_t<range_reference_t<_Base>>;
3006 using difference_type
3007 = common_type_t<range_difference_t<_Base>,
3008 range_difference_t<range_reference_t<_Base>>>;
3010 _Iterator() = default;
3013 _Iterator(_Iterator<!_Const> __i)
3015 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3016 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3017 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
3018 _M_parent(__i._M_parent)
3021 constexpr decltype(auto)
3023 { return **_M_inner; }
3025 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3026 // 3500. join_view::iterator::operator->() is bogus
3027 constexpr _Inner_iter
3029 requires __detail::__has_arrow<_Inner_iter>
3030 && copyable<_Inner_iter>
3031 { return *_M_inner; }
3033 constexpr _Iterator&
3036 auto&& __inner_range = [this] () -> auto&& {
3037 if constexpr (_S_ref_is_glvalue)
3038 return *_M_get_outer();
3040 return *_M_parent->_M_inner;
3042 if (++*_M_inner == ranges::end(__inner_range))
3056 requires _S_ref_is_glvalue && forward_range<_Base>
3057 && forward_range<range_reference_t<_Base>>
3064 constexpr _Iterator&
3066 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3067 && bidirectional_range<range_reference_t<_Base>>
3068 && common_range<range_reference_t<_Base>>
3070 if (_M_outer == ranges::end(_M_parent->_M_base))
3071 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3072 while (*_M_inner == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3073 *_M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3080 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3081 && bidirectional_range<range_reference_t<_Base>>
3082 && common_range<range_reference_t<_Base>>
3089 friend constexpr bool
3090 operator==(const _Iterator& __x, const _Iterator& __y)
3091 requires _S_ref_is_glvalue
3092 && forward_range<_Base>
3093 && equality_comparable<_Inner_iter>
3095 return (__x._M_outer == __y._M_outer
3096 && __x._M_inner == __y._M_inner);
3099 friend constexpr decltype(auto)
3100 iter_move(const _Iterator& __i)
3101 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
3102 { return ranges::iter_move(*__i._M_inner); }
3104 friend constexpr void
3105 iter_swap(const _Iterator& __x, const _Iterator& __y)
3106 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
3107 requires indirectly_swappable<_Inner_iter>
3108 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
3110 friend _Iterator<!_Const>;
3111 template<bool> friend struct _Sentinel;
3114 template<bool _Const>
3118 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3119 using _Base = join_view::_Base<_Const>;
3121 template<bool _Const2>
3123 __equal(const _Iterator<_Const2>& __i) const
3124 { return __i._M_get_outer() == _M_end; }
3126 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3129 _Sentinel() = default;
3132 _Sentinel(_Parent* __parent)
3133 : _M_end(ranges::end(__parent->_M_base))
3137 _Sentinel(_Sentinel<!_Const> __s)
3138 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3139 : _M_end(std::move(__s._M_end))
3142 template<bool _Const2>
3143 requires sentinel_for<sentinel_t<_Base>,
3144 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3145 friend constexpr bool
3146 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3147 { return __y.__equal(__x); }
3149 friend _Sentinel<!_Const>;
3152 _Vp _M_base = _Vp();
3153 [[no_unique_address]]
3154 __detail::__maybe_present_t<!forward_range<_Vp>,
3155 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3156 [[no_unique_address]]
3157 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3160 join_view() requires default_initializable<_Vp> = default;
3163 join_view(_Vp __base)
3164 : _M_base(std::move(__base))
3168 base() const& requires copy_constructible<_Vp>
3173 { return std::move(_M_base); }
3178 if constexpr (forward_range<_Vp>)
3180 constexpr bool __use_const
3181 = (__detail::__simple_view<_Vp>
3182 && is_reference_v<range_reference_t<_Vp>>);
3183 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3187 _M_outer = ranges::begin(_M_base);
3188 return _Iterator<false>{this};
3194 requires forward_range<const _Vp>
3195 && is_reference_v<range_reference_t<const _Vp>>
3196 && input_range<range_reference_t<const _Vp>>
3198 return _Iterator<true>{this, ranges::begin(_M_base)};
3204 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3205 && forward_range<_InnerRange>
3206 && common_range<_Vp> && common_range<_InnerRange>)
3207 return _Iterator<__detail::__simple_view<_Vp>>{this,
3208 ranges::end(_M_base)};
3210 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3215 requires forward_range<const _Vp>
3216 && is_reference_v<range_reference_t<const _Vp>>
3217 && input_range<range_reference_t<const _Vp>>
3219 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3220 && forward_range<range_reference_t<const _Vp>>
3221 && common_range<const _Vp>
3222 && common_range<range_reference_t<const _Vp>>)
3223 return _Iterator<true>{this, ranges::end(_M_base)};
3225 return _Sentinel<true>{this};
3229 template<typename _Range>
3230 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3236 template<typename _Range>
3237 concept __can_join_view
3238 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3239 } // namespace __detail
3241 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3243 template<viewable_range _Range>
3244 requires __detail::__can_join_view<_Range>
3246 operator() [[nodiscard]] (_Range&& __r) const
3248 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3249 // 3474. Nesting join_views is broken because of CTAD
3250 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3253 static constexpr bool _S_has_simple_call_op = true;
3256 inline constexpr _Join join;
3257 } // namespace views
3262 struct __require_constant;
3264 template<typename _Range>
3265 concept __tiny_range = sized_range<_Range>
3267 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3268 && (remove_reference_t<_Range>::size() <= 1);
3270 template<typename _Base>
3271 struct __lazy_split_view_outer_iter_cat
3274 template<forward_range _Base>
3275 struct __lazy_split_view_outer_iter_cat<_Base>
3276 { using iterator_category = input_iterator_tag; };
3278 template<typename _Base>
3279 struct __lazy_split_view_inner_iter_cat
3282 template<forward_range _Base>
3283 struct __lazy_split_view_inner_iter_cat<_Base>
3286 static constexpr auto
3289 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3290 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3291 return forward_iterator_tag{};
3296 using iterator_category = decltype(_S_iter_cat());
3300 template<input_range _Vp, forward_range _Pattern>
3301 requires view<_Vp> && view<_Pattern>
3302 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3304 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3305 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3308 template<bool _Const>
3309 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3311 template<bool _Const>
3314 template<bool _Const>
3316 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3319 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3320 using _Base = lazy_split_view::_Base<_Const>;
3324 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3326 // [range.lazy.split.outer] p1
3327 // Many of the following specifications refer to the notional member
3328 // current of outer-iterator. current is equivalent to current_ if
3329 // V models forward_range, and parent_->current_ otherwise.
3331 __current() noexcept
3333 if constexpr (forward_range<_Vp>)
3336 return *_M_parent->_M_current;
3340 __current() const noexcept
3342 if constexpr (forward_range<_Vp>)
3345 return *_M_parent->_M_current;
3348 _Parent* _M_parent = nullptr;
3350 [[no_unique_address]]
3351 __detail::__maybe_present_t<forward_range<_Vp>,
3352 iterator_t<_Base>> _M_current;
3353 bool _M_trailing_empty = false;
3356 using iterator_concept = __conditional_t<forward_range<_Base>,
3357 forward_iterator_tag,
3358 input_iterator_tag>;
3359 // iterator_category defined in __lazy_split_view_outer_iter_cat
3360 using difference_type = range_difference_t<_Base>;
3362 struct value_type : view_interface<value_type>
3365 _OuterIter _M_i = _OuterIter();
3367 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3368 // 4013. lazy_split_view::outer-iterator::value_type should not
3369 // provide default constructor
3371 value_type(_OuterIter __i)
3372 : _M_i(std::move(__i))
3378 constexpr _InnerIter<_Const>
3380 { return _InnerIter<_Const>{_M_i}; }
3382 constexpr default_sentinel_t
3383 end() const noexcept
3384 { return default_sentinel; }
3387 _OuterIter() = default;
3390 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3391 : _M_parent(__parent)
3395 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3396 requires forward_range<_Base>
3397 : _M_parent(__parent),
3398 _M_current(std::move(__current))
3402 _OuterIter(_OuterIter<!_Const> __i)
3404 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3405 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3406 _M_trailing_empty(__i._M_trailing_empty)
3409 constexpr value_type
3411 { return value_type{*this}; }
3413 constexpr _OuterIter&
3416 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3417 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3418 const auto __end = ranges::end(_M_parent->_M_base);
3419 if (__current() == __end)
3421 _M_trailing_empty = false;
3424 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3425 if (__pbegin == __pend)
3427 else if constexpr (__detail::__tiny_range<_Pattern>)
3429 __current() = ranges::find(std::move(__current()), __end,
3431 if (__current() != __end)
3434 if (__current() == __end)
3435 _M_trailing_empty = true;
3442 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3446 if (__current() == __end)
3447 _M_trailing_empty = true;
3450 } while (++__current() != __end);
3454 constexpr decltype(auto)
3457 if constexpr (forward_range<_Base>)
3467 friend constexpr bool
3468 operator==(const _OuterIter& __x, const _OuterIter& __y)
3469 requires forward_range<_Base>
3471 return __x._M_current == __y._M_current
3472 && __x._M_trailing_empty == __y._M_trailing_empty;
3475 friend constexpr bool
3476 operator==(const _OuterIter& __x, default_sentinel_t)
3477 { return __x.__at_end(); };
3479 friend _OuterIter<!_Const>;
3480 friend _InnerIter<_Const>;
3483 template<bool _Const>
3485 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3488 using _Base = lazy_split_view::_Base<_Const>;
3493 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3494 auto __end = ranges::end(_M_i._M_parent->_M_base);
3495 if constexpr (__detail::__tiny_range<_Pattern>)
3497 const auto& __cur = _M_i_current();
3500 if (__pcur == __pend)
3501 return _M_incremented;
3502 return *__cur == *__pcur;
3506 auto __cur = _M_i_current();
3509 if (__pcur == __pend)
3510 return _M_incremented;
3513 if (*__cur != *__pcur)
3515 if (++__pcur == __pend)
3517 } while (++__cur != __end);
3523 _M_i_current() noexcept
3524 { return _M_i.__current(); }
3527 _M_i_current() const noexcept
3528 { return _M_i.__current(); }
3530 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3531 bool _M_incremented = false;
3534 using iterator_concept
3535 = typename _OuterIter<_Const>::iterator_concept;
3536 // iterator_category defined in __lazy_split_view_inner_iter_cat
3537 using value_type = range_value_t<_Base>;
3538 using difference_type = range_difference_t<_Base>;
3540 _InnerIter() = default;
3543 _InnerIter(_OuterIter<_Const> __i)
3544 : _M_i(std::move(__i))
3547 constexpr const iterator_t<_Base>&
3548 base() const& noexcept
3549 { return _M_i_current(); }
3551 constexpr iterator_t<_Base>
3552 base() && requires forward_range<_Vp>
3553 { return std::move(_M_i_current()); }
3555 constexpr decltype(auto)
3557 { return *_M_i_current(); }
3559 constexpr _InnerIter&
3562 _M_incremented = true;
3563 if constexpr (!forward_range<_Base>)
3564 if constexpr (_Pattern::size() == 0)
3570 constexpr decltype(auto)
3573 if constexpr (forward_range<_Base>)
3583 friend constexpr bool
3584 operator==(const _InnerIter& __x, const _InnerIter& __y)
3585 requires forward_range<_Base>
3586 { return __x._M_i == __y._M_i; }
3588 friend constexpr bool
3589 operator==(const _InnerIter& __x, default_sentinel_t)
3590 { return __x.__at_end(); }
3592 friend constexpr decltype(auto)
3593 iter_move(const _InnerIter& __i)
3594 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3595 { return ranges::iter_move(__i._M_i_current()); }
3597 friend constexpr void
3598 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3599 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3600 __y._M_i_current())))
3601 requires indirectly_swappable<iterator_t<_Base>>
3602 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3605 _Vp _M_base = _Vp();
3606 _Pattern _M_pattern = _Pattern();
3607 [[no_unique_address]]
3608 __detail::__maybe_present_t<!forward_range<_Vp>,
3609 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3613 lazy_split_view() requires (default_initializable<_Vp>
3614 && default_initializable<_Pattern>)
3618 lazy_split_view(_Vp __base, _Pattern __pattern)
3619 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3622 template<input_range _Range>
3623 requires constructible_from<_Vp, views::all_t<_Range>>
3624 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3626 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3627 : _M_base(views::all(std::forward<_Range>(__r))),
3628 _M_pattern(views::single(std::move(__e)))
3632 base() const& requires copy_constructible<_Vp>
3637 { return std::move(_M_base); }
3642 if constexpr (forward_range<_Vp>)
3644 constexpr bool __simple
3645 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3646 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3650 _M_current = ranges::begin(_M_base);
3651 return _OuterIter<false>{this};
3656 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3658 return _OuterIter<true>{this, ranges::begin(_M_base)};
3662 end() requires forward_range<_Vp> && common_range<_Vp>
3664 constexpr bool __simple
3665 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3666 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3672 if constexpr (forward_range<_Vp>
3673 && forward_range<const _Vp>
3674 && common_range<const _Vp>)
3675 return _OuterIter<true>{this, ranges::end(_M_base)};
3677 return default_sentinel;
3681 template<typename _Range, typename _Pattern>
3682 lazy_split_view(_Range&&, _Pattern&&)
3683 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3685 template<input_range _Range>
3686 lazy_split_view(_Range&&, range_value_t<_Range>)
3687 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3693 template<typename _Range, typename _Pattern>
3694 concept __can_lazy_split_view
3695 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3696 } // namespace __detail
3698 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3700 template<viewable_range _Range, typename _Pattern>
3701 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3703 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3705 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3708 using _RangeAdaptor<_LazySplit>::operator();
3709 static constexpr int _S_arity = 2;
3710 // The pattern argument of views::lazy_split is not always simple -- it can be
3711 // a non-view range, the value category of which affects whether the call
3712 // is well-formed. But a scalar or a view pattern argument is surely
3714 template<typename _Pattern>
3715 static constexpr bool _S_has_simple_extra_args
3716 = is_scalar_v<_Pattern> || (view<_Pattern>
3717 && copy_constructible<_Pattern>);
3720 inline constexpr _LazySplit lazy_split;
3721 } // namespace views
3723 template<forward_range _Vp, forward_range _Pattern>
3724 requires view<_Vp> && view<_Pattern>
3725 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3727 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3730 _Vp _M_base = _Vp();
3731 _Pattern _M_pattern = _Pattern();
3732 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3738 split_view() requires (default_initializable<_Vp>
3739 && default_initializable<_Pattern>)
3743 split_view(_Vp __base, _Pattern __pattern)
3744 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3747 template<forward_range _Range>
3748 requires constructible_from<_Vp, views::all_t<_Range>>
3749 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3751 split_view(_Range&& __r, range_value_t<_Range> __e)
3752 : _M_base(views::all(std::forward<_Range>(__r))),
3753 _M_pattern(views::single(std::move(__e)))
3757 base() const& requires copy_constructible<_Vp>
3762 { return std::move(_M_base); }
3767 if (!_M_cached_begin)
3768 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3769 return {this, ranges::begin(_M_base), *_M_cached_begin};
3775 if constexpr (common_range<_Vp>)
3776 return _Iterator{this, ranges::end(_M_base), {}};
3778 return _Sentinel{this};
3781 constexpr subrange<iterator_t<_Vp>>
3782 _M_find_next(iterator_t<_Vp> __it)
3784 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3785 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3797 split_view* _M_parent = nullptr;
3798 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3799 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3800 bool _M_trailing_empty = false;
3802 friend struct _Sentinel;
3805 using iterator_concept = forward_iterator_tag;
3806 using iterator_category = input_iterator_tag;
3807 using value_type = subrange<iterator_t<_Vp>>;
3808 using difference_type = range_difference_t<_Vp>;
3810 _Iterator() = default;
3813 _Iterator(split_view* __parent,
3814 iterator_t<_Vp> __current,
3815 subrange<iterator_t<_Vp>> __next)
3816 : _M_parent(__parent),
3817 _M_cur(std::move(__current)),
3818 _M_next(std::move(__next))
3821 constexpr iterator_t<_Vp>
3825 constexpr value_type
3827 { return {_M_cur, _M_next.begin()}; }
3829 constexpr _Iterator&
3832 _M_cur = _M_next.begin();
3833 if (_M_cur != ranges::end(_M_parent->_M_base))
3835 _M_cur = _M_next.end();
3836 if (_M_cur == ranges::end(_M_parent->_M_base))
3838 _M_trailing_empty = true;
3839 _M_next = {_M_cur, _M_cur};
3842 _M_next = _M_parent->_M_find_next(_M_cur);
3845 _M_trailing_empty = false;
3857 friend constexpr bool
3858 operator==(const _Iterator& __x, const _Iterator& __y)
3860 return __x._M_cur == __y._M_cur
3861 && __x._M_trailing_empty == __y._M_trailing_empty;
3868 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3871 _M_equal(const _Iterator& __x) const
3872 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3875 _Sentinel() = default;
3878 _Sentinel(split_view* __parent)
3879 : _M_end(ranges::end(__parent->_M_base))
3882 friend constexpr bool
3883 operator==(const _Iterator& __x, const _Sentinel& __y)
3884 { return __y._M_equal(__x); }
3888 template<typename _Range, typename _Pattern>
3889 split_view(_Range&&, _Pattern&&)
3890 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3892 template<forward_range _Range>
3893 split_view(_Range&&, range_value_t<_Range>)
3894 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3900 template<typename _Range, typename _Pattern>
3901 concept __can_split_view
3902 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3903 } // namespace __detail
3905 struct _Split : __adaptor::_RangeAdaptor<_Split>
3907 template<viewable_range _Range, typename _Pattern>
3908 requires __detail::__can_split_view<_Range, _Pattern>
3910 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3912 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3915 using _RangeAdaptor<_Split>::operator();
3916 static constexpr int _S_arity = 2;
3917 template<typename _Pattern>
3918 static constexpr bool _S_has_simple_extra_args
3919 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3922 inline constexpr _Split split;
3923 } // namespace views
3929 template<input_or_output_iterator _Iter>
3931 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3933 if constexpr (contiguous_iterator<_Iter>)
3934 return span(std::__to_address(__i), __n);
3935 else if constexpr (random_access_iterator<_Iter>)
3936 return subrange(__i, __i + __n);
3938 return subrange(counted_iterator(std::move(__i), __n),
3943 inline constexpr _Counted counted{};
3944 } // namespace views
3947 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3948 class common_view : public view_interface<common_view<_Vp>>
3951 _Vp _M_base = _Vp();
3954 common_view() requires default_initializable<_Vp> = default;
3957 common_view(_Vp __r)
3958 : _M_base(std::move(__r))
3962 base() const& requires copy_constructible<_Vp>
3967 { return std::move(_M_base); }
3969 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3970 // 4012. common_view::begin/end are missing the simple-view check
3972 begin() requires (!__detail::__simple_view<_Vp>)
3974 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3975 return ranges::begin(_M_base);
3977 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3978 (ranges::begin(_M_base));
3982 begin() const requires range<const _Vp>
3984 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3985 return ranges::begin(_M_base);
3987 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3988 (ranges::begin(_M_base));
3992 end() requires (!__detail::__simple_view<_Vp>)
3994 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3995 return ranges::begin(_M_base) + ranges::size(_M_base);
3997 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3998 (ranges::end(_M_base));
4002 end() const requires range<const _Vp>
4004 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4005 return ranges::begin(_M_base) + ranges::size(_M_base);
4007 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4008 (ranges::end(_M_base));
4012 size() requires sized_range<_Vp>
4013 { return ranges::size(_M_base); }
4016 size() const requires sized_range<const _Vp>
4017 { return ranges::size(_M_base); }
4020 template<typename _Range>
4021 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4023 template<typename _Tp>
4024 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4025 = enable_borrowed_range<_Tp>;
4031 template<typename _Range>
4032 concept __already_common = common_range<_Range>
4033 && requires { views::all(std::declval<_Range>()); };
4035 template<typename _Range>
4036 concept __can_common_view
4037 = requires { common_view{std::declval<_Range>()}; };
4038 } // namespace __detail
4040 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4042 template<viewable_range _Range>
4043 requires __detail::__already_common<_Range>
4044 || __detail::__can_common_view<_Range>
4046 operator() [[nodiscard]] (_Range&& __r) const
4048 if constexpr (__detail::__already_common<_Range>)
4049 return views::all(std::forward<_Range>(__r));
4051 return common_view{std::forward<_Range>(__r)};
4054 static constexpr bool _S_has_simple_call_op = true;
4057 inline constexpr _Common common;
4058 } // namespace views
4061 requires bidirectional_range<_Vp>
4062 class reverse_view : public view_interface<reverse_view<_Vp>>
4065 static constexpr bool _S_needs_cached_begin
4066 = !common_range<_Vp> && !(random_access_range<_Vp>
4067 && sized_sentinel_for<sentinel_t<_Vp>,
4070 _Vp _M_base = _Vp();
4071 [[no_unique_address]]
4072 __detail::__maybe_present_t<_S_needs_cached_begin,
4073 __detail::_CachedPosition<_Vp>>
4077 reverse_view() requires default_initializable<_Vp> = default;
4080 reverse_view(_Vp __r)
4081 : _M_base(std::move(__r))
4085 base() const& requires copy_constructible<_Vp>
4090 { return std::move(_M_base); }
4092 constexpr reverse_iterator<iterator_t<_Vp>>
4095 if constexpr (_S_needs_cached_begin)
4096 if (_M_cached_begin._M_has_value())
4097 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
4099 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4100 if constexpr (_S_needs_cached_begin)
4101 _M_cached_begin._M_set(_M_base, __it);
4102 return std::make_reverse_iterator(std::move(__it));
4106 begin() requires common_range<_Vp>
4107 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4110 begin() const requires common_range<const _Vp>
4111 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4113 constexpr reverse_iterator<iterator_t<_Vp>>
4115 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4118 end() const requires common_range<const _Vp>
4119 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4122 size() requires sized_range<_Vp>
4123 { return ranges::size(_M_base); }
4126 size() const requires sized_range<const _Vp>
4127 { return ranges::size(_M_base); }
4130 template<typename _Range>
4131 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4133 template<typename _Tp>
4134 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4135 = enable_borrowed_range<_Tp>;
4142 inline constexpr bool __is_reversible_subrange = false;
4144 template<typename _Iter, subrange_kind _Kind>
4145 inline constexpr bool
4146 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4147 reverse_iterator<_Iter>,
4151 inline constexpr bool __is_reverse_view = false;
4153 template<typename _Vp>
4154 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
4156 template<typename _Range>
4157 concept __can_reverse_view
4158 = requires { reverse_view{std::declval<_Range>()}; };
4159 } // namespace __detail
4161 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4163 template<viewable_range _Range>
4164 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4165 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4166 || __detail::__can_reverse_view<_Range>
4168 operator() [[nodiscard]] (_Range&& __r) const
4170 using _Tp = remove_cvref_t<_Range>;
4171 if constexpr (__detail::__is_reverse_view<_Tp>)
4172 return std::forward<_Range>(__r).base();
4173 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4175 using _Iter = decltype(ranges::begin(__r).base());
4176 if constexpr (sized_range<_Tp>)
4177 return subrange<_Iter, _Iter, subrange_kind::sized>
4178 {__r.end().base(), __r.begin().base(), __r.size()};
4180 return subrange<_Iter, _Iter, subrange_kind::unsized>
4181 {__r.end().base(), __r.begin().base()};
4184 return reverse_view{std::forward<_Range>(__r)};
4187 static constexpr bool _S_has_simple_call_op = true;
4190 inline constexpr _Reverse reverse;
4191 } // namespace views
4195#if __cpp_lib_tuple_like // >= C++23
4196 template<typename _Tp, size_t _Nm>
4197 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4199 template<typename _Tp, size_t _Nm>
4200 concept __has_tuple_element = requires(_Tp __t)
4202 typename tuple_size<_Tp>::type;
4203 requires _Nm < tuple_size_v<_Tp>;
4204 typename tuple_element_t<_Nm, _Tp>;
4205 { std::get<_Nm>(__t) }
4206 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4210 template<typename _Tp, size_t _Nm>
4211 concept __returnable_element
4212 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4215 template<input_range _Vp, size_t _Nm>
4217 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4218 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4220 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4221 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4224 elements_view() requires default_initializable<_Vp> = default;
4227 elements_view(_Vp __base)
4228 : _M_base(std::move(__base))
4232 base() const& requires copy_constructible<_Vp>
4237 { return std::move(_M_base); }
4240 begin() requires (!__detail::__simple_view<_Vp>)
4241 { return _Iterator<false>(ranges::begin(_M_base)); }
4244 begin() const requires range<const _Vp>
4245 { return _Iterator<true>(ranges::begin(_M_base)); }
4248 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4249 { return _Sentinel<false>{ranges::end(_M_base)}; }
4252 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4253 { return _Iterator<false>{ranges::end(_M_base)}; }
4256 end() const requires range<const _Vp>
4257 { return _Sentinel<true>{ranges::end(_M_base)}; }
4260 end() const requires common_range<const _Vp>
4261 { return _Iterator<true>{ranges::end(_M_base)}; }
4264 size() requires sized_range<_Vp>
4265 { return ranges::size(_M_base); }
4268 size() const requires sized_range<const _Vp>
4269 { return ranges::size(_M_base); }
4272 template<bool _Const>
4273 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4275 template<bool _Const>
4279 template<bool _Const>
4280 requires forward_range<_Base<_Const>>
4281 struct __iter_cat<_Const>
4284 static auto _S_iter_cat()
4286 using _Base = elements_view::_Base<_Const>;
4287 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4288 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4289 if constexpr (!is_lvalue_reference_v<_Res>)
4290 return input_iterator_tag{};
4291 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4292 return random_access_iterator_tag{};
4297 using iterator_category = decltype(_S_iter_cat());
4300 template<bool _Const>
4303 template<bool _Const>
4304 struct _Iterator : __iter_cat<_Const>
4307 using _Base = elements_view::_Base<_Const>;
4309 iterator_t<_Base> _M_current = iterator_t<_Base>();
4311 static constexpr decltype(auto)
4312 _S_get_element(const iterator_t<_Base>& __i)
4314 if constexpr (is_reference_v<range_reference_t<_Base>>)
4315 return std::get<_Nm>(*__i);
4318 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4319 return static_cast<_Et>(std::get<_Nm>(*__i));
4326 if constexpr (random_access_range<_Base>)
4327 return random_access_iterator_tag{};
4328 else if constexpr (bidirectional_range<_Base>)
4329 return bidirectional_iterator_tag{};
4330 else if constexpr (forward_range<_Base>)
4331 return forward_iterator_tag{};
4333 return input_iterator_tag{};
4336 friend _Iterator<!_Const>;
4339 using iterator_concept = decltype(_S_iter_concept());
4340 // iterator_category defined in elements_view::__iter_cat
4342 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4343 using difference_type = range_difference_t<_Base>;
4345 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4348 _Iterator(iterator_t<_Base> __current)
4349 : _M_current(std::move(__current))
4353 _Iterator(_Iterator<!_Const> __i)
4354 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4355 : _M_current(std::move(__i._M_current))
4358 constexpr const iterator_t<_Base>&
4359 base() const& noexcept
4360 { return _M_current; }
4362 constexpr iterator_t<_Base>
4364 { return std::move(_M_current); }
4366 constexpr decltype(auto)
4368 { return _S_get_element(_M_current); }
4370 constexpr _Iterator&
4382 operator++(int) requires forward_range<_Base>
4389 constexpr _Iterator&
4390 operator--() requires bidirectional_range<_Base>
4397 operator--(int) requires bidirectional_range<_Base>
4404 constexpr _Iterator&
4405 operator+=(difference_type __n)
4406 requires random_access_range<_Base>
4412 constexpr _Iterator&
4413 operator-=(difference_type __n)
4414 requires random_access_range<_Base>
4420 constexpr decltype(auto)
4421 operator[](difference_type __n) const
4422 requires random_access_range<_Base>
4423 { return _S_get_element(_M_current + __n); }
4425 friend constexpr bool
4426 operator==(const _Iterator& __x, const _Iterator& __y)
4427 requires equality_comparable<iterator_t<_Base>>
4428 { return __x._M_current == __y._M_current; }
4430 friend constexpr bool
4431 operator<(const _Iterator& __x, const _Iterator& __y)
4432 requires random_access_range<_Base>
4433 { return __x._M_current < __y._M_current; }
4435 friend constexpr bool
4436 operator>(const _Iterator& __x, const _Iterator& __y)
4437 requires random_access_range<_Base>
4438 { return __y._M_current < __x._M_current; }
4440 friend constexpr bool
4441 operator<=(const _Iterator& __x, const _Iterator& __y)
4442 requires random_access_range<_Base>
4443 { return !(__y._M_current > __x._M_current); }
4445 friend constexpr bool
4446 operator>=(const _Iterator& __x, const _Iterator& __y)
4447 requires random_access_range<_Base>
4448 { return !(__x._M_current > __y._M_current); }
4450#ifdef __cpp_lib_three_way_comparison
4451 friend constexpr auto
4452 operator<=>(const _Iterator& __x, const _Iterator& __y)
4453 requires random_access_range<_Base>
4454 && three_way_comparable<iterator_t<_Base>>
4455 { return __x._M_current <=> __y._M_current; }
4458 friend constexpr _Iterator
4459 operator+(const _Iterator& __x, difference_type __y)
4460 requires random_access_range<_Base>
4461 { return _Iterator{__x} += __y; }
4463 friend constexpr _Iterator
4464 operator+(difference_type __x, const _Iterator& __y)
4465 requires random_access_range<_Base>
4466 { return __y + __x; }
4468 friend constexpr _Iterator
4469 operator-(const _Iterator& __x, difference_type __y)
4470 requires random_access_range<_Base>
4471 { return _Iterator{__x} -= __y; }
4473 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4474 // 3483. transform_view::iterator's difference is overconstrained
4475 friend constexpr difference_type
4476 operator-(const _Iterator& __x, const _Iterator& __y)
4477 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4478 { return __x._M_current - __y._M_current; }
4480 template <bool> friend struct _Sentinel;
4483 template<bool _Const>
4487 template<bool _Const2>
4489 _M_equal(const _Iterator<_Const2>& __x) const
4490 { return __x._M_current == _M_end; }
4492 template<bool _Const2>
4494 _M_distance_from(const _Iterator<_Const2>& __i) const
4495 { return _M_end - __i._M_current; }
4497 using _Base = elements_view::_Base<_Const>;
4498 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4501 _Sentinel() = default;
4504 _Sentinel(sentinel_t<_Base> __end)
4505 : _M_end(std::move(__end))
4509 _Sentinel(_Sentinel<!_Const> __other)
4511 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4512 : _M_end(std::move(__other._M_end))
4515 constexpr sentinel_t<_Base>
4519 template<bool _Const2>
4520 requires sentinel_for<sentinel_t<_Base>,
4521 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4522 friend constexpr bool
4523 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4524 { return __y._M_equal(__x); }
4526 template<bool _Const2,
4527 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4528 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4529 friend constexpr range_difference_t<_Base2>
4530 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4531 { return -__y._M_distance_from(__x); }
4533 template<bool _Const2,
4534 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4535 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4536 friend constexpr range_difference_t<_Base2>
4537 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4538 { return __x._M_distance_from(__y); }
4540 friend _Sentinel<!_Const>;
4543 _Vp _M_base = _Vp();
4546 template<typename _Tp, size_t _Nm>
4547 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4548 = enable_borrowed_range<_Tp>;
4550 template<typename _Range>
4551 using keys_view = elements_view<views::all_t<_Range>, 0>;
4553 template<typename _Range>
4554 using values_view = elements_view<views::all_t<_Range>, 1>;
4560 template<size_t _Nm, typename _Range>
4561 concept __can_elements_view
4562 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4563 } // namespace __detail
4565 template<size_t _Nm>
4566 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4568 template<viewable_range _Range>
4569 requires __detail::__can_elements_view<_Nm, _Range>
4571 operator() [[nodiscard]] (_Range&& __r) const
4573 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4576 static constexpr bool _S_has_simple_call_op = true;
4579 template<size_t _Nm>
4580 inline constexpr _Elements<_Nm> elements;
4581 inline constexpr auto keys = elements<0>;
4582 inline constexpr auto values = elements<1>;
4583 } // namespace views
4585#ifdef __cpp_lib_ranges_zip // C++ >= 23
4588 template<typename... _Rs>
4589 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4590 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4591 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4593 template<typename _Fp, typename _Tuple>
4595 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4597 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4598 return tuple<invoke_result_t<_Fp&, _Ts>...>
4599 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4600 }, std::forward<_Tuple>(__tuple));
4603 template<typename _Fp, typename _Tuple>
4605 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4607 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4608 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4609 }, std::forward<_Tuple>(__tuple));
4611 } // namespace __detail
4613 template<input_range... _Vs>
4614 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4615 class zip_view : public view_interface<zip_view<_Vs...>>
4617 tuple<_Vs...> _M_views;
4619 template<bool> class _Iterator;
4620 template<bool> class _Sentinel;
4623 zip_view() = default;
4626 zip_view(_Vs... __views)
4627 : _M_views(std::move(__views)...)
4631 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4632 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4635 begin() const requires (range<const _Vs> && ...)
4636 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4639 end() requires (!(__detail::__simple_view<_Vs> && ...))
4641 if constexpr (!__detail::__zip_is_common<_Vs...>)
4642 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4643 else if constexpr ((random_access_range<_Vs> && ...))
4644 return begin() + iter_difference_t<_Iterator<false>>(size());
4646 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4650 end() const requires (range<const _Vs> && ...)
4652 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4653 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4654 else if constexpr ((random_access_range<const _Vs> && ...))
4655 return begin() + iter_difference_t<_Iterator<true>>(size());
4657 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4661 size() requires (sized_range<_Vs> && ...)
4663 return std::apply([](auto... sizes) {
4664 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4665 return ranges::min({_CT(sizes)...});
4666 }, __detail::__tuple_transform(ranges::size, _M_views));
4670 size() const requires (sized_range<const _Vs> && ...)
4672 return std::apply([](auto... sizes) {
4673 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4674 return ranges::min({_CT(sizes)...});
4675 }, __detail::__tuple_transform(ranges::size, _M_views));
4679 template<typename... _Rs>
4680 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4682 template<typename... _Views>
4683 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4684 = (enable_borrowed_range<_Views> && ...);
4688 template<bool _Const, typename... _Vs>
4689 concept __all_random_access
4690 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4692 template<bool _Const, typename... _Vs>
4693 concept __all_bidirectional
4694 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4696 template<bool _Const, typename... _Vs>
4697 concept __all_forward
4698 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4700 template<bool _Const, typename... _Views>
4701 struct __zip_view_iter_cat
4704 template<bool _Const, typename... _Views>
4705 requires __all_forward<_Const, _Views...>
4706 struct __zip_view_iter_cat<_Const, _Views...>
4707 { using iterator_category = input_iterator_tag; };
4708 } // namespace __detail
4710 template<input_range... _Vs>
4711 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4712 template<bool _Const>
4713 class zip_view<_Vs...>::_Iterator
4714 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4716#ifdef __clang__ // LLVM-61763 workaround
4719 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4722 _Iterator(decltype(_M_current) __current)
4723 : _M_current(std::move(__current))
4729 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4730 return random_access_iterator_tag{};
4731 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4732 return bidirectional_iterator_tag{};
4733 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4734 return forward_iterator_tag{};
4736 return input_iterator_tag{};
4739#ifndef __clang__ // LLVM-61763 workaround
4740 template<move_constructible _Fp, input_range... _Ws>
4741 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4742 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4743 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4744 friend class zip_transform_view;
4748 // iterator_category defined in __zip_view_iter_cat
4749 using iterator_concept = decltype(_S_iter_concept());
4751 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4752 using difference_type
4753 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4755 _Iterator() = default;
4758 _Iterator(_Iterator<!_Const> __i)
4760 && (convertible_to<iterator_t<_Vs>,
4761 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4762 : _M_current(std::move(__i._M_current))
4768 auto __f = [](auto& __i) -> decltype(auto) {
4771 return __detail::__tuple_transform(__f, _M_current);
4774 constexpr _Iterator&
4777 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4787 requires __detail::__all_forward<_Const, _Vs...>
4794 constexpr _Iterator&
4796 requires __detail::__all_bidirectional<_Const, _Vs...>
4798 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4804 requires __detail::__all_bidirectional<_Const, _Vs...>
4811 constexpr _Iterator&
4812 operator+=(difference_type __x)
4813 requires __detail::__all_random_access<_Const, _Vs...>
4815 auto __f = [&]<typename _It>(_It& __i) {
4816 __i += iter_difference_t<_It>(__x);
4818 __detail::__tuple_for_each(__f, _M_current);
4822 constexpr _Iterator&
4823 operator-=(difference_type __x)
4824 requires __detail::__all_random_access<_Const, _Vs...>
4826 auto __f = [&]<typename _It>(_It& __i) {
4827 __i -= iter_difference_t<_It>(__x);
4829 __detail::__tuple_for_each(__f, _M_current);
4834 operator[](difference_type __n) const
4835 requires __detail::__all_random_access<_Const, _Vs...>
4837 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4838 return __i[iter_difference_t<_It>(__n)];
4840 return __detail::__tuple_transform(__f, _M_current);
4843 friend constexpr bool
4844 operator==(const _Iterator& __x, const _Iterator& __y)
4845 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4847 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4848 return __x._M_current == __y._M_current;
4850 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4851 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4852 }(make_index_sequence<sizeof...(_Vs)>{});
4855 friend constexpr auto
4856 operator<=>(const _Iterator& __x, const _Iterator& __y)
4857 requires __detail::__all_random_access<_Const, _Vs...>
4858 { return __x._M_current <=> __y._M_current; }
4860 friend constexpr _Iterator
4861 operator+(const _Iterator& __i, difference_type __n)
4862 requires __detail::__all_random_access<_Const, _Vs...>
4869 friend constexpr _Iterator
4870 operator+(difference_type __n, const _Iterator& __i)
4871 requires __detail::__all_random_access<_Const, _Vs...>
4878 friend constexpr _Iterator
4879 operator-(const _Iterator& __i, difference_type __n)
4880 requires __detail::__all_random_access<_Const, _Vs...>
4887 friend constexpr difference_type
4888 operator-(const _Iterator& __x, const _Iterator& __y)
4889 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4890 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4892 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4893 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4894 - std::get<_Is>(__y._M_current))...},
4896 [](difference_type __i) {
4897 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4899 }(make_index_sequence<sizeof...(_Vs)>{});
4902 friend constexpr auto
4903 iter_move(const _Iterator& __i)
4904 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4906 friend constexpr void
4907 iter_swap(const _Iterator& __l, const _Iterator& __r)
4908 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4910 [&]<size_t... _Is>(index_sequence<_Is...>) {
4911 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4912 }(make_index_sequence<sizeof...(_Vs)>{});
4915 friend class zip_view;
4918 template<input_range... _Vs>
4919 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4920 template<bool _Const>
4921 class zip_view<_Vs...>::_Sentinel
4923 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4926 _Sentinel(decltype(_M_end) __end)
4930 friend class zip_view;
4933 _Sentinel() = default;
4936 _Sentinel(_Sentinel<!_Const> __i)
4938 && (convertible_to<sentinel_t<_Vs>,
4939 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4940 : _M_end(std::move(__i._M_end))
4943 template<bool _OtherConst>
4944 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4945 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4946 friend constexpr bool
4947 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4949 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4950 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4951 }(make_index_sequence<sizeof...(_Vs)>{});
4954 template<bool _OtherConst>
4955 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4956 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4957 friend constexpr auto
4958 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4961 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4962 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4963 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4966 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4968 }(make_index_sequence<sizeof...(_Vs)>{});
4971 template<bool _OtherConst>
4972 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4973 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4974 friend constexpr auto
4975 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4976 { return -(__x - __y); }
4983 template<typename... _Ts>
4984 concept __can_zip_view
4985 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4990 template<typename... _Ts>
4991 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4993 operator() [[nodiscard]] (_Ts&&... __ts) const
4995 if constexpr (sizeof...(_Ts) == 0)
4996 return views::empty<tuple<>>;
4998 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
5002 inline constexpr _Zip zip;
5007 template<typename _Range, bool _Const>
5008 using __range_iter_cat
5009 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5012 template<move_constructible _Fp, input_range... _Vs>
5013 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5014 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5015 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5016 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
5018 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5019 zip_view<_Vs...> _M_zip;
5021 using _InnerView = zip_view<_Vs...>;
5023 template<bool _Const>
5024 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5026 template<bool _Const>
5027 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5029 template<bool _Const>
5030 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5032 template<bool _Const>
5036 template<bool _Const>
5037 requires forward_range<_Base<_Const>>
5038 struct __iter_cat<_Const>
5044 using __detail::__maybe_const_t;
5045 using __detail::__range_iter_cat;
5046 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5047 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5048 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5049 // 3798. Rvalue reference and iterator_category
5050 if constexpr (!is_reference_v<_Res>)
5051 return input_iterator_tag{};
5052 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5053 random_access_iterator_tag> && ...))
5054 return random_access_iterator_tag{};
5055 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5056 bidirectional_iterator_tag> && ...))
5057 return bidirectional_iterator_tag{};
5058 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5059 forward_iterator_tag> && ...))
5060 return forward_iterator_tag{};
5062 return input_iterator_tag{};
5065 using iterator_category = decltype(_S_iter_cat());
5068 template<bool> class _Iterator;
5069 template<bool> class _Sentinel;
5072 zip_transform_view() = default;
5075 zip_transform_view(_Fp __fun, _Vs... __views)
5076 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5081 { return _Iterator<false>(*this, _M_zip.begin()); }
5085 requires range<const _InnerView>
5086 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5087 { return _Iterator<true>(*this, _M_zip.begin()); }
5092 if constexpr (common_range<_InnerView>)
5093 return _Iterator<false>(*this, _M_zip.end());
5095 return _Sentinel<false>(_M_zip.end());
5100 requires range<const _InnerView>
5101 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5103 if constexpr (common_range<const _InnerView>)
5104 return _Iterator<true>(*this, _M_zip.end());
5106 return _Sentinel<true>(_M_zip.end());
5110 size() requires sized_range<_InnerView>
5111 { return _M_zip.size(); }
5114 size() const requires sized_range<const _InnerView>
5115 { return _M_zip.size(); }
5118 template<class _Fp, class... Rs>
5119 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5121 template<move_constructible _Fp, input_range... _Vs>
5122 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5123 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5124 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5125 template<bool _Const>
5126 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5128 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5130 _Parent* _M_parent = nullptr;
5131 __ziperator<_Const> _M_inner;
5134 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5135 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5138 friend class zip_transform_view;
5141 // iterator_category defined in zip_transform_view::__iter_cat
5142 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
5144 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5145 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5146 using difference_type = range_difference_t<_Base<_Const>>;
5148 _Iterator() = default;
5151 _Iterator(_Iterator<!_Const> __i)
5152 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5153 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5156 constexpr decltype(auto)
5159 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5160 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5161 }, _M_inner._M_current);
5164 constexpr _Iterator&
5176 operator++(int) requires forward_range<_Base<_Const>>
5183 constexpr _Iterator&
5184 operator--() requires bidirectional_range<_Base<_Const>>
5191 operator--(int) requires bidirectional_range<_Base<_Const>>
5198 constexpr _Iterator&
5199 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5205 constexpr _Iterator&
5206 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5212 constexpr decltype(auto)
5213 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5215 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5216 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5217 }, _M_inner._M_current);
5220 friend constexpr bool
5221 operator==(const _Iterator& __x, const _Iterator& __y)
5222 requires equality_comparable<__ziperator<_Const>>
5223 { return __x._M_inner == __y._M_inner; }
5225 friend constexpr auto
5226 operator<=>(const _Iterator& __x, const _Iterator& __y)
5227 requires random_access_range<_Base<_Const>>
5228 { return __x._M_inner <=> __y._M_inner; }
5230 friend constexpr _Iterator
5231 operator+(const _Iterator& __i, difference_type __n)
5232 requires random_access_range<_Base<_Const>>
5233 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5235 friend constexpr _Iterator
5236 operator+(difference_type __n, const _Iterator& __i)
5237 requires random_access_range<_Base<_Const>>
5238 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5240 friend constexpr _Iterator
5241 operator-(const _Iterator& __i, difference_type __n)
5242 requires random_access_range<_Base<_Const>>
5243 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5245 friend constexpr difference_type
5246 operator-(const _Iterator& __x, const _Iterator& __y)
5247 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5248 { return __x._M_inner - __y._M_inner; }
5251 template<move_constructible _Fp, input_range... _Vs>
5252 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5253 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5254 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5255 template<bool _Const>
5256 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5258 __zentinel<_Const> _M_inner;
5261 _Sentinel(__zentinel<_Const> __inner)
5265 friend class zip_transform_view;
5268 _Sentinel() = default;
5271 _Sentinel(_Sentinel<!_Const> __i)
5272 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5273 : _M_inner(std::move(__i._M_inner))
5276 template<bool _OtherConst>
5277 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5278 friend constexpr bool
5279 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5280 { return __x._M_inner == __y._M_inner; }
5282 template<bool _OtherConst>
5283 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5284 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5285 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5286 { return __x._M_inner - __y._M_inner; }
5288 template<bool _OtherConst>
5289 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5290 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5291 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5292 { return __x._M_inner - __y._M_inner; }
5299 template<typename _Fp, typename... _Ts>
5300 concept __can_zip_transform_view
5301 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5304 struct _ZipTransform
5306 template<typename _Fp, typename... _Ts>
5307 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5309 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5311 if constexpr (sizeof...(_Ts) == 0)
5312 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5314 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5318 inline constexpr _ZipTransform zip_transform;
5321 template<forward_range _Vp, size_t _Nm>
5322 requires view<_Vp> && (_Nm > 0)
5323 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5325 _Vp _M_base = _Vp();
5327 template<bool> class _Iterator;
5328 template<bool> class _Sentinel;
5330 struct __as_sentinel
5334 adjacent_view() requires default_initializable<_Vp> = default;
5337 adjacent_view(_Vp __base)
5338 : _M_base(std::move(__base))
5341 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5342 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5344 base() const & requires copy_constructible<_Vp>
5349 { return std::move(_M_base); }
5352 begin() requires (!__detail::__simple_view<_Vp>)
5353 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5356 begin() const requires range<const _Vp>
5357 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5360 end() requires (!__detail::__simple_view<_Vp>)
5362 if constexpr (common_range<_Vp>)
5363 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5365 return _Sentinel<false>(ranges::end(_M_base));
5369 end() const requires range<const _Vp>
5371 if constexpr (common_range<const _Vp>)
5372 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5374 return _Sentinel<true>(ranges::end(_M_base));
5378 size() requires sized_range<_Vp>
5380 using _ST = decltype(ranges::size(_M_base));
5381 using _CT = common_type_t<_ST, size_t>;
5382 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5383 __sz -= std::min<_CT>(__sz, _Nm - 1);
5384 return static_cast<_ST>(__sz);
5388 size() const requires sized_range<const _Vp>
5390 using _ST = decltype(ranges::size(_M_base));
5391 using _CT = common_type_t<_ST, size_t>;
5392 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5393 __sz -= std::min<_CT>(__sz, _Nm - 1);
5394 return static_cast<_ST>(__sz);
5398 template<typename _Vp, size_t _Nm>
5399 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5400 = enable_borrowed_range<_Vp>;
5404 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5405 template<typename _Tp, size_t _Nm>
5406 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5408 // For a functor F that is callable with N arguments, the expression
5409 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5410 template<typename _Fp, size_t _Nm>
5413 template<typename... _Ts>
5414 static invoke_result_t<_Fp, _Ts...>
5415 __tuple_apply(const tuple<_Ts...>&); // not defined
5417 template<typename _Tp>
5418 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5419 operator()(_Tp&&); // not defined
5423 template<forward_range _Vp, size_t _Nm>
5424 requires view<_Vp> && (_Nm > 0)
5425 template<bool _Const>
5426 class adjacent_view<_Vp, _Nm>::_Iterator
5428#ifdef __clang__ // LLVM-61763 workaround
5431 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5432 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5435 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5437 for (auto& __i : _M_current)
5440 ranges::advance(__first, 1, __last);
5445 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5447 if constexpr (!bidirectional_range<_Base>)
5448 for (auto& __it : _M_current)
5451 for (size_t __i = 0; __i < _Nm; ++__i)
5453 _M_current[_Nm - 1 - __i] = __last;
5454 ranges::advance(__last, -1, __first);
5461 if constexpr (random_access_range<_Base>)
5462 return random_access_iterator_tag{};
5463 else if constexpr (bidirectional_range<_Base>)
5464 return bidirectional_iterator_tag{};
5466 return forward_iterator_tag{};
5469 friend class adjacent_view;
5471#ifndef __clang__ // LLVM-61763 workaround
5472 template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
5473 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5474 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5475 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5476 range_reference_t<_Wp>>>
5477 friend class adjacent_transform_view;
5481 using iterator_category = input_iterator_tag;
5482 using iterator_concept = decltype(_S_iter_concept());
5483 using value_type = conditional_t<_Nm == 2,
5484 pair<range_value_t<_Base>, range_value_t<_Base>>,
5485 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5486 using difference_type = range_difference_t<_Base>;
5488 _Iterator() = default;
5491 _Iterator(_Iterator<!_Const> __i)
5492 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5494 for (size_t __j = 0; __j < _Nm; ++__j)
5495 _M_current[__j] = std::move(__i._M_current[__j]);
5501 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5502 return __detail::__tuple_transform(__f, _M_current);
5505 constexpr _Iterator&
5508 for (auto& __i : _M_current)
5521 constexpr _Iterator&
5522 operator--() requires bidirectional_range<_Base>
5524 for (auto& __i : _M_current)
5530 operator--(int) requires bidirectional_range<_Base>
5537 constexpr _Iterator&
5538 operator+=(difference_type __x)
5539 requires random_access_range<_Base>
5541 for (auto& __i : _M_current)
5546 constexpr _Iterator&
5547 operator-=(difference_type __x)
5548 requires random_access_range<_Base>
5550 for (auto& __i : _M_current)
5556 operator[](difference_type __n) const
5557 requires random_access_range<_Base>
5559 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5560 return __detail::__tuple_transform(__f, _M_current);
5563 friend constexpr bool
5564 operator==(const _Iterator& __x, const _Iterator& __y)
5565 { return __x._M_current.back() == __y._M_current.back(); }
5567 friend constexpr bool
5568 operator<(const _Iterator& __x, const _Iterator& __y)
5569 requires random_access_range<_Base>
5570 { return __x._M_current.back() < __y._M_current.back(); }
5572 friend constexpr bool
5573 operator>(const _Iterator& __x, const _Iterator& __y)
5574 requires random_access_range<_Base>
5575 { return __y < __x; }
5577 friend constexpr bool
5578 operator<=(const _Iterator& __x, const _Iterator& __y)
5579 requires random_access_range<_Base>
5580 { return !(__y < __x); }
5582 friend constexpr bool
5583 operator>=(const _Iterator& __x, const _Iterator& __y)
5584 requires random_access_range<_Base>
5585 { return !(__x < __y); }
5587 friend constexpr auto
5588 operator<=>(const _Iterator& __x, const _Iterator& __y)
5589 requires random_access_range<_Base>
5590 && three_way_comparable<iterator_t<_Base>>
5591 { return __x._M_current.back() <=> __y._M_current.back(); }
5593 friend constexpr _Iterator
5594 operator+(const _Iterator& __i, difference_type __n)
5595 requires random_access_range<_Base>
5602 friend constexpr _Iterator
5603 operator+(difference_type __n, const _Iterator& __i)
5604 requires random_access_range<_Base>
5611 friend constexpr _Iterator
5612 operator-(const _Iterator& __i, difference_type __n)
5613 requires random_access_range<_Base>
5620 friend constexpr difference_type
5621 operator-(const _Iterator& __x, const _Iterator& __y)
5622 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5623 { return __x._M_current.back() - __y._M_current.back(); }
5625 friend constexpr auto
5626 iter_move(const _Iterator& __i)
5627 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5629 friend constexpr void
5630 iter_swap(const _Iterator& __l, const _Iterator& __r)
5631 requires indirectly_swappable<iterator_t<_Base>>
5633 for (size_t __i = 0; __i < _Nm; __i++)
5634 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5638 template<forward_range _Vp, size_t _Nm>
5639 requires view<_Vp> && (_Nm > 0)
5640 template<bool _Const>
5641 class adjacent_view<_Vp, _Nm>::_Sentinel
5643 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5645 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5648 _Sentinel(sentinel_t<_Base> __end)
5652 friend class adjacent_view;
5655 _Sentinel() = default;
5658 _Sentinel(_Sentinel<!_Const> __i)
5659 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5660 : _M_end(std::move(__i._M_end))
5663 template<bool _OtherConst>
5664 requires sentinel_for<sentinel_t<_Base>,
5665 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5666 friend constexpr bool
5667 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5668 { return __x._M_current.back() == __y._M_end; }
5670 template<bool _OtherConst>
5671 requires sized_sentinel_for<sentinel_t<_Base>,
5672 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5673 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5674 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5675 { return __x._M_current.back() - __y._M_end; }
5677 template<bool _OtherConst>
5678 requires sized_sentinel_for<sentinel_t<_Base>,
5679 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5680 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5681 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5682 { return __y._M_end - __x._M_current.back(); }
5689 template<size_t _Nm, typename _Range>
5690 concept __can_adjacent_view
5691 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5694 template<size_t _Nm>
5695 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5697 template<viewable_range _Range>
5698 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5700 operator() [[nodiscard]] (_Range&& __r) const
5702 if constexpr (_Nm == 0)
5703 return views::empty<tuple<>>;
5705 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5709 template<size_t _Nm>
5710 inline constexpr _Adjacent<_Nm> adjacent;
5712 inline constexpr auto pairwise = adjacent<2>;
5715 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5716 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5717 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5718 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5719 range_reference_t<_Vp>>>
5720 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5722 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5723 adjacent_view<_Vp, _Nm> _M_inner;
5725 using _InnerView = adjacent_view<_Vp, _Nm>;
5727 template<bool _Const>
5728 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5730 template<bool _Const>
5731 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5733 template<bool> class _Iterator;
5734 template<bool> class _Sentinel;
5737 adjacent_transform_view() = default;
5740 adjacent_transform_view(_Vp __base, _Fp __fun)
5741 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5744 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5745 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5746 // 3947. Unexpected constraints on adjacent_transform_view::base()
5748 base() const & requires copy_constructible<_Vp>
5749 { return _M_inner.base(); }
5753 { return std::move(_M_inner.base()); }
5757 { return _Iterator<false>(*this, _M_inner.begin()); }
5761 requires range<const _InnerView>
5762 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5763 range_reference_t<const _Vp>>
5764 { return _Iterator<true>(*this, _M_inner.begin()); }
5769 if constexpr (common_range<_InnerView>)
5770 return _Iterator<false>(*this, _M_inner.end());
5772 return _Sentinel<false>(_M_inner.end());
5777 requires range<const _InnerView>
5778 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5779 range_reference_t<const _Vp>>
5781 if constexpr (common_range<const _InnerView>)
5782 return _Iterator<true>(*this, _M_inner.end());
5784 return _Sentinel<true>(_M_inner.end());
5788 size() requires sized_range<_InnerView>
5789 { return _M_inner.size(); }
5792 size() const requires sized_range<const _InnerView>
5793 { return _M_inner.size(); }
5796 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5797 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5798 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5799 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5800 range_reference_t<_Vp>>>
5801 template<bool _Const>
5802 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5804 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5805 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5807 _Parent* _M_parent = nullptr;
5808 _InnerIter<_Const> _M_inner;
5811 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5812 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5818 using __detail::__maybe_const_t;
5819 using __detail::__unarize;
5820 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5821 range_reference_t<_Base>>;
5822 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5823 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5824 // 3798. Rvalue reference and iterator_category
5825 if constexpr (!is_reference_v<_Res>)
5826 return input_iterator_tag{};
5827 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5828 return random_access_iterator_tag{};
5829 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5830 return bidirectional_iterator_tag{};
5831 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5832 return forward_iterator_tag{};
5834 return input_iterator_tag{};
5837 friend class adjacent_transform_view;
5840 using iterator_category = decltype(_S_iter_cat());
5841 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5843 = remove_cvref_t<invoke_result_t
5844 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5845 range_reference_t<_Base>>>;
5846 using difference_type = range_difference_t<_Base>;
5848 _Iterator() = default;
5851 _Iterator(_Iterator<!_Const> __i)
5852 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5853 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5856 constexpr decltype(auto)
5859 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5860 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5861 }, _M_inner._M_current);
5864 constexpr _Iterator&
5879 constexpr _Iterator&
5880 operator--() requires bidirectional_range<_Base>
5887 operator--(int) requires bidirectional_range<_Base>
5894 constexpr _Iterator&
5895 operator+=(difference_type __x) requires random_access_range<_Base>
5901 constexpr _Iterator&
5902 operator-=(difference_type __x) requires random_access_range<_Base>
5908 constexpr decltype(auto)
5909 operator[](difference_type __n) const requires random_access_range<_Base>
5911 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5912 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5913 }, _M_inner._M_current);
5916 friend constexpr bool
5917 operator==(const _Iterator& __x, const _Iterator& __y)
5918 { return __x._M_inner == __y._M_inner; }
5920 friend constexpr bool
5921 operator<(const _Iterator& __x, const _Iterator& __y)
5922 requires random_access_range<_Base>
5923 { return __x._M_inner < __y._M_inner; }
5925 friend constexpr bool
5926 operator>(const _Iterator& __x, const _Iterator& __y)
5927 requires random_access_range<_Base>
5928 { return __x._M_inner > __y._M_inner; }
5930 friend constexpr bool
5931 operator<=(const _Iterator& __x, const _Iterator& __y)
5932 requires random_access_range<_Base>
5933 { return __x._M_inner <= __y._M_inner; }
5935 friend constexpr bool
5936 operator>=(const _Iterator& __x, const _Iterator& __y)
5937 requires random_access_range<_Base>
5938 { return __x._M_inner >= __y._M_inner; }
5940 friend constexpr auto
5941 operator<=>(const _Iterator& __x, const _Iterator& __y)
5942 requires random_access_range<_Base> &&
5943 three_way_comparable<_InnerIter<_Const>>
5944 { return __x._M_inner <=> __y._M_inner; }
5946 friend constexpr _Iterator
5947 operator+(const _Iterator& __i, difference_type __n)
5948 requires random_access_range<_Base>
5949 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5951 friend constexpr _Iterator
5952 operator+(difference_type __n, const _Iterator& __i)
5953 requires random_access_range<_Base>
5954 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5956 friend constexpr _Iterator
5957 operator-(const _Iterator& __i, difference_type __n)
5958 requires random_access_range<_Base>
5959 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5961 friend constexpr difference_type
5962 operator-(const _Iterator& __x, const _Iterator& __y)
5963 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5964 { return __x._M_inner - __y._M_inner; }
5967 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5968 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5969 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5970 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5971 range_reference_t<_Vp>>>
5972 template<bool _Const>
5973 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5975 _InnerSent<_Const> _M_inner;
5978 _Sentinel(_InnerSent<_Const> __inner)
5982 friend class adjacent_transform_view;
5985 _Sentinel() = default;
5988 _Sentinel(_Sentinel<!_Const> __i)
5989 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5990 : _M_inner(std::move(__i._M_inner))
5993 template<bool _OtherConst>
5994 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5995 friend constexpr bool
5996 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5997 { return __x._M_inner == __y._M_inner; }
5999 template<bool _OtherConst>
6000 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6001 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6002 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6003 { return __x._M_inner - __y._M_inner; }
6005 template<bool _OtherConst>
6006 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6007 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6008 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
6009 { return __x._M_inner - __y._M_inner; }
6016 template<size_t _Nm, typename _Range, typename _Fp>
6017 concept __can_adjacent_transform_view
6018 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6019 (std::declval<_Range>(), std::declval<_Fp>()); };
6022 template<size_t _Nm>
6023 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6025 template<viewable_range _Range, typename _Fp>
6026 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6028 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
6030 if constexpr (_Nm == 0)
6031 return zip_transform(std::forward<_Fp>(__f));
6033 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6034 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6037 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6038 static constexpr int _S_arity = 2;
6039 static constexpr bool _S_has_simple_extra_args = true;
6042 template<size_t _Nm>
6043 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6045 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6047#endif // __cpp_lib_ranges_zip
6049#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6052 template<typename _Tp>
6053 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6055 _Tp __r = __num / __denom;
6056 if (__num % __denom)
6063 requires input_range<_Vp>
6064 class chunk_view : public view_interface<chunk_view<_Vp>>
6067 range_difference_t<_Vp> _M_n;
6068 range_difference_t<_Vp> _M_remainder = 0;
6069 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6076 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6077 : _M_base(std::move(__base)), _M_n(__n)
6078 { __glibcxx_assert(__n >= 0); }
6081 base() const & requires copy_constructible<_Vp>
6086 { return std::move(_M_base); }
6088 constexpr _OuterIter
6091 _M_current = ranges::begin(_M_base);
6092 _M_remainder = _M_n;
6093 return _OuterIter(*this);
6096 constexpr default_sentinel_t
6097 end() const noexcept
6098 { return default_sentinel; }
6101 size() requires sized_range<_Vp>
6103 return __detail::__to_unsigned_like(__detail::__div_ceil
6104 (ranges::distance(_M_base), _M_n));
6108 size() const requires sized_range<const _Vp>
6110 return __detail::__to_unsigned_like(__detail::__div_ceil
6111 (ranges::distance(_M_base), _M_n));
6115 template<typename _Range>
6116 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6119 requires input_range<_Vp>
6120 class chunk_view<_Vp>::_OuterIter
6122 chunk_view* _M_parent;
6125 _OuterIter(chunk_view& __parent) noexcept
6126 : _M_parent(std::__addressof(__parent))
6132 using iterator_concept = input_iterator_tag;
6133 using difference_type = range_difference_t<_Vp>;
6137 _OuterIter(_OuterIter&&) = default;
6138 _OuterIter& operator=(_OuterIter&&) = default;
6140 constexpr value_type
6143 __glibcxx_assert(*this != default_sentinel);
6144 return value_type(*_M_parent);
6147 constexpr _OuterIter&
6150 __glibcxx_assert(*this != default_sentinel);
6151 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6152 ranges::end(_M_parent->_M_base));
6153 _M_parent->_M_remainder = _M_parent->_M_n;
6161 friend constexpr bool
6162 operator==(const _OuterIter& __x, default_sentinel_t)
6164 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6165 && __x._M_parent->_M_remainder != 0;
6168 friend constexpr difference_type
6169 operator-(default_sentinel_t, const _OuterIter& __x)
6170 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6172 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6174 if (__dist < __x._M_parent->_M_remainder)
6175 return __dist == 0 ? 0 : 1;
6177 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6178 __x._M_parent->_M_n);
6181 friend constexpr difference_type
6182 operator-(const _OuterIter& __x, default_sentinel_t __y)
6183 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6184 { return -(__y - __x); }
6188 requires input_range<_Vp>
6189 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6192 chunk_view* _M_parent;
6195 value_type(chunk_view& __parent) noexcept
6196 : _M_parent(std::__addressof(__parent))
6202 constexpr _InnerIter
6203 begin() const noexcept
6204 { return _InnerIter(*_M_parent); }
6206 constexpr default_sentinel_t
6207 end() const noexcept
6208 { return default_sentinel; }
6212 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6214 return __detail::__to_unsigned_like
6215 (ranges::min(_M_parent->_M_remainder,
6216 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6221 requires input_range<_Vp>
6222 class chunk_view<_Vp>::_InnerIter
6224 chunk_view* _M_parent;
6227 _InnerIter(chunk_view& __parent) noexcept
6228 : _M_parent(std::__addressof(__parent))
6231 friend _OuterIter::value_type;
6234 using iterator_concept = input_iterator_tag;
6235 using difference_type = range_difference_t<_Vp>;
6236 using value_type = range_value_t<_Vp>;
6238 _InnerIter(_InnerIter&&) = default;
6239 _InnerIter& operator=(_InnerIter&&) = default;
6241 constexpr const iterator_t<_Vp>&
6243 { return *_M_parent->_M_current; }
6245 constexpr range_reference_t<_Vp>
6248 __glibcxx_assert(*this != default_sentinel);
6249 return **_M_parent->_M_current;
6252 constexpr _InnerIter&
6255 __glibcxx_assert(*this != default_sentinel);
6256 ++*_M_parent->_M_current;
6257 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6258 _M_parent->_M_remainder = 0;
6260 --_M_parent->_M_remainder;
6268 friend constexpr bool
6269 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6270 { return __x._M_parent->_M_remainder == 0; }
6272 friend constexpr difference_type
6273 operator-(default_sentinel_t, const _InnerIter& __x)
6274 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6276 return ranges::min(__x._M_parent->_M_remainder,
6277 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6280 friend constexpr difference_type
6281 operator-(const _InnerIter& __x, default_sentinel_t __y)
6282 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6283 { return -(__y - __x); }
6285 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6286 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
6287 friend constexpr range_rvalue_reference_t<_Vp>
6288 iter_move(const _InnerIter& __i)
6289 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6290 { return ranges::iter_move(*__i._M_parent->_M_current); }
6292 friend constexpr void
6293 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
6294 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6295 *__x._M_parent->_M_current)))
6296 requires indirectly_swappable<iterator_t<_Vp>>
6297 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6301 requires forward_range<_Vp>
6302 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6305 range_difference_t<_Vp> _M_n;
6306 template<bool> class _Iterator;
6310 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6311 : _M_base(std::move(__base)), _M_n(__n)
6312 { __glibcxx_assert(__n > 0); }
6315 base() const & requires copy_constructible<_Vp>
6320 { return std::move(_M_base); }
6323 begin() requires (!__detail::__simple_view<_Vp>)
6324 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6327 begin() const requires forward_range<const _Vp>
6328 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6331 end() requires (!__detail::__simple_view<_Vp>)
6333 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6335 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6336 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6338 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6339 return _Iterator<false>(this, ranges::end(_M_base));
6341 return default_sentinel;
6345 end() const requires forward_range<const _Vp>
6347 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6349 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6350 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6352 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6353 return _Iterator<true>(this, ranges::end(_M_base));
6355 return default_sentinel;
6359 size() requires sized_range<_Vp>
6361 return __detail::__to_unsigned_like(__detail::__div_ceil
6362 (ranges::distance(_M_base), _M_n));
6366 size() const requires sized_range<const _Vp>
6368 return __detail::__to_unsigned_like(__detail::__div_ceil
6369 (ranges::distance(_M_base), _M_n));
6373 template<typename _Vp>
6374 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6375 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6378 requires forward_range<_Vp>
6379 template<bool _Const>
6380 class chunk_view<_Vp>::_Iterator
6382 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6383 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6385 iterator_t<_Base> _M_current = iterator_t<_Base>();
6386 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6387 range_difference_t<_Base> _M_n = 0;
6388 range_difference_t<_Base> _M_missing = 0;
6391 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6392 range_difference_t<_Base> __missing = 0)
6393 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6394 _M_n(__parent->_M_n), _M_missing(__missing)
6400 if constexpr (random_access_range<_Base>)
6401 return random_access_iterator_tag{};
6402 else if constexpr (bidirectional_range<_Base>)
6403 return bidirectional_iterator_tag{};
6405 return forward_iterator_tag{};
6411 using iterator_category = input_iterator_tag;
6412 using iterator_concept = decltype(_S_iter_cat());
6413 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6414 using difference_type = range_difference_t<_Base>;
6416 _Iterator() = default;
6418 constexpr _Iterator(_Iterator<!_Const> __i)
6420 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6421 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6422 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6423 _M_n(__i._M_n), _M_missing(__i._M_missing)
6426 constexpr iterator_t<_Base>
6428 { return _M_current; }
6430 constexpr value_type
6433 __glibcxx_assert(_M_current != _M_end);
6434 return views::take(subrange(_M_current, _M_end), _M_n);
6437 constexpr _Iterator&
6440 __glibcxx_assert(_M_current != _M_end);
6441 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6453 constexpr _Iterator&
6454 operator--() requires bidirectional_range<_Base>
6456 ranges::advance(_M_current, _M_missing - _M_n);
6462 operator--(int) requires bidirectional_range<_Base>
6469 constexpr _Iterator&
6470 operator+=(difference_type __x)
6471 requires random_access_range<_Base>
6475 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6476 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6480 ranges::advance(_M_current, _M_n * __x + _M_missing);
6486 constexpr _Iterator&
6487 operator-=(difference_type __x)
6488 requires random_access_range<_Base>
6489 { return *this += -__x; }
6491 constexpr value_type
6492 operator[](difference_type __n) const
6493 requires random_access_range<_Base>
6494 { return *(*this + __n); }
6496 friend constexpr bool
6497 operator==(const _Iterator& __x, const _Iterator& __y)
6498 { return __x._M_current == __y._M_current; }
6500 friend constexpr bool
6501 operator==(const _Iterator& __x, default_sentinel_t)
6502 { return __x._M_current == __x._M_end; }
6504 friend constexpr bool
6505 operator<(const _Iterator& __x, const _Iterator& __y)
6506 requires random_access_range<_Base>
6507 { return __x._M_current > __y._M_current; }
6509 friend constexpr bool
6510 operator>(const _Iterator& __x, const _Iterator& __y)
6511 requires random_access_range<_Base>
6512 { return __y < __x; }
6514 friend constexpr bool
6515 operator<=(const _Iterator& __x, const _Iterator& __y)
6516 requires random_access_range<_Base>
6517 { return !(__y < __x); }
6519 friend constexpr bool
6520 operator>=(const _Iterator& __x, const _Iterator& __y)
6521 requires random_access_range<_Base>
6522 { return !(__x < __y); }
6524 friend constexpr auto
6525 operator<=>(const _Iterator& __x, const _Iterator& __y)
6526 requires random_access_range<_Base>
6527 && three_way_comparable<iterator_t<_Base>>
6528 { return __x._M_current <=> __y._M_current; }
6530 friend constexpr _Iterator
6531 operator+(const _Iterator& __i, difference_type __n)
6532 requires random_access_range<_Base>
6539 friend constexpr _Iterator
6540 operator+(difference_type __n, const _Iterator& __i)
6541 requires random_access_range<_Base>
6548 friend constexpr _Iterator
6549 operator-(const _Iterator& __i, difference_type __n)
6550 requires random_access_range<_Base>
6557 friend constexpr difference_type
6558 operator-(const _Iterator& __x, const _Iterator& __y)
6559 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6561 return (__x._M_current - __y._M_current
6562 + __x._M_missing - __y._M_missing) / __x._M_n;
6565 friend constexpr difference_type
6566 operator-(default_sentinel_t __y, const _Iterator& __x)
6567 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6568 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6570 friend constexpr difference_type
6571 operator-(const _Iterator& __x, default_sentinel_t __y)
6572 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6573 { return -(__y - __x); }
6580 template<typename _Range, typename _Dp>
6581 concept __can_chunk_view
6582 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6585 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6587 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6588 requires __detail::__can_chunk_view<_Range, _Dp>
6590 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6591 { return chunk_view(std::forward<_Range>(__r), __n); }
6593 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6594 static constexpr int _S_arity = 2;
6595 static constexpr bool _S_has_simple_extra_args = true;
6598 inline constexpr _Chunk chunk;
6600#endif // __cpp_lib_ranges_chunk
6602#ifdef __cpp_lib_ranges_slide // C++ >= 23
6605 template<typename _Vp>
6606 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6608 template<typename _Vp>
6609 concept __slide_caches_last
6610 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6612 template<typename _Vp>
6613 concept __slide_caches_first
6614 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6617 template<forward_range _Vp>
6619 class slide_view : public view_interface<slide_view<_Vp>>
6622 range_difference_t<_Vp> _M_n;
6623 [[no_unique_address]]
6624 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6625 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6626 [[no_unique_address]]
6627 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6628 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6630 template<bool> class _Iterator;
6635 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6636 : _M_base(std::move(__base)), _M_n(__n)
6637 { __glibcxx_assert(__n > 0); }
6639 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6640 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
6642 base() const & requires copy_constructible<_Vp>
6647 { return std::move(_M_base); }
6650 begin() requires (!(__detail::__simple_view<_Vp>
6651 && __detail::__slide_caches_nothing<const _Vp>))
6653 if constexpr (__detail::__slide_caches_first<_Vp>)
6655 iterator_t<_Vp> __it;
6656 if (_M_cached_begin._M_has_value())
6657 __it = _M_cached_begin._M_get(_M_base);
6660 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6661 _M_cached_begin._M_set(_M_base, __it);
6663 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6666 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6670 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6671 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6674 end() requires (!(__detail::__simple_view<_Vp>
6675 && __detail::__slide_caches_nothing<const _Vp>))
6677 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6678 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6680 else if constexpr (__detail::__slide_caches_last<_Vp>)
6682 iterator_t<_Vp> __it;
6683 if (_M_cached_end._M_has_value())
6684 __it = _M_cached_end._M_get(_M_base);
6687 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6688 _M_cached_end._M_set(_M_base, __it);
6690 return _Iterator<false>(std::move(__it), _M_n);
6692 else if constexpr (common_range<_Vp>)
6693 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6695 return _Sentinel(ranges::end(_M_base));
6699 end() const requires __detail::__slide_caches_nothing<const _Vp>
6700 { return begin() + range_difference_t<const _Vp>(size()); }
6703 size() requires sized_range<_Vp>
6705 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6708 return __detail::__to_unsigned_like(__sz);
6712 size() const requires sized_range<const _Vp>
6714 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6717 return __detail::__to_unsigned_like(__sz);
6721 template<typename _Range>
6722 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6724 template<typename _Vp>
6725 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6726 = enable_borrowed_range<_Vp>;
6728 template<forward_range _Vp>
6730 template<bool _Const>
6731 class slide_view<_Vp>::_Iterator
6733 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6734 static constexpr bool _S_last_elt_present
6735 = __detail::__slide_caches_first<_Base>;
6737 iterator_t<_Base> _M_current = iterator_t<_Base>();
6738 [[no_unique_address]]
6739 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6740 _M_last_elt = decltype(_M_last_elt)();
6741 range_difference_t<_Base> _M_n = 0;
6744 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6745 requires (!_S_last_elt_present)
6746 : _M_current(__current), _M_n(__n)
6750 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6751 range_difference_t<_Base> __n)
6752 requires _S_last_elt_present
6753 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6759 if constexpr (random_access_range<_Base>)
6760 return random_access_iterator_tag{};
6761 else if constexpr (bidirectional_range<_Base>)
6762 return bidirectional_iterator_tag{};
6764 return forward_iterator_tag{};
6768 friend slide_view::_Sentinel;
6771 using iterator_category = input_iterator_tag;
6772 using iterator_concept = decltype(_S_iter_concept());
6773 using value_type = decltype(views::counted(_M_current, _M_n));
6774 using difference_type = range_difference_t<_Base>;
6776 _Iterator() = default;
6779 _Iterator(_Iterator<!_Const> __i)
6780 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6781 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6786 { return views::counted(_M_current, _M_n); }
6788 constexpr _Iterator&
6792 if constexpr (_S_last_elt_present)
6805 constexpr _Iterator&
6806 operator--() requires bidirectional_range<_Base>
6809 if constexpr (_S_last_elt_present)
6815 operator--(int) requires bidirectional_range<_Base>
6822 constexpr _Iterator&
6823 operator+=(difference_type __x)
6824 requires random_access_range<_Base>
6827 if constexpr (_S_last_elt_present)
6832 constexpr _Iterator&
6833 operator-=(difference_type __x)
6834 requires random_access_range<_Base>
6837 if constexpr (_S_last_elt_present)
6843 operator[](difference_type __n) const
6844 requires random_access_range<_Base>
6845 { return views::counted(_M_current + __n, _M_n); }
6847 friend constexpr bool
6848 operator==(const _Iterator& __x, const _Iterator& __y)
6850 if constexpr (_S_last_elt_present)
6851 return __x._M_last_elt == __y._M_last_elt;
6853 return __x._M_current == __y._M_current;
6856 friend constexpr bool
6857 operator<(const _Iterator& __x, const _Iterator& __y)
6858 requires random_access_range<_Base>
6859 { return __x._M_current < __y._M_current; }
6861 friend constexpr bool
6862 operator>(const _Iterator& __x, const _Iterator& __y)
6863 requires random_access_range<_Base>
6864 { return __y < __x; }
6866 friend constexpr bool
6867 operator<=(const _Iterator& __x, const _Iterator& __y)
6868 requires random_access_range<_Base>
6869 { return !(__y < __x); }
6871 friend constexpr bool
6872 operator>=(const _Iterator& __x, const _Iterator& __y)
6873 requires random_access_range<_Base>
6874 { return !(__x < __y); }
6876 friend constexpr auto
6877 operator<=>(const _Iterator& __x, const _Iterator& __y)
6878 requires random_access_range<_Base>
6879 && three_way_comparable<iterator_t<_Base>>
6880 { return __x._M_current <=> __y._M_current; }
6882 friend constexpr _Iterator
6883 operator+(const _Iterator& __i, difference_type __n)
6884 requires random_access_range<_Base>
6891 friend constexpr _Iterator
6892 operator+(difference_type __n, const _Iterator& __i)
6893 requires random_access_range<_Base>
6900 friend constexpr _Iterator
6901 operator-(const _Iterator& __i, difference_type __n)
6902 requires random_access_range<_Base>
6909 friend constexpr difference_type
6910 operator-(const _Iterator& __x, const _Iterator& __y)
6911 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6913 if constexpr (_S_last_elt_present)
6914 return __x._M_last_elt - __y._M_last_elt;
6916 return __x._M_current - __y._M_current;
6920 template<forward_range _Vp>
6922 class slide_view<_Vp>::_Sentinel
6924 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6927 _Sentinel(sentinel_t<_Vp> __end)
6934 _Sentinel() = default;
6936 friend constexpr bool
6937 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6938 { return __x._M_last_elt == __y._M_end; }
6940 friend constexpr range_difference_t<_Vp>
6941 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6942 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6943 { return __x._M_last_elt - __y._M_end; }
6945 friend constexpr range_difference_t<_Vp>
6946 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6947 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6948 { return __y._M_end -__x._M_last_elt; }
6955 template<typename _Range, typename _Dp>
6956 concept __can_slide_view
6957 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6960 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6962 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6963 requires __detail::__can_slide_view<_Range, _Dp>
6965 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6966 { return slide_view(std::forward<_Range>(__r), __n); }
6968 using __adaptor::_RangeAdaptor<_Slide>::operator();
6969 static constexpr int _S_arity = 2;
6970 static constexpr bool _S_has_simple_extra_args = true;
6973 inline constexpr _Slide slide;
6975#endif // __cpp_lib_ranges_slide
6977#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
6978 template<forward_range _Vp,
6979 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6980 requires view<_Vp> && is_object_v<_Pred>
6981 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6983 _Vp _M_base = _Vp();
6984 __detail::__box<_Pred> _M_pred;
6985 __detail::_CachedPosition<_Vp> _M_cached_begin;
6987 constexpr iterator_t<_Vp>
6988 _M_find_next(iterator_t<_Vp> __current)
6990 __glibcxx_assert(_M_pred.has_value());
6991 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6992 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6994 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6995 return ranges::next(__it, 1, ranges::end(_M_base));
6998 constexpr iterator_t<_Vp>
6999 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
7001 __glibcxx_assert(_M_pred.has_value());
7002 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
7003 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
7005 auto __rbegin = std::make_reverse_iterator(__current);
7006 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
7007 __glibcxx_assert(__rbegin != __rend);
7008 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7009 return ranges::prev(__it, 1, ranges::begin(_M_base));
7015 chunk_by_view() requires (default_initializable<_Vp>
7016 && default_initializable<_Pred>)
7020 chunk_by_view(_Vp __base, _Pred __pred)
7021 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
7025 base() const & requires copy_constructible<_Vp>
7030 { return std::move(_M_base); }
7032 constexpr const _Pred&
7034 { return *_M_pred; }
7039 __glibcxx_assert(_M_pred.has_value());
7040 iterator_t<_Vp> __it;
7041 if (_M_cached_begin._M_has_value())
7042 __it = _M_cached_begin._M_get(_M_base);
7045 __it = _M_find_next(ranges::begin(_M_base));
7046 _M_cached_begin._M_set(_M_base, __it);
7048 return _Iterator(*this, ranges::begin(_M_base), __it);
7054 if constexpr (common_range<_Vp>)
7055 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
7057 return default_sentinel;
7061 template<typename _Range, typename _Pred>
7062 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7064 template<forward_range _Vp,
7065 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7066 requires view<_Vp> && is_object_v<_Pred>
7067 class chunk_by_view<_Vp, _Pred>::_Iterator
7069 chunk_by_view* _M_parent = nullptr;
7070 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7071 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7074 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7075 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7081 if constexpr (bidirectional_range<_Vp>)
7082 return bidirectional_iterator_tag{};
7084 return forward_iterator_tag{};
7087 friend chunk_by_view;
7090 using value_type = subrange<iterator_t<_Vp>>;
7091 using difference_type = range_difference_t<_Vp>;
7092 using iterator_category = input_iterator_tag;
7093 using iterator_concept = decltype(_S_iter_concept());
7095 _Iterator() = default;
7097 constexpr value_type
7100 __glibcxx_assert(_M_current != _M_next);
7101 return ranges::subrange(_M_current, _M_next);
7104 constexpr _Iterator&
7107 __glibcxx_assert(_M_current != _M_next);
7108 _M_current = _M_next;
7109 _M_next = _M_parent->_M_find_next(_M_current);
7121 constexpr _Iterator&
7122 operator--() requires bidirectional_range<_Vp>
7124 _M_next = _M_current;
7125 _M_current = _M_parent->_M_find_prev(_M_next);
7130 operator--(int) requires bidirectional_range<_Vp>
7137 friend constexpr bool
7138 operator==(const _Iterator& __x, const _Iterator& __y)
7139 { return __x._M_current == __y._M_current; }
7141 friend constexpr bool
7142 operator==(const _Iterator& __x, default_sentinel_t)
7143 { return __x._M_current == __x._M_next; }
7150 template<typename _Range, typename _Pred>
7151 concept __can_chunk_by_view
7152 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7155 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7157 template<viewable_range _Range, typename _Pred>
7158 requires __detail::__can_chunk_by_view<_Range, _Pred>
7160 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7161 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7163 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7164 static constexpr int _S_arity = 2;
7165 static constexpr bool _S_has_simple_extra_args = true;
7168 inline constexpr _ChunkBy chunk_by;
7170#endif // __cpp_lib_ranges_chunk_by
7172#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7175 template<typename _Range, typename _Pattern>
7176 concept __compatible_joinable_ranges
7177 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7178 && common_reference_with<range_reference_t<_Range>,
7179 range_reference_t<_Pattern>>
7180 && common_reference_with<range_rvalue_reference_t<_Range>,
7181 range_rvalue_reference_t<_Pattern>>;
7183 template<typename _Range>
7184 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7187 template<input_range _Vp, forward_range _Pattern>
7188 requires view<_Vp> && view<_Pattern>
7189 && input_range<range_reference_t<_Vp>>
7190 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7191 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7193 using _InnerRange = range_reference_t<_Vp>;
7195 _Vp _M_base = _Vp();
7196 [[no_unique_address]]
7197 __detail::__maybe_present_t<!forward_range<_Vp>,
7198 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7199 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7200 _Pattern _M_pattern = _Pattern();
7202 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7203 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7204 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7206 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7207 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7208 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7210 template<bool _Const>
7211 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7213 template<bool _Const>
7217 template<bool _Const>
7218 requires _S_ref_is_glvalue<_Const>
7219 && forward_range<_Base<_Const>>
7220 && forward_range<_InnerBase<_Const>>
7221 struct __iter_cat<_Const>
7227 using _OuterIter = join_with_view::_OuterIter<_Const>;
7228 using _InnerIter = join_with_view::_InnerIter<_Const>;
7229 using _PatternIter = join_with_view::_PatternIter<_Const>;
7230 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7231 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7232 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7233 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7234 // 3798. Rvalue reference and iterator_category
7235 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7236 iter_reference_t<_PatternIter>>>)
7237 return input_iterator_tag{};
7238 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7239 && derived_from<_InnerCat, bidirectional_iterator_tag>
7240 && derived_from<_PatternCat, bidirectional_iterator_tag>
7241 && common_range<_InnerBase<_Const>>
7242 && common_range<_PatternBase<_Const>>)
7243 return bidirectional_iterator_tag{};
7244 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7245 && derived_from<_InnerCat, forward_iterator_tag>
7246 && derived_from<_PatternCat, forward_iterator_tag>)
7247 return forward_iterator_tag{};
7249 return input_iterator_tag{};
7252 using iterator_category = decltype(_S_iter_cat());
7255 template<bool> struct _Iterator;
7256 template<bool> struct _Sentinel;
7259 join_with_view() requires (default_initializable<_Vp>
7260 && default_initializable<_Pattern>)
7264 join_with_view(_Vp __base, _Pattern __pattern)
7265 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7268 template<input_range _Range>
7269 requires constructible_from<_Vp, views::all_t<_Range>>
7270 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7272 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7273 : _M_base(views::all(std::forward<_Range>(__r))),
7274 _M_pattern(views::single(std::move(__e)))
7278 base() const& requires copy_constructible<_Vp>
7283 { return std::move(_M_base); }
7288 if constexpr (forward_range<_Vp>)
7290 constexpr bool __use_const = is_reference_v<_InnerRange>
7291 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7292 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7296 _M_outer_it = ranges::begin(_M_base);
7297 return _Iterator<false>{*this};
7303 requires forward_range<const _Vp>
7304 && forward_range<const _Pattern>
7305 && is_reference_v<range_reference_t<const _Vp>>
7306 && input_range<range_reference_t<const _Vp>>
7307 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7312 constexpr bool __use_const
7313 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7314 if constexpr (is_reference_v<_InnerRange>
7315 && forward_range<_Vp> && common_range<_Vp>
7316 && forward_range<_InnerRange> && common_range<_InnerRange>)
7317 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7319 return _Sentinel<__use_const>{*this};
7324 requires forward_range<const _Vp>
7325 && forward_range<const _Pattern>
7326 && is_reference_v<range_reference_t<const _Vp>>
7327 && input_range<range_reference_t<const _Vp>>
7329 using _InnerConstRange = range_reference_t<const _Vp>;
7330 if constexpr (forward_range<_InnerConstRange>
7331 && common_range<const _Vp>
7332 && common_range<_InnerConstRange>)
7333 return _Iterator<true>{*this, ranges::end(_M_base)};
7335 return _Sentinel<true>{*this};
7339 template<typename _Range, typename _Pattern>
7340 join_with_view(_Range&&, _Pattern&&)
7341 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7343 template<input_range _Range>
7344 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7345 -> join_with_view<views::all_t<_Range>,
7346 single_view<range_value_t<range_reference_t<_Range>>>>;
7348 template<input_range _Vp, forward_range _Pattern>
7349 requires view<_Vp> && view<_Pattern>
7350 && input_range<range_reference_t<_Vp>>
7351 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7352 template<bool _Const>
7353 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7355 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7356 using _Base = join_with_view::_Base<_Const>;
7357 using _InnerBase = join_with_view::_InnerBase<_Const>;
7358 using _PatternBase = join_with_view::_PatternBase<_Const>;
7360 using _OuterIter = join_with_view::_OuterIter<_Const>;
7361 using _InnerIter = join_with_view::_InnerIter<_Const>;
7362 using _PatternIter = join_with_view::_PatternIter<_Const>;
7364 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7366 _Parent* _M_parent = nullptr;
7367 [[no_unique_address]]
7368 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it;
7369 variant<_PatternIter, _InnerIter> _M_inner_it;
7371 constexpr _OuterIter&
7374 if constexpr (forward_range<_Base>)
7377 return *_M_parent->_M_outer_it;
7380 constexpr const _OuterIter&
7381 _M_get_outer() const
7383 if constexpr (forward_range<_Base>)
7386 return *_M_parent->_M_outer_it;
7390 _Iterator(_Parent& __parent, _OuterIter __outer)
7391 requires forward_range<_Base>
7392 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7394 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7396 auto&& __inner = _M_update_inner();
7397 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7403 _Iterator(_Parent& __parent)
7404 requires (!forward_range<_Base>)
7405 : _M_parent(std::__addressof(__parent))
7407 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7409 auto&& __inner = _M_update_inner();
7410 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7418 _OuterIter& __outer = _M_get_outer();
7419 if constexpr (_S_ref_is_glvalue)
7420 return __detail::__as_lvalue(*__outer);
7422 return _M_parent->_M_inner._M_emplace_deref(__outer);
7428 if constexpr (_S_ref_is_glvalue)
7429 return __detail::__as_lvalue(*_M_get_outer());
7431 return *_M_parent->_M_inner;
7439 if (_M_inner_it.index() == 0)
7441 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7444 auto&& __inner = _M_update_inner();
7445 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7449 auto&& __inner = _M_get_inner();
7450 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7453 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7455 if constexpr (_S_ref_is_glvalue)
7456 _M_inner_it.template emplace<0>();
7460 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7468 if constexpr (_S_ref_is_glvalue
7469 && bidirectional_range<_Base>
7470 && __detail::__bidirectional_common<_InnerBase>
7471 && __detail::__bidirectional_common<_PatternBase>)
7472 return bidirectional_iterator_tag{};
7473 else if constexpr (_S_ref_is_glvalue
7474 && forward_range<_Base>
7475 && forward_range<_InnerBase>)
7476 return forward_iterator_tag{};
7478 return input_iterator_tag{};
7481 friend join_with_view;
7484 using iterator_concept = decltype(_S_iter_concept());
7485 // iterator_category defined in join_with_view::__iter_cat
7486 using value_type = common_type_t<iter_value_t<_InnerIter>,
7487 iter_value_t<_PatternIter>>;
7488 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7489 iter_difference_t<_InnerIter>,
7490 iter_difference_t<_PatternIter>>;
7492 _Iterator() = default;
7495 _Iterator(_Iterator<!_Const> __i)
7497 && convertible_to<iterator_t<_Vp>, _OuterIter>
7498 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7499 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7500 : _M_parent(__i._M_parent),
7501 _M_outer_it(std::move(__i._M_outer_it))
7503 if (__i._M_inner_it.index() == 0)
7504 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7506 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7509 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7510 iter_reference_t<_PatternIter>>
7513 if (_M_inner_it.index() == 0)
7514 return *std::get<0>(_M_inner_it);
7516 return *std::get<1>(_M_inner_it);
7519 constexpr _Iterator&
7522 if (_M_inner_it.index() == 0)
7523 ++std::get<0>(_M_inner_it);
7525 ++std::get<1>(_M_inner_it);
7536 requires _S_ref_is_glvalue
7537 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7539 _Iterator __tmp = *this;
7544 constexpr _Iterator&
7546 requires _S_ref_is_glvalue
7547 && bidirectional_range<_Base>
7548 && __detail::__bidirectional_common<_InnerBase>
7549 && __detail::__bidirectional_common<_PatternBase>
7551 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7553 auto&& __inner = *--_M_outer_it;
7554 _M_inner_it.template emplace<1>(ranges::end(__inner));
7559 if (_M_inner_it.index() == 0)
7561 auto& __it = std::get<0>(_M_inner_it);
7562 if (__it == ranges::begin(_M_parent->_M_pattern))
7564 auto&& __inner = *--_M_outer_it;
7565 _M_inner_it.template emplace<1>(ranges::end(__inner));
7572 auto& __it = std::get<1>(_M_inner_it);
7573 auto&& __inner = *_M_outer_it;
7574 if (__it == ranges::begin(__inner))
7575 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7581 if (_M_inner_it.index() == 0)
7582 --std::get<0>(_M_inner_it);
7584 --std::get<1>(_M_inner_it);
7590 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7591 && __detail::__bidirectional_common<_InnerBase>
7592 && __detail::__bidirectional_common<_PatternBase>
7594 _Iterator __tmp = *this;
7599 friend constexpr bool
7600 operator==(const _Iterator& __x, const _Iterator& __y)
7601 requires _S_ref_is_glvalue
7602 && forward_range<_Base> && equality_comparable<_InnerIter>
7603 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7605 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7606 iter_rvalue_reference_t<_PatternIter>>
7607 iter_move(const _Iterator& __x)
7609 if (__x._M_inner_it.index() == 0)
7610 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7612 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7615 friend constexpr void
7616 iter_swap(const _Iterator& __x, const _Iterator& __y)
7617 requires indirectly_swappable<_InnerIter, _PatternIter>
7619 if (__x._M_inner_it.index() == 0)
7621 if (__y._M_inner_it.index() == 0)
7622 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7624 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7628 if (__y._M_inner_it.index() == 0)
7629 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7631 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7636 template<input_range _Vp, forward_range _Pattern>
7637 requires view<_Vp> && view<_Pattern>
7638 && input_range<range_reference_t<_Vp>>
7639 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7640 template<bool _Const>
7641 class join_with_view<_Vp, _Pattern>::_Sentinel
7643 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7644 using _Base = join_with_view::_Base<_Const>;
7646 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7649 _Sentinel(_Parent& __parent)
7650 : _M_end(ranges::end(__parent._M_base))
7653 friend join_with_view;
7656 _Sentinel() = default;
7659 _Sentinel(_Sentinel<!_Const> __s)
7660 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7661 : _M_end(std::move(__s._M_end))
7664 template<bool _OtherConst>
7665 requires sentinel_for<sentinel_t<_Base>,
7666 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7667 friend constexpr bool
7668 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7669 { return __x._M_get_outer() == __y._M_end; }
7676 template<typename _Range, typename _Pattern>
7677 concept __can_join_with_view
7678 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7679 } // namespace __detail
7681 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7683 template<viewable_range _Range, typename _Pattern>
7684 requires __detail::__can_join_with_view<_Range, _Pattern>
7686 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7688 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7691 using _RangeAdaptor<_JoinWith>::operator();
7692 static constexpr int _S_arity = 2;
7693 template<typename _Pattern>
7694 static constexpr bool _S_has_simple_extra_args
7695 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7698 inline constexpr _JoinWith join_with;
7699 } // namespace views
7700#endif // __cpp_lib_ranges_join_with
7702#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7703 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7704 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7705 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7706 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7708 __detail::__box<_Tp> _M_value;
7709 [[no_unique_address]] _Bound _M_bound = _Bound();
7713 template<typename _Range>
7714 friend constexpr auto
7715 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7717 template<typename _Range>
7718 friend constexpr auto
7719 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7722 repeat_view() requires default_initializable<_Tp> = default;
7725 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7726 requires copy_constructible<_Tp>
7727 : _M_value(__value), _M_bound(__bound)
7729 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7730 __glibcxx_assert(__bound >= 0);
7734 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7735 : _M_value(std::move(__value)), _M_bound(__bound)
7738 template<typename... _Args, typename... _BoundArgs>
7739 requires constructible_from<_Tp, _Args...>
7740 && constructible_from<_Bound, _BoundArgs...>
7742 repeat_view(piecewise_construct_t,
7743 tuple<_Args...> __args,
7744 tuple<_BoundArgs...> __bound_args = tuple<>{})
7745 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7746 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7751 { return _Iterator(std::__addressof(*_M_value)); }
7754 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7755 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7757 constexpr unreachable_sentinel_t
7758 end() const noexcept
7759 { return unreachable_sentinel; }
7762 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7763 { return __detail::__to_unsigned_like(_M_bound); }
7766 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7767 // 4053. Unary call to std::views::repeat does not decay the argument
7768 template<typename _Tp, typename _Bound = unreachable_sentinel_t>
7769 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7771 template<move_constructible _Tp, semiregular _Bound>
7772 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7773 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7774 class repeat_view<_Tp, _Bound>::_Iterator
7777 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7779 const _Tp* _M_value = nullptr;
7780 __index_type _M_current = __index_type();
7783 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7784 : _M_value(__value), _M_current(__bound)
7786 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7787 __glibcxx_assert(__bound >= 0);
7793 using iterator_concept = random_access_iterator_tag;
7794 using iterator_category = random_access_iterator_tag;
7795 using value_type = _Tp;
7796 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7798 __detail::__iota_diff_t<__index_type>>;
7800 _Iterator() = default;
7802 constexpr const _Tp&
7803 operator*() const noexcept
7804 { return *_M_value; }
7806 constexpr _Iterator&
7821 constexpr _Iterator&
7824 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7825 __glibcxx_assert(_M_current > 0);
7838 constexpr _Iterator&
7839 operator+=(difference_type __n)
7841 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7842 __glibcxx_assert(_M_current + __n >= 0);
7847 constexpr _Iterator&
7848 operator-=(difference_type __n)
7850 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7851 __glibcxx_assert(_M_current - __n >= 0);
7856 constexpr const _Tp&
7857 operator[](difference_type __n) const noexcept
7858 { return *(*this + __n); }
7860 friend constexpr bool
7861 operator==(const _Iterator& __x, const _Iterator& __y)
7862 { return __x._M_current == __y._M_current; }
7864 friend constexpr auto
7865 operator<=>(const _Iterator& __x, const _Iterator& __y)
7866 { return __x._M_current <=> __y._M_current; }
7868 friend constexpr _Iterator
7869 operator+(_Iterator __i, difference_type __n)
7875 friend constexpr _Iterator
7876 operator+(difference_type __n, _Iterator __i)
7877 { return __i + __n; }
7879 friend constexpr _Iterator
7880 operator-(_Iterator __i, difference_type __n)
7886 friend constexpr difference_type
7887 operator-(const _Iterator& __x, const _Iterator& __y)
7889 return (static_cast<difference_type>(__x._M_current)
7890 - static_cast<difference_type>(__y._M_current));
7898 template<typename _Tp, typename _Bound>
7899 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7901 template<typename _Tp>
7902 concept __can_repeat_view
7903 = requires { repeat_view(std::declval<_Tp>()); };
7905 template<typename _Tp, typename _Bound>
7906 concept __can_bounded_repeat_view
7907 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7912 template<typename _Tp>
7913 requires __detail::__can_repeat_view<_Tp>
7915 operator() [[nodiscard]] (_Tp&& __value) const
7917 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7918 // 4054. Repeating a repeat_view should repeat the view
7919 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7922 template<typename _Tp, typename _Bound>
7923 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7925 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7926 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7929 inline constexpr _Repeat repeat;
7933 template<typename _Range>
7935 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7937 using _Tp = remove_cvref_t<_Range>;
7938 static_assert(__is_repeat_view<_Tp>);
7939 if constexpr (sized_range<_Tp>)
7940 return views::repeat(*std::forward<_Range>(__r)._M_value,
7941 std::min(ranges::distance(__r), __n));
7943 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7946 template<typename _Range>
7948 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7950 using _Tp = remove_cvref_t<_Range>;
7951 static_assert(__is_repeat_view<_Tp>);
7952 if constexpr (sized_range<_Tp>)
7954 auto __sz = ranges::distance(__r);
7955 return views::repeat(*std::forward<_Range>(__r)._M_value,
7956 __sz - std::min(__sz, __n));
7963#endif // __cpp_lib_ranges_repeat
7965#ifdef __cpp_lib_ranges_stride // C++ >= 23
7966 template<input_range _Vp>
7968 class stride_view : public view_interface<stride_view<_Vp>>
7971 range_difference_t<_Vp> _M_stride;
7973 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7975 template<bool _Const>
7979 template<bool _Const>
7980 requires forward_range<_Base<_Const>>
7981 struct __iter_cat<_Const>
7987 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7988 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7989 return random_access_iterator_tag{};
7994 using iterator_category = decltype(_S_iter_cat());
7997 template<bool> class _Iterator;
8001 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8002 : _M_base(std::move(__base)), _M_stride(__stride)
8003 { __glibcxx_assert(__stride > 0); }
8006 base() const& requires copy_constructible<_Vp>
8011 { return std::move(_M_base); }
8013 constexpr range_difference_t<_Vp>
8014 stride() const noexcept
8015 { return _M_stride; }
8018 begin() requires (!__detail::__simple_view<_Vp>)
8019 { return _Iterator<false>(this, ranges::begin(_M_base)); }
8022 begin() const requires range<const _Vp>
8023 { return _Iterator<true>(this, ranges::begin(_M_base)); }
8026 end() requires (!__detail::__simple_view<_Vp>)
8028 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8030 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8031 return _Iterator<false>(this, ranges::end(_M_base), __missing);
8033 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8034 return _Iterator<false>(this, ranges::end(_M_base));
8036 return default_sentinel;
8040 end() const requires range<const _Vp>
8042 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8043 && forward_range<const _Vp>)
8045 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8046 return _Iterator<true>(this, ranges::end(_M_base), __missing);
8048 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8049 return _Iterator<true>(this, ranges::end(_M_base));
8051 return default_sentinel;
8055 size() requires sized_range<_Vp>
8057 return __detail::__to_unsigned_like
8058 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8062 size() const requires sized_range<const _Vp>
8064 return __detail::__to_unsigned_like
8065 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8069 template<typename _Range>
8070 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8072 template<typename _Vp>
8073 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8074 = enable_borrowed_range<_Vp>;
8076 template<input_range _Vp>
8078 template<bool _Const>
8079 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8081 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8082 using _Base = stride_view::_Base<_Const>;
8084 iterator_t<_Base> _M_current = iterator_t<_Base>();
8085 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8086 range_difference_t<_Base> _M_stride = 0;
8087 range_difference_t<_Base> _M_missing = 0;
8090 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8091 range_difference_t<_Base> __missing = 0)
8092 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8093 _M_stride(__parent->_M_stride), _M_missing(__missing)
8099 if constexpr (random_access_range<_Base>)
8100 return random_access_iterator_tag{};
8101 else if constexpr (bidirectional_range<_Base>)
8102 return bidirectional_iterator_tag{};
8103 else if constexpr (forward_range<_Base>)
8104 return forward_iterator_tag{};
8106 return input_iterator_tag{};
8112 using difference_type = range_difference_t<_Base>;
8113 using value_type = range_value_t<_Base>;
8114 using iterator_concept = decltype(_S_iter_concept());
8115 // iterator_category defined in stride_view::__iter_cat
8117 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8120 _Iterator(_Iterator<!_Const> __other)
8122 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8123 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8124 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8125 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8128 constexpr iterator_t<_Base>
8130 { return std::move(_M_current); }
8132 constexpr const iterator_t<_Base>&
8133 base() const & noexcept
8134 { return _M_current; }
8136 constexpr decltype(auto)
8138 { return *_M_current; }
8140 constexpr _Iterator&
8143 __glibcxx_assert(_M_current != _M_end);
8144 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8153 operator++(int) requires forward_range<_Base>
8160 constexpr _Iterator&
8161 operator--() requires bidirectional_range<_Base>
8163 ranges::advance(_M_current, _M_missing - _M_stride);
8169 operator--(int) requires bidirectional_range<_Base>
8176 constexpr _Iterator&
8177 operator+=(difference_type __n) requires random_access_range<_Base>
8181 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8182 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8186 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8192 constexpr _Iterator&
8193 operator-=(difference_type __n) requires random_access_range<_Base>
8194 { return *this += -__n; }
8196 constexpr decltype(auto) operator[](difference_type __n) const
8197 requires random_access_range<_Base>
8198 { return *(*this + __n); }
8200 friend constexpr bool
8201 operator==(const _Iterator& __x, default_sentinel_t)
8202 { return __x._M_current == __x._M_end; }
8204 friend constexpr bool
8205 operator==(const _Iterator& __x, const _Iterator& __y)
8206 requires equality_comparable<iterator_t<_Base>>
8207 { return __x._M_current == __y._M_current; }
8209 friend constexpr bool
8210 operator<(const _Iterator& __x, const _Iterator& __y)
8211 requires random_access_range<_Base>
8212 { return __x._M_current < __y._M_current; }
8214 friend constexpr bool
8215 operator>(const _Iterator& __x, const _Iterator& __y)
8216 requires random_access_range<_Base>
8217 { return __y._M_current < __x._M_current; }
8219 friend constexpr bool
8220 operator<=(const _Iterator& __x, const _Iterator& __y)
8221 requires random_access_range<_Base>
8222 { return !(__y._M_current < __x._M_current); }
8224 friend constexpr bool
8225 operator>=(const _Iterator& __x, const _Iterator& __y)
8226 requires random_access_range<_Base>
8227 { return !(__x._M_current < __y._M_current); }
8229 friend constexpr auto
8230 operator<=>(const _Iterator& __x, const _Iterator& __y)
8231 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8232 { return __x._M_current <=> __y._M_current; }
8234 friend constexpr _Iterator
8235 operator+(const _Iterator& __i, difference_type __n)
8236 requires random_access_range<_Base>
8243 friend constexpr _Iterator
8244 operator+(difference_type __n, const _Iterator& __i)
8245 requires random_access_range<_Base>
8246 { return __i + __n; }
8248 friend constexpr _Iterator
8249 operator-(const _Iterator& __i, difference_type __n)
8250 requires random_access_range<_Base>
8257 friend constexpr difference_type
8258 operator-(const _Iterator& __x, const _Iterator& __y)
8259 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8261 auto __n = __x._M_current - __y._M_current;
8262 if constexpr (forward_range<_Base>)
8263 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8265 return -__detail::__div_ceil(-__n, __x._M_stride);
8267 return __detail::__div_ceil(__n, __x._M_stride);
8270 friend constexpr difference_type
8271 operator-(default_sentinel_t __y, const _Iterator& __x)
8272 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8273 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8275 friend constexpr difference_type
8276 operator-(const _Iterator& __x, default_sentinel_t __y)
8277 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8278 { return -(__y - __x); }
8280 friend constexpr range_rvalue_reference_t<_Base>
8281 iter_move(const _Iterator& __i)
8282 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8283 { return ranges::iter_move(__i._M_current); }
8285 friend constexpr void
8286 iter_swap(const _Iterator& __x, const _Iterator& __y)
8287 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8288 requires indirectly_swappable<iterator_t<_Base>>
8289 { ranges::iter_swap(__x._M_current, __y._M_current); }
8296 template<typename _Range, typename _Dp>
8297 concept __can_stride_view
8298 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8301 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8303 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8304 requires __detail::__can_stride_view<_Range, _Dp>
8306 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8307 { return stride_view(std::forward<_Range>(__r), __n); }
8309 using __adaptor::_RangeAdaptor<_Stride>::operator();
8310 static constexpr int _S_arity = 2;
8311 static constexpr bool _S_has_simple_extra_args = true;
8314 inline constexpr _Stride stride;
8316#endif // __cpp_lib_ranges_stride
8318#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8321 template<bool _Const, typename _First, typename... _Vs>
8322 concept __cartesian_product_is_random_access
8323 = (random_access_range<__maybe_const_t<_Const, _First>>
8325 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8326 && sized_range<__maybe_const_t<_Const, _Vs>>));
8328 template<typename _Range>
8329 concept __cartesian_product_common_arg
8330 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8332 template<bool _Const, typename _First, typename... _Vs>
8333 concept __cartesian_product_is_bidirectional
8334 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8336 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8337 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8339 template<typename _First, typename... _Vs>
8340 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8342 template<typename... _Vs>
8343 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8345 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8346 concept __cartesian_is_sized_sentinel
8347 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8348 iterator_t<__maybe_const_t<_Const, _First>>>
8350 && (sized_range<__maybe_const_t<_Const, _Vs>>
8351 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8352 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8354 template<__cartesian_product_common_arg _Range>
8356 __cartesian_common_arg_end(_Range& __r)
8358 if constexpr (common_range<_Range>)
8359 return ranges::end(__r);
8361 return ranges::begin(__r) + ranges::distance(__r);
8363 } // namespace __detail
8365 template<input_range _First, forward_range... _Vs>
8366 requires (view<_First> && ... && view<_Vs>)
8367 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8369 tuple<_First, _Vs...> _M_bases;
8371 template<bool> class _Iterator;
8374 _S_difference_type()
8376 // TODO: Implement the recommended practice of using the smallest
8377 // sufficiently wide type according to the maximum sizes of the
8378 // underlying ranges?
8379 return common_type_t<ptrdiff_t,
8380 range_difference_t<_First>,
8381 range_difference_t<_Vs>...>{};
8385 cartesian_product_view() = default;
8388 cartesian_product_view(_First __first, _Vs... __rest)
8389 : _M_bases(std::move(__first), std::move(__rest)...)
8392 constexpr _Iterator<false>
8393 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8394 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8396 constexpr _Iterator<true>
8397 begin() const requires (range<const _First> && ... && range<const _Vs>)
8398 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8400 constexpr _Iterator<false>
8401 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8402 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8404 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8405 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8406 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8407 auto& __first = std::get<0>(_M_bases);
8408 return _Ret{(__empty_tail
8409 ? ranges::begin(__first)
8410 : __detail::__cartesian_common_arg_end(__first)),
8411 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8412 }(make_index_sequence<sizeof...(_Vs)>{});
8414 return _Iterator<false>{*this, std::move(__its)};
8417 constexpr _Iterator<true>
8418 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8420 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8421 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8422 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8423 auto& __first = std::get<0>(_M_bases);
8424 return _Ret{(__empty_tail
8425 ? ranges::begin(__first)
8426 : __detail::__cartesian_common_arg_end(__first)),
8427 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8428 }(make_index_sequence<sizeof...(_Vs)>{});
8430 return _Iterator<true>{*this, std::move(__its)};
8433 constexpr default_sentinel_t
8434 end() const noexcept
8435 { return default_sentinel; }
8438 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8440 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8441 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8442 auto __size = static_cast<_ST>(1);
8443#ifdef _GLIBCXX_ASSERTIONS
8444 if constexpr (integral<_ST>)
8447 = (__builtin_mul_overflow(__size,
8448 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8451 __glibcxx_assert(!__overflow);
8455 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8457 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8461 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8463 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8464 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8465 auto __size = static_cast<_ST>(1);
8466#ifdef _GLIBCXX_ASSERTIONS
8467 if constexpr (integral<_ST>)
8470 = (__builtin_mul_overflow(__size,
8471 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8474 __glibcxx_assert(!__overflow);
8478 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8480 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8484 template<typename... _Vs>
8485 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8487 template<input_range _First, forward_range... _Vs>
8488 requires (view<_First> && ... && view<_Vs>)
8489 template<bool _Const>
8490 class cartesian_product_view<_First, _Vs...>::_Iterator
8492 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8493 _Parent* _M_parent = nullptr;
8494 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8495 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8498 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8499 : _M_parent(std::__addressof(__parent)),
8500 _M_current(std::move(__current))
8506 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8507 return random_access_iterator_tag{};
8508 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8509 return bidirectional_iterator_tag{};
8510 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8511 return forward_iterator_tag{};
8513 return input_iterator_tag{};
8516 friend cartesian_product_view;
8519 using iterator_category = input_iterator_tag;
8520 using iterator_concept = decltype(_S_iter_concept());
8522 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8523 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8525 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8526 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8527 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8529 _Iterator() = default;
8532 _Iterator(_Iterator<!_Const> __i)
8534 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8535 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8536 : _M_parent(std::__addressof(__i._M_parent)),
8537 _M_current(std::move(__i._M_current))
8543 auto __f = [](auto& __i) -> decltype(auto) {
8546 return __detail::__tuple_transform(__f, _M_current);
8549 constexpr _Iterator&
8561 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8568 constexpr _Iterator&
8570 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8578 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8585 constexpr _Iterator&
8586 operator+=(difference_type __x)
8587 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8593 constexpr _Iterator&
8594 operator-=(difference_type __x)
8595 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8596 { return *this += -__x; }
8599 operator[](difference_type __n) const
8600 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8601 { return *((*this) + __n); }
8603 friend constexpr bool
8604 operator==(const _Iterator& __x, const _Iterator& __y)
8605 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8606 { return __x._M_current == __y._M_current; }
8608 friend constexpr bool
8609 operator==(const _Iterator& __x, default_sentinel_t)
8611 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8612 return ((std::get<_Is>(__x._M_current)
8613 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8615 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8618 friend constexpr auto
8619 operator<=>(const _Iterator& __x, const _Iterator& __y)
8620 requires __detail::__all_random_access<_Const, _First, _Vs...>
8621 { return __x._M_current <=> __y._M_current; }
8623 friend constexpr _Iterator
8624 operator+(_Iterator __x, difference_type __y)
8625 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8626 { return __x += __y; }
8628 friend constexpr _Iterator
8629 operator+(difference_type __x, _Iterator __y)
8630 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8631 { return __y += __x; }
8633 friend constexpr _Iterator
8634 operator-(_Iterator __x, difference_type __y)
8635 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8636 { return __x -= __y; }
8638 friend constexpr difference_type
8639 operator-(const _Iterator& __x, const _Iterator& __y)
8640 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8641 { return __x._M_distance_from(__y._M_current); }
8643 friend constexpr difference_type
8644 operator-(const _Iterator& __i, default_sentinel_t)
8645 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8647 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8648 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8649 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8650 }(make_index_sequence<sizeof...(_Vs)>{});
8651 return __i._M_distance_from(__end_tuple);
8654 friend constexpr difference_type
8655 operator-(default_sentinel_t, const _Iterator& __i)
8656 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8657 { return -(__i - default_sentinel); }
8659 friend constexpr auto
8660 iter_move(const _Iterator& __i)
8661 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8663 friend constexpr void
8664 iter_swap(const _Iterator& __l, const _Iterator& __r)
8665 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8667 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8669 [&]<size_t... _Is>(index_sequence<_Is...>) {
8670 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8671 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8675 template<size_t _Nm = sizeof...(_Vs)>
8679 auto& __it = std::get<_Nm>(_M_current);
8681 if constexpr (_Nm > 0)
8682 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8684 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8689 template<size_t _Nm = sizeof...(_Vs)>
8693 auto& __it = std::get<_Nm>(_M_current);
8694 if constexpr (_Nm > 0)
8695 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8697 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8703 template<size_t _Nm = sizeof...(_Vs)>
8705 _M_advance(difference_type __x)
8706 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8714 // Constant time iterator advancement.
8715 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8716 auto& __it = std::get<_Nm>(_M_current);
8717 if constexpr (_Nm == 0)
8719#ifdef _GLIBCXX_ASSERTIONS
8720 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8722 auto __size = ranges::ssize(__r);
8723 auto __begin = ranges::begin(__r);
8724 auto __offset = __it - __begin;
8725 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8732 auto __size = ranges::ssize(__r);
8733 auto __begin = ranges::begin(__r);
8734 auto __offset = __it - __begin;
8736 __x = __offset / __size;
8740 __offset = __size + __offset;
8743 __it = __begin + __offset;
8744 _M_advance<_Nm - 1>(__x);
8749 template<typename _Tuple>
8750 constexpr difference_type
8751 _M_distance_from(const _Tuple& __t) const
8753 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8754 auto __sum = static_cast<difference_type>(0);
8755#ifdef _GLIBCXX_ASSERTIONS
8756 if constexpr (integral<difference_type>)
8759 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8761 __glibcxx_assert(!__overflow);
8765 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8767 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8770 template<size_t _Nm, typename _Tuple>
8771 constexpr difference_type
8772 _M_scaled_distance(const _Tuple& __t) const
8774 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8775 - std::get<_Nm>(__t));
8776#ifdef _GLIBCXX_ASSERTIONS
8777 if constexpr (integral<difference_type>)
8779 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8780 __glibcxx_assert(!__overflow);
8784 __dist *= _M_scaled_size<_Nm+1>();
8788 template<size_t _Nm>
8789 constexpr difference_type
8790 _M_scaled_size() const
8792 if constexpr (_Nm <= sizeof...(_Vs))
8794 auto __size = static_cast<difference_type>(ranges::size
8795 (std::get<_Nm>(_M_parent->_M_bases)));
8796#ifdef _GLIBCXX_ASSERTIONS
8797 if constexpr (integral<difference_type>)
8799 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8800 __glibcxx_assert(!__overflow);
8804 __size *= _M_scaled_size<_Nm+1>();
8808 return static_cast<difference_type>(1);
8816 template<typename... _Ts>
8817 concept __can_cartesian_product_view
8818 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8821 struct _CartesianProduct
8823 template<typename... _Ts>
8824 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8826 operator() [[nodiscard]] (_Ts&&... __ts) const
8828 if constexpr (sizeof...(_Ts) == 0)
8829 return views::single(tuple{});
8831 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8835 inline constexpr _CartesianProduct cartesian_product;
8837#endif // __cpp_lib_ranges_cartesian_product
8839#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8840 template<input_range _Vp>
8842 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8844 _Vp _M_base = _Vp();
8847 as_rvalue_view() requires default_initializable<_Vp> = default;
8850 as_rvalue_view(_Vp __base)
8851 : _M_base(std::move(__base))
8855 base() const& requires copy_constructible<_Vp>
8860 { return std::move(_M_base); }
8863 begin() requires (!__detail::__simple_view<_Vp>)
8864 { return move_iterator(ranges::begin(_M_base)); }
8867 begin() const requires range<const _Vp>
8868 { return move_iterator(ranges::begin(_M_base)); }
8871 end() requires (!__detail::__simple_view<_Vp>)
8873 if constexpr (common_range<_Vp>)
8874 return move_iterator(ranges::end(_M_base));
8876 return move_sentinel(ranges::end(_M_base));
8880 end() const requires range<const _Vp>
8882 if constexpr (common_range<const _Vp>)
8883 return move_iterator(ranges::end(_M_base));
8885 return move_sentinel(ranges::end(_M_base));
8889 size() requires sized_range<_Vp>
8890 { return ranges::size(_M_base); }
8893 size() const requires sized_range<const _Vp>
8894 { return ranges::size(_M_base); }
8897 template<typename _Range>
8898 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8900 template<typename _Tp>
8901 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8902 = enable_borrowed_range<_Tp>;
8908 template<typename _Tp>
8909 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8912 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8914 template<viewable_range _Range>
8915 requires __detail::__can_as_rvalue_view<_Range>
8917 operator() [[nodiscard]] (_Range&& __r) const
8919 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8920 range_reference_t<_Range>>)
8921 return views::all(std::forward<_Range>(__r));
8923 return as_rvalue_view(std::forward<_Range>(__r));
8927 inline constexpr _AsRvalue as_rvalue;
8929#endif // __cpp_lib_as_rvalue
8931#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8934 template<typename _Range>
8935 concept __range_with_movable_reference = input_range<_Range>
8936 && move_constructible<range_reference_t<_Range>>
8937 && move_constructible<range_rvalue_reference_t<_Range>>;
8941 requires __detail::__range_with_movable_reference<_Vp>
8942 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8944 _Vp _M_base = _Vp();
8946 template<bool _Const> class _Iterator;
8947 template<bool _Const> class _Sentinel;
8950 enumerate_view() requires default_initializable<_Vp> = default;
8953 enumerate_view(_Vp __base)
8954 : _M_base(std::move(__base))
8958 begin() requires (!__detail::__simple_view<_Vp>)
8959 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8962 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8963 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8966 end() requires (!__detail::__simple_view<_Vp>)
8968 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8969 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8971 return _Sentinel<false>(ranges::end(_M_base));
8975 end() const requires __detail::__range_with_movable_reference<const _Vp>
8977 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8978 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8980 return _Sentinel<true>(ranges::end(_M_base));
8984 size() requires sized_range<_Vp>
8985 { return ranges::size(_M_base); }
8988 size() const requires sized_range<const _Vp>
8989 { return ranges::size(_M_base); }
8992 base() const & requires copy_constructible<_Vp>
8997 { return std::move(_M_base); }
9000 template<typename _Range>
9001 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9003 template<typename _Tp>
9004 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9005 = enable_borrowed_range<_Tp>;
9008 requires __detail::__range_with_movable_reference<_Vp>
9009 template<bool _Const>
9010 class enumerate_view<_Vp>::_Iterator
9012 using _Base = __maybe_const_t<_Const, _Vp>;
9017 if constexpr (random_access_range<_Base>)
9018 return random_access_iterator_tag{};
9019 else if constexpr (bidirectional_range<_Base>)
9020 return bidirectional_iterator_tag{};
9021 else if constexpr (forward_range<_Base>)
9022 return forward_iterator_tag{};
9024 return input_iterator_tag{};
9027 friend enumerate_view;
9030 using iterator_category = input_iterator_tag;
9031 using iterator_concept = decltype(_S_iter_concept());
9032 using difference_type = range_difference_t<_Base>;
9033 using value_type = tuple<difference_type, range_value_t<_Base>>;
9036 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9038 iterator_t<_Base> _M_current = iterator_t<_Base>();
9039 difference_type _M_pos = 0;
9042 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9043 : _M_current(std::move(__current)), _M_pos(__pos)
9047 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
9050 _Iterator(_Iterator<!_Const> __i)
9051 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9052 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9055 constexpr const iterator_t<_Base> &
9056 base() const & noexcept
9057 { return _M_current; }
9059 constexpr iterator_t<_Base>
9061 { return std::move(_M_current); }
9063 constexpr difference_type
9064 index() const noexcept
9069 { return __reference_type(_M_pos, *_M_current); }
9071 constexpr _Iterator&
9084 operator++(int) requires forward_range<_Base>
9091 constexpr _Iterator&
9092 operator--() requires bidirectional_range<_Base>
9100 operator--(int) requires bidirectional_range<_Base>
9107 constexpr _Iterator&
9108 operator+=(difference_type __n) requires random_access_range<_Base>
9115 constexpr _Iterator&
9116 operator-=(difference_type __n) requires random_access_range<_Base>
9124 operator[](difference_type __n) const requires random_access_range<_Base>
9125 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9127 friend constexpr bool
9128 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9129 { return __x._M_pos == __y._M_pos; }
9131 friend constexpr strong_ordering
9132 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9133 { return __x._M_pos <=> __y._M_pos; }
9135 friend constexpr _Iterator
9136 operator+(const _Iterator& __x, difference_type __y)
9137 requires random_access_range<_Base>
9138 { return (auto(__x) += __y); }
9140 friend constexpr _Iterator
9141 operator+(difference_type __x, const _Iterator& __y)
9142 requires random_access_range<_Base>
9143 { return auto(__y) += __x; }
9145 friend constexpr _Iterator
9146 operator-(const _Iterator& __x, difference_type __y)
9147 requires random_access_range<_Base>
9148 { return auto(__x) -= __y; }
9150 friend constexpr difference_type
9151 operator-(const _Iterator& __x, const _Iterator& __y)
9152 { return __x._M_pos - __y._M_pos; }
9154 friend constexpr auto
9155 iter_move(const _Iterator& __i)
9156 noexcept(noexcept(ranges::iter_move(__i._M_current))
9157 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9159 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9160 (__i._M_pos, ranges::iter_move(__i._M_current));
9165 requires __detail::__range_with_movable_reference<_Vp>
9166 template<bool _Const>
9167 class enumerate_view<_Vp>::_Sentinel
9169 using _Base = __maybe_const_t<_Const, _Vp>;
9171 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9174 _Sentinel(sentinel_t<_Base> __end)
9175 : _M_end(std::move(__end))
9178 friend enumerate_view;
9181 _Sentinel() = default;
9184 _Sentinel(_Sentinel<!_Const> __other)
9185 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9186 : _M_end(std::move(__other._M_end))
9189 constexpr sentinel_t<_Base>
9193 template<bool _OtherConst>
9194 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9195 friend constexpr bool
9196 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9197 { return __x._M_current == __y._M_end; }
9199 template<bool _OtherConst>
9200 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9201 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9202 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9203 { return __x._M_current - __y._M_end; }
9205 template<bool _OtherConst>
9206 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9207 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9208 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9209 { return __x._M_end - __y._M_current; }
9216 template<typename _Tp>
9217 concept __can_enumerate_view
9218 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9221 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9223 template<viewable_range _Range>
9224 requires __detail::__can_enumerate_view<_Range>
9226 operator() [[nodiscard]] (_Range&& __r) const
9227 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9230 inline constexpr _Enumerate enumerate;
9232#endif // __cpp_lib_ranges_enumerate
9234#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9236 requires input_range<_Vp>
9237 class as_const_view : public view_interface<as_const_view<_Vp>>
9239 _Vp _M_base = _Vp();
9242 as_const_view() requires default_initializable<_Vp> = default;
9245 as_const_view(_Vp __base)
9246 noexcept(is_nothrow_move_constructible_v<_Vp>)
9247 : _M_base(std::move(__base))
9252 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9253 requires copy_constructible<_Vp>
9258 noexcept(is_nothrow_move_constructible_v<_Vp>)
9259 { return std::move(_M_base); }
9262 begin() requires (!__detail::__simple_view<_Vp>)
9263 { return ranges::cbegin(_M_base); }
9266 begin() const requires range<const _Vp>
9267 { return ranges::cbegin(_M_base); }
9270 end() requires (!__detail::__simple_view<_Vp>)
9271 { return ranges::cend(_M_base); }
9274 end() const requires range<const _Vp>
9275 { return ranges::cend(_M_base); }
9278 size() requires sized_range<_Vp>
9279 { return ranges::size(_M_base); }
9282 size() const requires sized_range<const _Vp>
9283 { return ranges::size(_M_base); }
9286 template<typename _Range>
9287 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9289 template<typename _Tp>
9290 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9291 = enable_borrowed_range<_Tp>;
9297 template<typename _Tp>
9298 inline constexpr bool __is_ref_view = false;
9300 template<typename _Range>
9301 inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
9303 template<typename _Range>
9304 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9307 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9309 template<viewable_range _Range>
9311 operator()(_Range&& __r) const
9312 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9313 requires __detail::__can_as_const_view<_Range>
9315 using _Tp = remove_cvref_t<_Range>;
9316 using element_type = remove_reference_t<range_reference_t<_Range>>;
9317 if constexpr (constant_range<views::all_t<_Range>>)
9318 return views::all(std::forward<_Range>(__r));
9319 else if constexpr (__detail::__is_empty_view<_Tp>)
9320 return views::empty<const element_type>;
9321 else if constexpr (std::__detail::__is_span<_Tp>)
9322 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9323 else if constexpr (__detail::__is_ref_view<_Tp>
9324 && constant_range<const element_type>)
9325 return ref_view(static_cast<const element_type&>
9326 (std::forward<_Range>(__r).base()));
9327 else if constexpr (is_lvalue_reference_v<_Range>
9328 && constant_range<const _Tp>
9330 return ref_view(static_cast<const _Tp&>(__r));
9332 return as_const_view(std::forward<_Range>(__r));
9336 inline constexpr _AsConst as_const;
9338#endif // __cpp_lib_as_const
9339} // namespace ranges
9341 namespace views = ranges::views;
9343#if __cpp_lib_ranges_to_container // C++ >= 23
9346/// @cond undocumented
9349 template<typename _Container>
9350 constexpr bool __reservable_container
9351 = sized_range<_Container>
9352 && requires(_Container& __c, range_size_t<_Container> __n) {
9354 { __c.capacity() } -> same_as<decltype(__n)>;
9355 { __c.max_size() } -> same_as<decltype(__n)>;
9358 template<typename _Cont, typename _Range>
9359 constexpr bool __toable = requires {
9360 requires (!input_range<_Cont>
9361 || convertible_to<range_reference_t<_Range>,
9362 range_value_t<_Cont>>);
9364} // namespace __detail
9367 /// Convert a range to a container.
9369 * @tparam _Cont A container type.
9370 * @param __r A range that models the `input_range` concept.
9371 * @param __args... Arguments to pass to the container constructor.
9374 * This function converts a range to the `_Cont` type.
9376 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9377 * will convert the view to `std::vector<int>`.
9379 * Additional constructor arguments for the container can be supplied after
9380 * the input range argument, e.g.
9381 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9383 template<typename _Cont, input_range _Rg, typename... _Args>
9384 requires (!view<_Cont>)
9386 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9388 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9389 static_assert(is_class_v<_Cont>);
9391 if constexpr (__detail::__toable<_Cont, _Rg>)
9393 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9394 return _Cont(std::forward<_Rg>(__r),
9395 std::forward<_Args>(__args)...);
9396 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9397 return _Cont(from_range, std::forward<_Rg>(__r),
9398 std::forward<_Args>(__args)...);
9399 else if constexpr (requires { requires common_range<_Rg>;
9400 typename __iter_category_t<iterator_t<_Rg>>;
9401 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9402 input_iterator_tag>;
9403 requires constructible_from<_Cont, iterator_t<_Rg>,
9404 sentinel_t<_Rg>, _Args...>;
9406 return _Cont(ranges::begin(__r), ranges::end(__r),
9407 std::forward<_Args>(__args)...);
9410 static_assert(constructible_from<_Cont, _Args...>);
9411 _Cont __c(std::forward<_Args>(__args)...);
9412 if constexpr (sized_range<_Rg>
9413 && __detail::__reservable_container<_Cont>)
9414 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9415 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9416 // 4016. container-insertable checks do not match what
9417 // container-inserter does
9418 auto __it = ranges::begin(__r);
9419 const auto __sent = ranges::end(__r);
9420 while (__it != __sent)
9422 if constexpr (requires { __c.emplace_back(*__it); })
9423 __c.emplace_back(*__it);
9424 else if constexpr (requires { __c.push_back(*__it); })
9425 __c.push_back(*__it);
9426 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9427 __c.emplace(__c.end(), *__it);
9429 __c.insert(__c.end(), *__it);
9437 static_assert(input_range<range_reference_t<_Rg>>);
9438 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9439 // 3984. ranges::to's recursion branch may be ill-formed
9440 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9441 []<typename _Elt>(_Elt&& __elem) {
9442 using _ValT = range_value_t<_Cont>;
9443 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9444 }), std::forward<_Args>(__args)...);
9448/// @cond undocumented
9451 template<typename _Rg>
9454 using iterator_category = input_iterator_tag;
9455 using value_type = range_value_t<_Rg>;
9456 using difference_type = ptrdiff_t;
9457 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9458 using reference = range_reference_t<_Rg>;
9459 reference operator*() const;
9460 pointer operator->() const;
9461 _InputIter& operator++();
9462 _InputIter operator++(int);
9463 bool operator==(const _InputIter&) const;
9466 template<template<typename...> typename _Cont, input_range _Rg,
9469 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9471 template<template<typename...> typename _Cont, input_range _Rg,
9474 = decltype(_Cont(from_range, std::declval<_Rg>(),
9475 std::declval<_Args>()...));
9477 template<template<typename...> typename _Cont, input_range _Rg,
9480 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9481 std::declval<_InputIter<_Rg>>(),
9482 std::declval<_Args>()...));
9484} // namespace __detail
9487 template<template<typename...> typename _Cont, input_range _Rg,
9490 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9492 using __detail::_DeduceExpr1;
9493 using __detail::_DeduceExpr2;
9494 using __detail::_DeduceExpr3;
9495 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9496 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9497 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9498 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9499 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9500 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9501 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9502 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9503 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9505 static_assert(false); // Cannot deduce container specialization.
9508/// @cond undocumented
9511 template<typename _Cont>
9514 template<typename _Range, typename... _Args>
9515 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9516 std::declval<_Args>()...); }
9518 operator()(_Range&& __r, _Args&&... __args) const
9520 return ranges::to<_Cont>(std::forward<_Range>(__r),
9521 std::forward<_Args>(__args)...);
9524} // namespace __detail
9527 /// ranges::to adaptor for converting a range to a container type
9529 * @tparam _Cont A container type.
9530 * @param __args... Arguments to pass to the container constructor.
9533 * This range adaptor returns a range adaptor closure object that converts
9534 * a range to the `_Cont` type.
9536 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9537 * will convert the view to `std::vector<int>`.
9539 * Additional constructor arguments for the container can be supplied, e.g.
9540 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9542 template<typename _Cont, typename... _Args>
9543 requires (!view<_Cont>)
9545 to [[nodiscard]] (_Args&&... __args)
9547 using __detail::_To;
9548 using views::__adaptor::_Partial;
9549 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9552/// @cond undocumented
9555 template<template<typename...> typename _Cont>
9558 template<typename _Range, typename... _Args>
9559 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9560 std::declval<_Args>()...); }
9562 operator()(_Range&& __r, _Args&&... __args) const
9564 return ranges::to<_Cont>(std::forward<_Range>(__r),
9565 std::forward<_Args>(__args)...);
9568} // namespace __detail
9571 /// ranges::to adaptor for converting a range to a deduced container type.
9573 * @tparam _Cont A container template.
9574 * @param __args... Arguments to pass to the container constructor.
9577 * This range adaptor returns a range adaptor closure object that converts
9578 * a range to a specialization of the `_Cont` class template. The specific
9579 * specialization of `_Cont` to be used is deduced automatically.
9581 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9582 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9583 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9585 * Additional constructor arguments for the container can be supplied, e.g.
9586 * `r | std::ranges::to<std::vector>(an_allocator)`.
9588 template<template<typename...> typename _Cont, typename... _Args>
9590 to [[nodiscard]] (_Args&&... __args)
9592 using __detail::_To2;
9593 using views::__adaptor::_Partial;
9594 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9597} // namespace ranges
9598#endif // __cpp_lib_ranges_to_container
9600_GLIBCXX_END_NAMESPACE_VERSION
9602#endif // library concepts
9604#endif /* _GLIBCXX_RANGES */