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 static constexpr size_t
340 { return _M_value.operator->(); }
343 data() const noexcept
344 { return _M_value.operator->(); }
347 [[no_unique_address]] __detail::__box<_Tp> _M_value;
350 template<typename _Tp>
351 single_view(_Tp) -> single_view<_Tp>;
355 template<typename _Wp>
356 constexpr auto __to_signed_like(_Wp __w) noexcept
358 if constexpr (!integral<_Wp>)
359 return iter_difference_t<_Wp>();
360 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
361 return iter_difference_t<_Wp>(__w);
362 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
363 return ptrdiff_t(__w);
364 else if constexpr (sizeof(long long) > sizeof(_Wp))
365 return (long long)(__w);
366#ifdef __SIZEOF_INT128__
367 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
368 return __int128(__w);
371 return __max_diff_type(__w);
374 template<typename _Wp>
375 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
377 template<typename _It>
378 concept __decrementable = incrementable<_It>
381 { --__i } -> same_as<_It&>;
382 { __i-- } -> same_as<_It>;
385 template<typename _It>
386 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
387 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
389 { __i += __n } -> same_as<_It&>;
390 { __i -= __n } -> same_as<_It&>;
394 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
397 template<typename _Winc>
398 struct __iota_view_iter_cat
401 template<incrementable _Winc>
402 struct __iota_view_iter_cat<_Winc>
403 { using iterator_category = input_iterator_tag; };
404 } // namespace __detail
406 template<weakly_incrementable _Winc,
407 semiregular _Bound = unreachable_sentinel_t>
408 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
410 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
415 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
421 using namespace __detail;
422 if constexpr (__advanceable<_Winc>)
423 return random_access_iterator_tag{};
424 else if constexpr (__decrementable<_Winc>)
425 return bidirectional_iterator_tag{};
426 else if constexpr (incrementable<_Winc>)
427 return forward_iterator_tag{};
429 return input_iterator_tag{};
433 using iterator_concept = decltype(_S_iter_concept());
434 // iterator_category defined in __iota_view_iter_cat
435 using value_type = _Winc;
436 using difference_type = __detail::__iota_diff_t<_Winc>;
438 _Iterator() requires default_initializable<_Winc> = default;
441 _Iterator(_Winc __value)
442 : _M_value(__value) { }
445 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
460 operator++(int) requires incrementable<_Winc>
468 operator--() requires __detail::__decrementable<_Winc>
475 operator--(int) requires __detail::__decrementable<_Winc>
483 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
485 using __detail::__is_integer_like;
486 using __detail::__is_signed_integer_like;
487 if constexpr (__is_integer_like<_Winc>
488 && !__is_signed_integer_like<_Winc>)
490 if (__n >= difference_type(0))
491 _M_value += static_cast<_Winc>(__n);
493 _M_value -= static_cast<_Winc>(-__n);
501 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
503 using __detail::__is_integer_like;
504 using __detail::__is_signed_integer_like;
505 if constexpr (__is_integer_like<_Winc>
506 && !__is_signed_integer_like<_Winc>)
508 if (__n >= difference_type(0))
509 _M_value -= static_cast<_Winc>(__n);
511 _M_value += static_cast<_Winc>(-__n);
519 operator[](difference_type __n) const
520 requires __detail::__advanceable<_Winc>
521 { return _Winc(_M_value + __n); }
523 friend constexpr bool
524 operator==(const _Iterator& __x, const _Iterator& __y)
525 requires equality_comparable<_Winc>
526 { return __x._M_value == __y._M_value; }
528 friend constexpr bool
529 operator<(const _Iterator& __x, const _Iterator& __y)
530 requires totally_ordered<_Winc>
531 { return __x._M_value < __y._M_value; }
533 friend constexpr bool
534 operator>(const _Iterator& __x, const _Iterator& __y)
535 requires totally_ordered<_Winc>
536 { return __y < __x; }
538 friend constexpr bool
539 operator<=(const _Iterator& __x, const _Iterator& __y)
540 requires totally_ordered<_Winc>
541 { return !(__y < __x); }
543 friend constexpr bool
544 operator>=(const _Iterator& __x, const _Iterator& __y)
545 requires totally_ordered<_Winc>
546 { return !(__x < __y); }
548#ifdef __cpp_lib_three_way_comparison
549 friend constexpr auto
550 operator<=>(const _Iterator& __x, const _Iterator& __y)
551 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
552 { return __x._M_value <=> __y._M_value; }
555 friend constexpr _Iterator
556 operator+(_Iterator __i, difference_type __n)
557 requires __detail::__advanceable<_Winc>
563 friend constexpr _Iterator
564 operator+(difference_type __n, _Iterator __i)
565 requires __detail::__advanceable<_Winc>
566 { return __i += __n; }
568 friend constexpr _Iterator
569 operator-(_Iterator __i, difference_type __n)
570 requires __detail::__advanceable<_Winc>
576 friend constexpr difference_type
577 operator-(const _Iterator& __x, const _Iterator& __y)
578 requires __detail::__advanceable<_Winc>
580 using __detail::__is_integer_like;
581 using __detail::__is_signed_integer_like;
582 using _Dt = difference_type;
583 if constexpr (__is_integer_like<_Winc>)
585 if constexpr (__is_signed_integer_like<_Winc>)
586 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
588 return (__y._M_value > __x._M_value)
589 ? _Dt(-_Dt(__y._M_value - __x._M_value))
590 : _Dt(__x._M_value - __y._M_value);
593 return __x._M_value - __y._M_value;
597 _Winc _M_value = _Winc();
607 _M_equal(const _Iterator& __x) const
608 { return __x._M_value == _M_bound; }
611 _M_distance_from(const _Iterator& __x) const
612 { return _M_bound - __x._M_value; }
614 _Bound _M_bound = _Bound();
617 _Sentinel() = default;
620 _Sentinel(_Bound __bound)
621 : _M_bound(__bound) { }
623 friend constexpr bool
624 operator==(const _Iterator& __x, const _Sentinel& __y)
625 { return __y._M_equal(__x); }
627 friend constexpr iter_difference_t<_Winc>
628 operator-(const _Iterator& __x, const _Sentinel& __y)
629 requires sized_sentinel_for<_Bound, _Winc>
630 { return -__y._M_distance_from(__x); }
632 friend constexpr iter_difference_t<_Winc>
633 operator-(const _Sentinel& __x, const _Iterator& __y)
634 requires sized_sentinel_for<_Bound, _Winc>
635 { return __x._M_distance_from(__y); }
640 _Winc _M_value = _Winc();
641 [[no_unique_address]] _Bound _M_bound = _Bound();
644 iota_view() requires default_initializable<_Winc> = default;
647 iota_view(_Winc __value)
652 iota_view(type_identity_t<_Winc> __value,
653 type_identity_t<_Bound> __bound)
654 : _M_value(__value), _M_bound(__bound)
656 if constexpr (totally_ordered_with<_Winc, _Bound>)
657 __glibcxx_assert( bool(__value <= __bound) );
661 iota_view(_Iterator __first, _Iterator __last)
662 requires same_as<_Winc, _Bound>
663 : iota_view(__first._M_value, __last._M_value)
667 iota_view(_Iterator __first, unreachable_sentinel_t __last)
668 requires same_as<_Bound, unreachable_sentinel_t>
669 : iota_view(__first._M_value, __last)
673 iota_view(_Iterator __first, _Sentinel __last)
674 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
675 : iota_view(__first._M_value, __last._M_bound)
679 begin() const { return _Iterator{_M_value}; }
684 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
685 return unreachable_sentinel;
687 return _Sentinel{_M_bound};
691 end() const requires same_as<_Winc, _Bound>
692 { return _Iterator{_M_bound}; }
696 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
697 || (integral<_Winc> && integral<_Bound>)
698 || sized_sentinel_for<_Bound, _Winc>
700 using __detail::__is_integer_like;
701 using __detail::__to_unsigned_like;
702 if constexpr (integral<_Winc> && integral<_Bound>)
704 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
705 return _Up(_M_bound) - _Up(_M_value);
707 else if constexpr (__is_integer_like<_Winc>)
708 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
710 return __to_unsigned_like(_M_bound - _M_value);
714 template<typename _Winc, typename _Bound>
715 requires (!__detail::__is_integer_like<_Winc>
716 || !__detail::__is_integer_like<_Bound>
717 || (__detail::__is_signed_integer_like<_Winc>
718 == __detail::__is_signed_integer_like<_Bound>))
719 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
721 template<typename _Winc, typename _Bound>
722 inline constexpr bool
723 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
727 template<typename _Tp>
728 inline constexpr empty_view<_Tp> empty{};
732 template<typename _Tp>
733 concept __can_single_view
734 = requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
735 } // namespace __detail
739 template<__detail::__can_single_view _Tp>
741 operator() [[nodiscard]] (_Tp&& __e) const
742 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
743 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
746 inline constexpr _Single single{};
750 template<typename... _Args>
751 concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); };
752 } // namespace __detail
756 template<__detail::__can_iota_view _Tp>
758 operator() [[nodiscard]] (_Tp&& __e) const
759 { return iota_view(std::forward<_Tp>(__e)); }
761 template<typename _Tp, typename _Up>
762 requires __detail::__can_iota_view<_Tp, _Up>
764 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const
765 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
768 inline constexpr _Iota iota{};
774 template<typename _Val, typename _CharT, typename _Traits>
775 concept __stream_extractable
776 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
777 } // namespace __detail
779 template<movable _Val, typename _CharT,
780 typename _Traits = char_traits<_CharT>>
781 requires default_initializable<_Val>
782 && __detail::__stream_extractable<_Val, _CharT, _Traits>
783 class basic_istream_view
784 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
788 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
789 : _M_stream(std::__addressof(__stream))
795 *_M_stream >> _M_object;
796 return _Iterator{this};
799 constexpr default_sentinel_t
801 { return default_sentinel; }
804 basic_istream<_CharT, _Traits>* _M_stream;
805 _Val _M_object = _Val();
810 using iterator_concept = input_iterator_tag;
811 using difference_type = ptrdiff_t;
812 using value_type = _Val;
815 _Iterator(basic_istream_view* __parent) noexcept
816 : _M_parent(__parent)
819 _Iterator(const _Iterator&) = delete;
820 _Iterator(_Iterator&&) = default;
821 _Iterator& operator=(const _Iterator&) = delete;
822 _Iterator& operator=(_Iterator&&) = default;
827 *_M_parent->_M_stream >> _M_parent->_M_object;
837 { return _M_parent->_M_object; }
840 operator==(const _Iterator& __x, default_sentinel_t)
841 { return __x._M_at_end(); }
844 basic_istream_view* _M_parent;
848 { return !*_M_parent->_M_stream; }
854 template<typename _Val>
855 using istream_view = basic_istream_view<_Val, char>;
857 template<typename _Val>
858 using wistream_view = basic_istream_view<_Val, wchar_t>;
864 template<typename _Tp, typename _Up>
865 concept __can_istream_view = requires (_Up __e) {
866 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
868 } // namespace __detail
870 template<typename _Tp>
873 template<typename _CharT, typename _Traits>
875 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
876 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
877 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
880 template<typename _Tp>
881 inline constexpr _Istream<_Tp> istream;
885 // C++20 24.7 [range.adaptors] Range adaptors
889 template<typename _Tp, int _Disc>
892 // Alias for a type that is conditionally present
893 // (and is an empty type otherwise).
894 // Data members using this alias should use [[no_unique_address]] so that
895 // they take no space when not needed.
896 // The optional template parameter _Disc is for discriminating two otherwise
897 // equivalent absent types so that even they can overlap.
898 template<bool _Present, typename _Tp, int _Disc = 0>
899 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
901 // Alias for a type that is conditionally const.
902 template<bool _Const, typename _Tp>
903 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
905} // namespace __detail
907// Shorthand for __detail::__maybe_const_t.
908using __detail::__maybe_const_t;
910namespace views::__adaptor
912 // True if the range adaptor _Adaptor can be applied with _Args.
913 template<typename _Adaptor, typename... _Args>
914 concept __adaptor_invocable
915 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
917 // True if the range adaptor non-closure _Adaptor can be partially applied
919 template<typename _Adaptor, typename... _Args>
920 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
921 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
922 && (constructible_from<decay_t<_Args>, _Args> && ...);
924 template<typename _Adaptor, typename... _Args>
927 template<typename _Lhs, typename _Rhs>
930 // The base class of every range adaptor closure.
932 // The derived class should define the optional static data member
933 // _S_has_simple_call_op to true if the behavior of this adaptor is
934 // independent of the constness/value category of the adaptor object.
935 template<typename _Derived>
936 struct _RangeAdaptorClosure
939 template<typename _Tp, typename _Up>
940 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
941 void __is_range_adaptor_closure_fn
942 (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined
944 template<typename _Tp>
945 concept __is_range_adaptor_closure
946 = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
948#pragma GCC diagnostic push
949#pragma GCC diagnostic ignored "-Wdangling-reference"
950 // range | adaptor is equivalent to adaptor(range).
951 template<typename _Self, typename _Range>
952 requires __is_range_adaptor_closure<_Self>
953 && __adaptor_invocable<_Self, _Range>
955 operator|(_Range&& __r, _Self&& __self)
956 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
958 // Compose the adaptors __lhs and __rhs into a pipeline, returning
959 // another range adaptor closure object.
960 template<typename _Lhs, typename _Rhs>
961 requires __is_range_adaptor_closure<_Lhs>
962 && __is_range_adaptor_closure<_Rhs>
964 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
966 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
967 std::forward<_Rhs>(__rhs)};
969#pragma GCC diagnostic pop
971 // The base class of every range adaptor non-closure.
973 // The static data member _Derived::_S_arity must contain the total number of
974 // arguments that the adaptor takes, and the class _Derived must introduce
975 // _RangeAdaptor::operator() into the class scope via a using-declaration.
977 // The optional static data member _Derived::_S_has_simple_extra_args should
978 // be defined to true if the behavior of this adaptor is independent of the
979 // constness/value category of the extra arguments. This data member could
980 // also be defined as a variable template parameterized by the types of the
982 template<typename _Derived>
985 // Partially apply the arguments __args to the range adaptor _Derived,
986 // returning a range adaptor closure object.
987 template<typename... _Args>
988 requires __adaptor_partial_app_viable<_Derived, _Args...>
990 operator()(_Args&&... __args) const
992 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
996 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
997 // one that's not overloaded according to constness or value category of the
999 template<typename _Adaptor>
1000 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1002 // True if the behavior of the range adaptor non-closure _Adaptor is
1003 // independent of the value category of its extra arguments _Args.
1004 template<typename _Adaptor, typename... _Args>
1005 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1006 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1008 // A range adaptor closure that represents partial application of
1009 // the range adaptor _Adaptor with arguments _Args.
1010 template<typename _Adaptor, typename... _Args>
1011 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1013 tuple<_Args...> _M_args;
1015 // First parameter is to ensure this constructor is never used
1016 // instead of the copy/move constructor.
1017 template<typename... _Ts>
1019 _Partial(int, _Ts&&... __args)
1020 : _M_args(std::forward<_Ts>(__args)...)
1023 // Invoke _Adaptor with arguments __r, _M_args... according to the
1024 // value category of this _Partial object.
1025#if __cpp_explicit_this_parameter
1026 template<typename _Self, typename _Range>
1027 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1029 operator()(this _Self&& __self, _Range&& __r)
1031 auto __forwarder = [&__r] (auto&&... __args) {
1032 return _Adaptor{}(std::forward<_Range>(__r),
1033 std::forward<decltype(__args)>(__args)...);
1035 return std::apply(__forwarder, __like_t<_Self, _Partial>(__self)._M_args);
1038 template<typename _Range>
1039 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1041 operator()(_Range&& __r) const &
1043 auto __forwarder = [&__r] (const auto&... __args) {
1044 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1046 return std::apply(__forwarder, _M_args);
1049 template<typename _Range>
1050 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1052 operator()(_Range&& __r) &&
1054 auto __forwarder = [&__r] (auto&... __args) {
1055 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
1057 return std::apply(__forwarder, _M_args);
1060 template<typename _Range>
1062 operator()(_Range&& __r) const && = delete;
1066 // A lightweight specialization of the above primary template for
1067 // the common case where _Adaptor accepts a single extra argument.
1068 template<typename _Adaptor, typename _Arg>
1069 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1073 template<typename _Tp>
1075 _Partial(int, _Tp&& __arg)
1076 : _M_arg(std::forward<_Tp>(__arg))
1079#if __cpp_explicit_this_parameter
1080 template<typename _Self, typename _Range>
1081 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Arg>>
1083 operator()(this _Self&& __self, _Range&& __r)
1085 return _Adaptor{}(std::forward<_Range>(__r),
1086 __like_t<_Self, _Partial>(__self)._M_arg);
1089 template<typename _Range>
1090 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1092 operator()(_Range&& __r) const &
1093 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1095 template<typename _Range>
1096 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
1098 operator()(_Range&& __r) &&
1099 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
1101 template<typename _Range>
1103 operator()(_Range&& __r) const && = delete;
1107 // Partial specialization of the primary template for the case where the extra
1108 // arguments of the adaptor can always be safely and efficiently forwarded by
1109 // const reference. This lets us get away with a single operator() overload,
1110 // which makes overload resolution failure diagnostics more concise.
1111 template<typename _Adaptor, typename... _Args>
1112 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1113 && (is_trivially_copyable_v<_Args> && ...)
1114 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1116 tuple<_Args...> _M_args;
1118 template<typename... _Ts>
1120 _Partial(int, _Ts&&... __args)
1121 : _M_args(std::forward<_Ts>(__args)...)
1124 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1125 // of the value category of this _Partial object.
1126 template<typename _Range>
1127 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1129 operator()(_Range&& __r) const
1131 auto __forwarder = [&__r] (const auto&... __args) {
1132 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1134 return std::apply(__forwarder, _M_args);
1137 static constexpr bool _S_has_simple_call_op = true;
1140 // A lightweight specialization of the above template for the common case
1141 // where _Adaptor accepts a single extra argument.
1142 template<typename _Adaptor, typename _Arg>
1143 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1144 && is_trivially_copyable_v<_Arg>
1145 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1149 template<typename _Tp>
1151 _Partial(int, _Tp&& __arg)
1152 : _M_arg(std::forward<_Tp>(__arg))
1155 template<typename _Range>
1156 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1158 operator()(_Range&& __r) const
1159 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1161 static constexpr bool _S_has_simple_call_op = true;
1164 template<typename _Lhs, typename _Rhs, typename _Range>
1165 concept __pipe_invocable
1166 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1168 // A range adaptor closure that represents composition of the range
1169 // adaptor closures _Lhs and _Rhs.
1170 template<typename _Lhs, typename _Rhs>
1171 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1173 [[no_unique_address]] _Lhs _M_lhs;
1174 [[no_unique_address]] _Rhs _M_rhs;
1176 template<typename _Tp, typename _Up>
1178 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1179 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1182 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1183 // range adaptor closure object.
1184#if __cpp_explicit_this_parameter
1185 template<typename _Self, typename _Range>
1186 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1188 operator()(this _Self&& __self, _Range&& __r)
1190 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1191 (__like_t<_Self, _Pipe>(__self)._M_lhs
1192 (std::forward<_Range>(__r))));
1195 template<typename _Range>
1196 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1198 operator()(_Range&& __r) const &
1199 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1201 template<typename _Range>
1202 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1204 operator()(_Range&& __r) &&
1205 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1207 template<typename _Range>
1209 operator()(_Range&& __r) const && = delete;
1213 // A partial specialization of the above primary template for the case where
1214 // both adaptor operands have a simple operator(). This in turn lets us
1215 // implement composition using a single simple operator(), which makes
1216 // overload resolution failure diagnostics more concise.
1217 template<typename _Lhs, typename _Rhs>
1218 requires __closure_has_simple_call_op<_Lhs>
1219 && __closure_has_simple_call_op<_Rhs>
1220 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1222 [[no_unique_address]] _Lhs _M_lhs;
1223 [[no_unique_address]] _Rhs _M_rhs;
1225 template<typename _Tp, typename _Up>
1227 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1228 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1231 template<typename _Range>
1232 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1234 operator()(_Range&& __r) const
1235 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1237 static constexpr bool _S_has_simple_call_op = true;
1239} // namespace views::__adaptor
1241#if __cpp_lib_ranges >= 202202L
1242 // P2387R3 Pipe support for user-defined range adaptors
1243 template<typename _Derived>
1244 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1245 class range_adaptor_closure
1246 : public views::__adaptor::_RangeAdaptorClosure<_Derived>
1250 template<range _Range> requires is_object_v<_Range>
1251 class ref_view : public view_interface<ref_view<_Range>>
1256 static void _S_fun(_Range&); // not defined
1257 static void _S_fun(_Range&&) = delete;
1260 template<__detail::__different_from<ref_view> _Tp>
1261 requires convertible_to<_Tp, _Range&>
1262 && requires { _S_fun(declval<_Tp>()); }
1265 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1266 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1273 constexpr iterator_t<_Range>
1275 { return ranges::begin(*_M_r); }
1277 constexpr sentinel_t<_Range>
1279 { return ranges::end(*_M_r); }
1282 empty() const requires requires { ranges::empty(*_M_r); }
1283 { return ranges::empty(*_M_r); }
1286 size() const requires sized_range<_Range>
1287 { return ranges::size(*_M_r); }
1290 data() const requires contiguous_range<_Range>
1291 { return ranges::data(*_M_r); }
1294 template<typename _Range>
1295 ref_view(_Range&) -> ref_view<_Range>;
1297 template<typename _Tp>
1298 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1300 template<range _Range>
1301 requires movable<_Range>
1302 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1303 class owning_view : public view_interface<owning_view<_Range>>
1306 _Range _M_r = _Range();
1309 owning_view() requires default_initializable<_Range> = default;
1312 owning_view(_Range&& __t)
1313 noexcept(is_nothrow_move_constructible_v<_Range>)
1314 : _M_r(std::move(__t))
1317 owning_view(owning_view&&) = default;
1318 owning_view& operator=(owning_view&&) = default;
1324 constexpr const _Range&
1325 base() const& noexcept
1330 { return std::move(_M_r); }
1332 constexpr const _Range&&
1333 base() const&& noexcept
1334 { return std::move(_M_r); }
1336 constexpr iterator_t<_Range>
1338 { return ranges::begin(_M_r); }
1340 constexpr sentinel_t<_Range>
1342 { return ranges::end(_M_r); }
1345 begin() const requires range<const _Range>
1346 { return ranges::begin(_M_r); }
1349 end() const requires range<const _Range>
1350 { return ranges::end(_M_r); }
1353 empty() requires requires { ranges::empty(_M_r); }
1354 { return ranges::empty(_M_r); }
1357 empty() const requires requires { ranges::empty(_M_r); }
1358 { return ranges::empty(_M_r); }
1361 size() requires sized_range<_Range>
1362 { return ranges::size(_M_r); }
1365 size() const requires sized_range<const _Range>
1366 { return ranges::size(_M_r); }
1369 data() requires contiguous_range<_Range>
1370 { return ranges::data(_M_r); }
1373 data() const requires contiguous_range<const _Range>
1374 { return ranges::data(_M_r); }
1377 template<typename _Tp>
1378 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1379 = enable_borrowed_range<_Tp>;
1385 template<typename _Range>
1386 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1388 template<typename _Range>
1389 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1390 } // namespace __detail
1392 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1394 template<typename _Range>
1395 static constexpr bool
1398 if constexpr (view<decay_t<_Range>>)
1399 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1400 else if constexpr (__detail::__can_ref_view<_Range>)
1403 return noexcept(owning_view{std::declval<_Range>()});
1406 template<viewable_range _Range>
1407 requires view<decay_t<_Range>>
1408 || __detail::__can_ref_view<_Range>
1409 || __detail::__can_owning_view<_Range>
1411 operator() [[nodiscard]] (_Range&& __r) const
1412 noexcept(_S_noexcept<_Range>())
1414 if constexpr (view<decay_t<_Range>>)
1415 return std::forward<_Range>(__r);
1416 else if constexpr (__detail::__can_ref_view<_Range>)
1417 return ref_view{std::forward<_Range>(__r)};
1419 return owning_view{std::forward<_Range>(__r)};
1422 static constexpr bool _S_has_simple_call_op = true;
1425 inline constexpr _All all;
1427 template<viewable_range _Range>
1428 using all_t = decltype(all(std::declval<_Range>()));
1429 } // namespace views
1433 template<typename _Tp>
1434 struct __non_propagating_cache
1436 // When _Tp is not an object type (e.g. is a reference type), we make
1437 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1438 // users can easily conditionally declare data members with this type
1439 // (such as join_view::_M_inner).
1442 template<typename _Tp>
1443 requires is_object_v<_Tp>
1444 struct __non_propagating_cache<_Tp>
1445 : protected _Optional_base<_Tp>
1447 __non_propagating_cache() = default;
1450 __non_propagating_cache(const __non_propagating_cache&) noexcept
1454 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1455 { __other._M_reset(); }
1457 constexpr __non_propagating_cache&
1458 operator=(const __non_propagating_cache& __other) noexcept
1460 if (std::__addressof(__other) != this)
1465 constexpr __non_propagating_cache&
1466 operator=(__non_propagating_cache&& __other) noexcept
1473 constexpr __non_propagating_cache&
1474 operator=(_Tp __val)
1477 this->_M_payload._M_construct(std::move(__val));
1482 operator bool() const noexcept
1483 { return this->_M_is_engaged(); }
1486 operator*() noexcept
1487 { return this->_M_get(); }
1489 constexpr const _Tp&
1490 operator*() const noexcept
1491 { return this->_M_get(); }
1493 template<typename _Iter>
1495 _M_emplace_deref(const _Iter& __i)
1498 auto __f = [] (auto& __x) { return *__x; };
1499 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1500 return this->_M_get();
1504 template<range _Range>
1505 struct _CachedPosition
1508 _M_has_value() const
1511 constexpr iterator_t<_Range>
1512 _M_get(const _Range&) const
1514 __glibcxx_assert(false);
1515 __builtin_unreachable();
1519 _M_set(const _Range&, const iterator_t<_Range>&) const
1523 template<forward_range _Range>
1524 struct _CachedPosition<_Range>
1525 : protected __non_propagating_cache<iterator_t<_Range>>
1528 _M_has_value() const
1529 { return this->_M_is_engaged(); }
1531 constexpr iterator_t<_Range>
1532 _M_get(const _Range&) const
1534 __glibcxx_assert(_M_has_value());
1539 _M_set(const _Range&, const iterator_t<_Range>& __it)
1541 __glibcxx_assert(!_M_has_value());
1542 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1544 this->_M_payload._M_engaged = true;
1548 template<random_access_range _Range>
1549 requires (sizeof(range_difference_t<_Range>)
1550 <= sizeof(iterator_t<_Range>))
1551 struct _CachedPosition<_Range>
1554 range_difference_t<_Range> _M_offset = -1;
1557 _CachedPosition() = default;
1560 _CachedPosition(const _CachedPosition&) = default;
1563 _CachedPosition(_CachedPosition&& __other) noexcept
1564 { *this = std::move(__other); }
1566 constexpr _CachedPosition&
1567 operator=(const _CachedPosition&) = default;
1569 constexpr _CachedPosition&
1570 operator=(_CachedPosition&& __other) noexcept
1572 // Propagate the cached offset, but invalidate the source.
1573 _M_offset = __other._M_offset;
1574 __other._M_offset = -1;
1579 _M_has_value() const
1580 { return _M_offset >= 0; }
1582 constexpr iterator_t<_Range>
1583 _M_get(_Range& __r) const
1585 __glibcxx_assert(_M_has_value());
1586 return ranges::begin(__r) + _M_offset;
1590 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1592 __glibcxx_assert(!_M_has_value());
1593 _M_offset = __it - ranges::begin(__r);
1596 } // namespace __detail
1600 template<typename _Base>
1601 struct __filter_view_iter_cat
1604 template<forward_range _Base>
1605 struct __filter_view_iter_cat<_Base>
1611 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1612 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1613 return bidirectional_iterator_tag{};
1614 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1615 return forward_iterator_tag{};
1620 using iterator_category = decltype(_S_iter_cat());
1622 } // namespace __detail
1624 template<input_range _Vp,
1625 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1626 requires view<_Vp> && is_object_v<_Pred>
1627 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1632 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1635 static constexpr auto
1638 if constexpr (bidirectional_range<_Vp>)
1639 return bidirectional_iterator_tag{};
1640 else if constexpr (forward_range<_Vp>)
1641 return forward_iterator_tag{};
1643 return input_iterator_tag{};
1648 using _Vp_iter = iterator_t<_Vp>;
1650 _Vp_iter _M_current = _Vp_iter();
1651 filter_view* _M_parent = nullptr;
1654 using iterator_concept = decltype(_S_iter_concept());
1655 // iterator_category defined in __filter_view_iter_cat
1656 using value_type = range_value_t<_Vp>;
1657 using difference_type = range_difference_t<_Vp>;
1659 _Iterator() requires default_initializable<_Vp_iter> = default;
1662 _Iterator(filter_view* __parent, _Vp_iter __current)
1663 : _M_current(std::move(__current)),
1667 constexpr const _Vp_iter&
1668 base() const & noexcept
1669 { return _M_current; }
1673 { return std::move(_M_current); }
1675 constexpr range_reference_t<_Vp>
1677 { return *_M_current; }
1681 requires __detail::__has_arrow<_Vp_iter>
1682 && copyable<_Vp_iter>
1683 { return _M_current; }
1685 constexpr _Iterator&
1688 _M_current = ranges::find_if(std::move(++_M_current),
1689 ranges::end(_M_parent->_M_base),
1690 std::ref(*_M_parent->_M_pred));
1699 operator++(int) requires forward_range<_Vp>
1706 constexpr _Iterator&
1707 operator--() requires bidirectional_range<_Vp>
1711 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1716 operator--(int) requires bidirectional_range<_Vp>
1723 friend constexpr bool
1724 operator==(const _Iterator& __x, const _Iterator& __y)
1725 requires equality_comparable<_Vp_iter>
1726 { return __x._M_current == __y._M_current; }
1728 friend constexpr range_rvalue_reference_t<_Vp>
1729 iter_move(const _Iterator& __i)
1730 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1731 { return ranges::iter_move(__i._M_current); }
1733 friend constexpr void
1734 iter_swap(const _Iterator& __x, const _Iterator& __y)
1735 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1736 requires indirectly_swappable<_Vp_iter>
1737 { ranges::iter_swap(__x._M_current, __y._M_current); }
1743 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1746 __equal(const _Iterator& __i) const
1747 { return __i._M_current == _M_end; }
1750 _Sentinel() = default;
1753 _Sentinel(filter_view* __parent)
1754 : _M_end(ranges::end(__parent->_M_base))
1757 constexpr sentinel_t<_Vp>
1761 friend constexpr bool
1762 operator==(const _Iterator& __x, const _Sentinel& __y)
1763 { return __y.__equal(__x); }
1766 _Vp _M_base = _Vp();
1767 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1768 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1771 filter_view() requires (default_initializable<_Vp>
1772 && default_initializable<_Pred>)
1776 filter_view(_Vp __base, _Pred __pred)
1777 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1781 base() const& requires copy_constructible<_Vp>
1786 { return std::move(_M_base); }
1788 constexpr const _Pred&
1790 { return *_M_pred; }
1795 if (_M_cached_begin._M_has_value())
1796 return {this, _M_cached_begin._M_get(_M_base)};
1798 __glibcxx_assert(_M_pred.has_value());
1799 auto __it = ranges::find_if(ranges::begin(_M_base),
1800 ranges::end(_M_base),
1801 std::ref(*_M_pred));
1802 _M_cached_begin._M_set(_M_base, __it);
1803 return {this, std::move(__it)};
1809 if constexpr (common_range<_Vp>)
1810 return _Iterator{this, ranges::end(_M_base)};
1812 return _Sentinel{this};
1816 template<typename _Range, typename _Pred>
1817 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1823 template<typename _Range, typename _Pred>
1824 concept __can_filter_view
1825 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1826 } // namespace __detail
1828 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1830 template<viewable_range _Range, typename _Pred>
1831 requires __detail::__can_filter_view<_Range, _Pred>
1833 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1835 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1838 using _RangeAdaptor<_Filter>::operator();
1839 static constexpr int _S_arity = 2;
1840 static constexpr bool _S_has_simple_extra_args = true;
1843 inline constexpr _Filter filter;
1844 } // namespace views
1846#if __cpp_lib_ranges >= 202207L // C++ >= 23
1847 template<input_range _Vp, move_constructible _Fp>
1849 template<input_range _Vp, copy_constructible _Fp>
1851 requires view<_Vp> && is_object_v<_Fp>
1852 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1853 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1854 range_reference_t<_Vp>>>
1855 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1858 template<bool _Const>
1859 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1861 template<bool _Const>
1865 template<bool _Const>
1866 requires forward_range<_Base<_Const>>
1867 struct __iter_cat<_Const>
1873 using _Base = transform_view::_Base<_Const>;
1874 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1875 if constexpr (is_lvalue_reference_v<_Res>)
1878 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1879 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1880 return random_access_iterator_tag{};
1885 return input_iterator_tag{};
1888 using iterator_category = decltype(_S_iter_cat());
1891 template<bool _Const>
1894 template<bool _Const>
1895 struct _Iterator : __iter_cat<_Const>
1898 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1899 using _Base = transform_view::_Base<_Const>;
1904 if constexpr (random_access_range<_Base>)
1905 return random_access_iterator_tag{};
1906 else if constexpr (bidirectional_range<_Base>)
1907 return bidirectional_iterator_tag{};
1908 else if constexpr (forward_range<_Base>)
1909 return forward_iterator_tag{};
1911 return input_iterator_tag{};
1914 using _Base_iter = iterator_t<_Base>;
1916 _Base_iter _M_current = _Base_iter();
1917 _Parent* _M_parent = nullptr;
1920 using iterator_concept = decltype(_S_iter_concept());
1921 // iterator_category defined in __transform_view_iter_cat
1923 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1924 using difference_type = range_difference_t<_Base>;
1926 _Iterator() requires default_initializable<_Base_iter> = default;
1929 _Iterator(_Parent* __parent, _Base_iter __current)
1930 : _M_current(std::move(__current)),
1935 _Iterator(_Iterator<!_Const> __i)
1937 && convertible_to<iterator_t<_Vp>, _Base_iter>
1938 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1941 constexpr const _Base_iter&
1942 base() const & noexcept
1943 { return _M_current; }
1945 constexpr _Base_iter
1947 { return std::move(_M_current); }
1949 constexpr decltype(auto)
1951 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1952 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1954 constexpr _Iterator&
1966 operator++(int) requires forward_range<_Base>
1973 constexpr _Iterator&
1974 operator--() requires bidirectional_range<_Base>
1981 operator--(int) requires bidirectional_range<_Base>
1988 constexpr _Iterator&
1989 operator+=(difference_type __n) requires random_access_range<_Base>
1995 constexpr _Iterator&
1996 operator-=(difference_type __n) requires random_access_range<_Base>
2002 constexpr decltype(auto)
2003 operator[](difference_type __n) const
2004 requires random_access_range<_Base>
2005 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
2007 friend constexpr bool
2008 operator==(const _Iterator& __x, const _Iterator& __y)
2009 requires equality_comparable<_Base_iter>
2010 { return __x._M_current == __y._M_current; }
2012 friend constexpr bool
2013 operator<(const _Iterator& __x, const _Iterator& __y)
2014 requires random_access_range<_Base>
2015 { return __x._M_current < __y._M_current; }
2017 friend constexpr bool
2018 operator>(const _Iterator& __x, const _Iterator& __y)
2019 requires random_access_range<_Base>
2020 { return __y < __x; }
2022 friend constexpr bool
2023 operator<=(const _Iterator& __x, const _Iterator& __y)
2024 requires random_access_range<_Base>
2025 { return !(__y < __x); }
2027 friend constexpr bool
2028 operator>=(const _Iterator& __x, const _Iterator& __y)
2029 requires random_access_range<_Base>
2030 { return !(__x < __y); }
2032#ifdef __cpp_lib_three_way_comparison
2033 friend constexpr auto
2034 operator<=>(const _Iterator& __x, const _Iterator& __y)
2035 requires random_access_range<_Base>
2036 && three_way_comparable<_Base_iter>
2037 { return __x._M_current <=> __y._M_current; }
2040 friend constexpr _Iterator
2041 operator+(_Iterator __i, difference_type __n)
2042 requires random_access_range<_Base>
2043 { return {__i._M_parent, __i._M_current + __n}; }
2045 friend constexpr _Iterator
2046 operator+(difference_type __n, _Iterator __i)
2047 requires random_access_range<_Base>
2048 { return {__i._M_parent, __i._M_current + __n}; }
2050 friend constexpr _Iterator
2051 operator-(_Iterator __i, difference_type __n)
2052 requires random_access_range<_Base>
2053 { return {__i._M_parent, __i._M_current - __n}; }
2055 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2056 // 3483. transform_view::iterator's difference is overconstrained
2057 friend constexpr difference_type
2058 operator-(const _Iterator& __x, const _Iterator& __y)
2059 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2060 { return __x._M_current - __y._M_current; }
2062 friend constexpr decltype(auto)
2063 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
2065 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
2066 return std::move(*__i);
2071 friend _Iterator<!_Const>;
2072 template<bool> friend struct _Sentinel;
2075 template<bool _Const>
2079 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2080 using _Base = transform_view::_Base<_Const>;
2082 template<bool _Const2>
2084 __distance_from(const _Iterator<_Const2>& __i) const
2085 { return _M_end - __i._M_current; }
2087 template<bool _Const2>
2089 __equal(const _Iterator<_Const2>& __i) const
2090 { return __i._M_current == _M_end; }
2092 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2095 _Sentinel() = default;
2098 _Sentinel(sentinel_t<_Base> __end)
2103 _Sentinel(_Sentinel<!_Const> __i)
2105 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2106 : _M_end(std::move(__i._M_end))
2109 constexpr sentinel_t<_Base>
2113 template<bool _Const2>
2114 requires sentinel_for<sentinel_t<_Base>,
2115 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2116 friend constexpr bool
2117 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2118 { return __y.__equal(__x); }
2120 template<bool _Const2,
2121 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2122 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2123 friend constexpr range_difference_t<_Base2>
2124 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2125 { return -__y.__distance_from(__x); }
2127 template<bool _Const2,
2128 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2129 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2130 friend constexpr range_difference_t<_Base2>
2131 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2132 { return __y.__distance_from(__x); }
2134 friend _Sentinel<!_Const>;
2137 _Vp _M_base = _Vp();
2138 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2141 transform_view() requires (default_initializable<_Vp>
2142 && default_initializable<_Fp>)
2146 transform_view(_Vp __base, _Fp __fun)
2147 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2151 base() const& requires copy_constructible<_Vp>
2152 { return _M_base ; }
2156 { return std::move(_M_base); }
2158 constexpr _Iterator<false>
2160 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2162 constexpr _Iterator<true>
2164 requires range<const _Vp>
2165 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2166 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2168 constexpr _Sentinel<false>
2170 { return _Sentinel<false>{ranges::end(_M_base)}; }
2172 constexpr _Iterator<false>
2173 end() requires common_range<_Vp>
2174 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2176 constexpr _Sentinel<true>
2178 requires range<const _Vp>
2179 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2180 { return _Sentinel<true>{ranges::end(_M_base)}; }
2182 constexpr _Iterator<true>
2184 requires common_range<const _Vp>
2185 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2186 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2189 size() requires sized_range<_Vp>
2190 { return ranges::size(_M_base); }
2193 size() const requires sized_range<const _Vp>
2194 { return ranges::size(_M_base); }
2197 template<typename _Range, typename _Fp>
2198 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2204 template<typename _Range, typename _Fp>
2205 concept __can_transform_view
2206 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2207 } // namespace __detail
2209 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2211 template<viewable_range _Range, typename _Fp>
2212 requires __detail::__can_transform_view<_Range, _Fp>
2214 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2216 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2219 using _RangeAdaptor<_Transform>::operator();
2220 static constexpr int _S_arity = 2;
2221 static constexpr bool _S_has_simple_extra_args = true;
2224 inline constexpr _Transform transform;
2225 } // namespace views
2228 class take_view : public view_interface<take_view<_Vp>>
2231 template<bool _Const>
2232 using _CI = counted_iterator<
2233 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2235 template<bool _Const>
2239 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2240 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2243 _Sentinel() = default;
2246 _Sentinel(sentinel_t<_Base> __end)
2251 _Sentinel(_Sentinel<!_Const> __s)
2252 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2253 : _M_end(std::move(__s._M_end))
2256 constexpr sentinel_t<_Base>
2260 friend constexpr bool
2261 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2262 { return __y.count() == 0 || __y.base() == __x._M_end; }
2264 template<bool _OtherConst = !_Const,
2265 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2266 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2267 friend constexpr bool
2268 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2269 { return __y.count() == 0 || __y.base() == __x._M_end; }
2271 friend _Sentinel<!_Const>;
2274 _Vp _M_base = _Vp();
2275 range_difference_t<_Vp> _M_count = 0;
2278 take_view() requires default_initializable<_Vp> = default;
2281 take_view(_Vp __base, range_difference_t<_Vp> __count)
2282 : _M_base(std::move(__base)), _M_count(std::move(__count))
2286 base() const& requires copy_constructible<_Vp>
2291 { return std::move(_M_base); }
2294 begin() requires (!__detail::__simple_view<_Vp>)
2296 if constexpr (sized_range<_Vp>)
2298 if constexpr (random_access_range<_Vp>)
2299 return ranges::begin(_M_base);
2303 return counted_iterator(ranges::begin(_M_base), __sz);
2307 return counted_iterator(ranges::begin(_M_base), _M_count);
2311 begin() const requires range<const _Vp>
2313 if constexpr (sized_range<const _Vp>)
2315 if constexpr (random_access_range<const _Vp>)
2316 return ranges::begin(_M_base);
2320 return counted_iterator(ranges::begin(_M_base), __sz);
2324 return counted_iterator(ranges::begin(_M_base), _M_count);
2328 end() requires (!__detail::__simple_view<_Vp>)
2330 if constexpr (sized_range<_Vp>)
2332 if constexpr (random_access_range<_Vp>)
2333 return ranges::begin(_M_base) + size();
2335 return default_sentinel;
2338 return _Sentinel<false>{ranges::end(_M_base)};
2342 end() const requires range<const _Vp>
2344 if constexpr (sized_range<const _Vp>)
2346 if constexpr (random_access_range<const _Vp>)
2347 return ranges::begin(_M_base) + size();
2349 return default_sentinel;
2352 return _Sentinel<true>{ranges::end(_M_base)};
2356 size() requires sized_range<_Vp>
2358 auto __n = ranges::size(_M_base);
2359 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2363 size() const requires sized_range<const _Vp>
2365 auto __n = ranges::size(_M_base);
2366 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2370 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2371 // 3447. Deduction guides for take_view and drop_view have different
2373 template<typename _Range>
2374 take_view(_Range&&, range_difference_t<_Range>)
2375 -> take_view<views::all_t<_Range>>;
2377 template<typename _Tp>
2378 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2379 = enable_borrowed_range<_Tp>;
2385 template<typename _Range>
2386 inline constexpr bool __is_empty_view = false;
2388 template<typename _Tp>
2389 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2391 template<typename _Range>
2392 inline constexpr bool __is_basic_string_view = false;
2394 template<typename _CharT, typename _Traits>
2395 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2398 using ranges::__detail::__is_subrange;
2400 template<typename _Range>
2401 inline constexpr bool __is_iota_view = false;
2403 template<typename _Winc, typename _Bound>
2404 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2406 template<typename _Range>
2407 inline constexpr bool __is_repeat_view = false;
2409 template<typename _Range>
2411 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2413 template<typename _Range, typename _Dp>
2414 concept __can_take_view
2415 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2416 } // namespace __detail
2418 struct _Take : __adaptor::_RangeAdaptor<_Take>
2420 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2421 requires __detail::__can_take_view<_Range, _Dp>
2423 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2425 using _Tp = remove_cvref_t<_Range>;
2426 if constexpr (__detail::__is_empty_view<_Tp>)
2428 else if constexpr (random_access_range<_Tp>
2430 && (std::__detail::__is_span<_Tp>
2431 || __detail::__is_basic_string_view<_Tp>
2432 || __detail::__is_subrange<_Tp>
2433 || __detail::__is_iota_view<_Tp>))
2435 __n = std::min<_Dp>(ranges::distance(__r), __n);
2436 auto __begin = ranges::begin(__r);
2437 auto __end = __begin + __n;
2438 if constexpr (std::__detail::__is_span<_Tp>)
2439 return span<typename _Tp::element_type>(__begin, __end);
2440 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2441 return _Tp(__begin, __end);
2442 else if constexpr (__detail::__is_subrange<_Tp>)
2443 return subrange<iterator_t<_Tp>>(__begin, __end);
2445 return iota_view(*__begin, *__end);
2447 else if constexpr (__detail::__is_repeat_view<_Tp>)
2448 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2450 return take_view(std::forward<_Range>(__r), __n);
2453 using _RangeAdaptor<_Take>::operator();
2454 static constexpr int _S_arity = 2;
2455 // The count argument of views::take is not always simple -- it can be
2456 // e.g. a move-only class that's implicitly convertible to the difference
2457 // type. But an integer-like count argument is surely simple.
2458 template<typename _Tp>
2459 static constexpr bool _S_has_simple_extra_args
2460 = ranges::__detail::__is_integer_like<_Tp>;
2463 inline constexpr _Take take;
2464 } // namespace views
2466 template<view _Vp, typename _Pred>
2467 requires input_range<_Vp> && is_object_v<_Pred>
2468 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2469 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2471 template<bool _Const>
2475 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2477 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2478 const _Pred* _M_pred = nullptr;
2481 _Sentinel() = default;
2484 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2485 : _M_end(__end), _M_pred(__pred)
2489 _Sentinel(_Sentinel<!_Const> __s)
2490 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2491 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2494 constexpr sentinel_t<_Base>
2495 base() const { return _M_end; }
2497 friend constexpr bool
2498 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2499 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2501 template<bool _OtherConst = !_Const,
2502 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2503 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2504 friend constexpr bool
2505 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2506 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2508 friend _Sentinel<!_Const>;
2511 _Vp _M_base = _Vp();
2512 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2515 take_while_view() requires (default_initializable<_Vp>
2516 && default_initializable<_Pred>)
2520 take_while_view(_Vp __base, _Pred __pred)
2521 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2525 base() const& requires copy_constructible<_Vp>
2530 { return std::move(_M_base); }
2532 constexpr const _Pred&
2534 { return *_M_pred; }
2537 begin() requires (!__detail::__simple_view<_Vp>)
2538 { return ranges::begin(_M_base); }
2541 begin() const requires range<const _Vp>
2542 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2543 { return ranges::begin(_M_base); }
2546 end() requires (!__detail::__simple_view<_Vp>)
2547 { return _Sentinel<false>(ranges::end(_M_base),
2548 std::__addressof(*_M_pred)); }
2551 end() const requires range<const _Vp>
2552 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2553 { return _Sentinel<true>(ranges::end(_M_base),
2554 std::__addressof(*_M_pred)); }
2557 template<typename _Range, typename _Pred>
2558 take_while_view(_Range&&, _Pred)
2559 -> take_while_view<views::all_t<_Range>, _Pred>;
2565 template<typename _Range, typename _Pred>
2566 concept __can_take_while_view
2567 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2568 } // namespace __detail
2570 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2572 template<viewable_range _Range, typename _Pred>
2573 requires __detail::__can_take_while_view<_Range, _Pred>
2575 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2577 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2580 using _RangeAdaptor<_TakeWhile>::operator();
2581 static constexpr int _S_arity = 2;
2582 static constexpr bool _S_has_simple_extra_args = true;
2585 inline constexpr _TakeWhile take_while;
2586 } // namespace views
2589 class drop_view : public view_interface<drop_view<_Vp>>
2592 _Vp _M_base = _Vp();
2593 range_difference_t<_Vp> _M_count = 0;
2595 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2596 // both random_access_range and sized_range. Otherwise, cache its result.
2597 static constexpr bool _S_needs_cached_begin
2598 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2599 [[no_unique_address]]
2600 __detail::__maybe_present_t<_S_needs_cached_begin,
2601 __detail::_CachedPosition<_Vp>>
2605 drop_view() requires default_initializable<_Vp> = default;
2608 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2609 : _M_base(std::move(__base)), _M_count(__count)
2610 { __glibcxx_assert(__count >= 0); }
2613 base() const& requires copy_constructible<_Vp>
2618 { return std::move(_M_base); }
2620 // This overload is disabled for simple views with constant-time begin().
2623 requires (!(__detail::__simple_view<_Vp>
2624 && random_access_range<const _Vp>
2625 && sized_range<const _Vp>))
2627 if constexpr (_S_needs_cached_begin)
2628 if (_M_cached_begin._M_has_value())
2629 return _M_cached_begin._M_get(_M_base);
2631 auto __it = ranges::next(ranges::begin(_M_base),
2632 _M_count, ranges::end(_M_base));
2633 if constexpr (_S_needs_cached_begin)
2634 _M_cached_begin._M_set(_M_base, __it);
2638 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2639 // 3482. drop_view's const begin should additionally require sized_range
2642 requires random_access_range<const _Vp> && sized_range<const _Vp>
2644 return ranges::next(ranges::begin(_M_base), _M_count,
2645 ranges::end(_M_base));
2649 end() requires (!__detail::__simple_view<_Vp>)
2650 { return ranges::end(_M_base); }
2653 end() const requires range<const _Vp>
2654 { return ranges::end(_M_base); }
2657 size() requires sized_range<_Vp>
2659 const auto __s = ranges::size(_M_base);
2660 const auto __c = static_cast<decltype(__s)>(_M_count);
2661 return __s < __c ? 0 : __s - __c;
2665 size() const requires sized_range<const _Vp>
2667 const auto __s = ranges::size(_M_base);
2668 const auto __c = static_cast<decltype(__s)>(_M_count);
2669 return __s < __c ? 0 : __s - __c;
2673 template<typename _Range>
2674 drop_view(_Range&&, range_difference_t<_Range>)
2675 -> drop_view<views::all_t<_Range>>;
2677 template<typename _Tp>
2678 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2679 = enable_borrowed_range<_Tp>;
2685 template<typename _Range>
2687 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2689 template<typename _Range, typename _Dp>
2690 concept __can_drop_view
2691 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2692 } // namespace __detail
2694 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2696 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2697 requires __detail::__can_drop_view<_Range, _Dp>
2699 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2701 using _Tp = remove_cvref_t<_Range>;
2702 if constexpr (__detail::__is_empty_view<_Tp>)
2704 else if constexpr (random_access_range<_Tp>
2706 && (std::__detail::__is_span<_Tp>
2707 || __detail::__is_basic_string_view<_Tp>
2708 || __detail::__is_iota_view<_Tp>
2709 || __detail::__is_subrange<_Tp>))
2711 __n = std::min<_Dp>(ranges::distance(__r), __n);
2712 auto __begin = ranges::begin(__r) + __n;
2713 auto __end = ranges::end(__r);
2714 if constexpr (std::__detail::__is_span<_Tp>)
2715 return span<typename _Tp::element_type>(__begin, __end);
2716 else if constexpr (__detail::__is_subrange<_Tp>)
2718 if constexpr (_Tp::_S_store_size)
2720 using ranges::__detail::__to_unsigned_like;
2721 auto __m = ranges::distance(__r) - __n;
2722 return _Tp(__begin, __end, __to_unsigned_like(__m));
2725 return _Tp(__begin, __end);
2728 return _Tp(__begin, __end);
2730 else if constexpr (__detail::__is_repeat_view<_Tp>)
2731 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2733 return drop_view(std::forward<_Range>(__r), __n);
2736 using _RangeAdaptor<_Drop>::operator();
2737 static constexpr int _S_arity = 2;
2738 template<typename _Tp>
2739 static constexpr bool _S_has_simple_extra_args
2740 = _Take::_S_has_simple_extra_args<_Tp>;
2743 inline constexpr _Drop drop;
2744 } // namespace views
2746 template<view _Vp, typename _Pred>
2747 requires input_range<_Vp> && is_object_v<_Pred>
2748 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2749 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2752 _Vp _M_base = _Vp();
2753 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2754 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2757 drop_while_view() requires (default_initializable<_Vp>
2758 && default_initializable<_Pred>)
2762 drop_while_view(_Vp __base, _Pred __pred)
2763 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2767 base() const& requires copy_constructible<_Vp>
2772 { return std::move(_M_base); }
2774 constexpr const _Pred&
2776 { return *_M_pred; }
2781 if (_M_cached_begin._M_has_value())
2782 return _M_cached_begin._M_get(_M_base);
2784 __glibcxx_assert(_M_pred.has_value());
2785 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2786 ranges::end(_M_base),
2787 std::cref(*_M_pred));
2788 _M_cached_begin._M_set(_M_base, __it);
2794 { return ranges::end(_M_base); }
2797 template<typename _Range, typename _Pred>
2798 drop_while_view(_Range&&, _Pred)
2799 -> drop_while_view<views::all_t<_Range>, _Pred>;
2801 template<typename _Tp, typename _Pred>
2802 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2803 = enable_borrowed_range<_Tp>;
2809 template<typename _Range, typename _Pred>
2810 concept __can_drop_while_view
2811 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2812 } // namespace __detail
2814 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2816 template<viewable_range _Range, typename _Pred>
2817 requires __detail::__can_drop_while_view<_Range, _Pred>
2819 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2821 return drop_while_view(std::forward<_Range>(__r),
2822 std::forward<_Pred>(__p));
2825 using _RangeAdaptor<_DropWhile>::operator();
2826 static constexpr int _S_arity = 2;
2827 static constexpr bool _S_has_simple_extra_args = true;
2830 inline constexpr _DropWhile drop_while;
2831 } // namespace views
2835 template<typename _Tp>
2837 __as_lvalue(_Tp&& __t)
2838 { return static_cast<_Tp&>(__t); }
2839 } // namespace __detail
2841 template<input_range _Vp>
2842 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2843 class join_view : public view_interface<join_view<_Vp>>
2846 using _InnerRange = range_reference_t<_Vp>;
2848 template<bool _Const>
2849 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2851 template<bool _Const>
2852 using _Outer_iter = iterator_t<_Base<_Const>>;
2854 template<bool _Const>
2855 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2857 template<bool _Const>
2858 static constexpr bool _S_ref_is_glvalue
2859 = is_reference_v<range_reference_t<_Base<_Const>>>;
2861 template<bool _Const>
2865 template<bool _Const>
2866 requires _S_ref_is_glvalue<_Const>
2867 && forward_range<_Base<_Const>>
2868 && forward_range<range_reference_t<_Base<_Const>>>
2869 struct __iter_cat<_Const>
2872 static constexpr auto
2875 using _Outer_iter = join_view::_Outer_iter<_Const>;
2876 using _Inner_iter = join_view::_Inner_iter<_Const>;
2877 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2878 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2879 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2880 && derived_from<_InnerCat, bidirectional_iterator_tag>
2881 && common_range<range_reference_t<_Base<_Const>>>)
2882 return bidirectional_iterator_tag{};
2883 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2884 && derived_from<_InnerCat, forward_iterator_tag>)
2885 return forward_iterator_tag{};
2887 return input_iterator_tag{};
2890 using iterator_category = decltype(_S_iter_cat());
2893 template<bool _Const>
2896 template<bool _Const>
2897 struct _Iterator : __iter_cat<_Const>
2900 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2901 using _Base = join_view::_Base<_Const>;
2905 static constexpr bool _S_ref_is_glvalue
2906 = join_view::_S_ref_is_glvalue<_Const>;
2911 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2912 if constexpr (_S_ref_is_glvalue)
2915 return _M_parent->_M_inner._M_emplace_deref(__x);
2918 _Outer_iter& __outer = _M_get_outer();
2919 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2921 auto&& __inner = __update_inner(__outer);
2922 _M_inner = ranges::begin(__inner);
2923 if (_M_inner != ranges::end(__inner))
2927 if constexpr (_S_ref_is_glvalue)
2931 static constexpr auto
2934 if constexpr (_S_ref_is_glvalue
2935 && bidirectional_range<_Base>
2936 && bidirectional_range<range_reference_t<_Base>>
2937 && common_range<range_reference_t<_Base>>)
2938 return bidirectional_iterator_tag{};
2939 else if constexpr (_S_ref_is_glvalue
2940 && forward_range<_Base>
2941 && forward_range<range_reference_t<_Base>>)
2942 return forward_iterator_tag{};
2944 return input_iterator_tag{};
2947 using _Outer_iter = join_view::_Outer_iter<_Const>;
2948 using _Inner_iter = join_view::_Inner_iter<_Const>;
2950 constexpr _Outer_iter&
2953 if constexpr (forward_range<_Base>)
2956 return *_M_parent->_M_outer;
2959 constexpr const _Outer_iter&
2960 _M_get_outer() const
2962 if constexpr (forward_range<_Base>)
2965 return *_M_parent->_M_outer;
2969 _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base>
2970 : _M_outer(std::move(__outer)), _M_parent(__parent)
2974 _Iterator(_Parent* __parent) requires (!forward_range<_Base>)
2975 : _M_parent(__parent)
2978 [[no_unique_address]]
2979 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer;
2980 optional<_Inner_iter> _M_inner;
2981 _Parent* _M_parent = nullptr;
2984 using iterator_concept = decltype(_S_iter_concept());
2985 // iterator_category defined in __join_view_iter_cat
2986 using value_type = range_value_t<range_reference_t<_Base>>;
2987 using difference_type
2988 = common_type_t<range_difference_t<_Base>,
2989 range_difference_t<range_reference_t<_Base>>>;
2991 _Iterator() = default;
2994 _Iterator(_Iterator<!_Const> __i)
2996 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2997 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2998 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
2999 _M_parent(__i._M_parent)
3002 constexpr decltype(auto)
3004 { return **_M_inner; }
3006 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3007 // 3500. join_view::iterator::operator->() is bogus
3008 constexpr _Inner_iter
3010 requires __detail::__has_arrow<_Inner_iter>
3011 && copyable<_Inner_iter>
3012 { return *_M_inner; }
3014 constexpr _Iterator&
3017 auto&& __inner_range = [this] () -> auto&& {
3018 if constexpr (_S_ref_is_glvalue)
3019 return *_M_get_outer();
3021 return *_M_parent->_M_inner;
3023 if (++*_M_inner == ranges::end(__inner_range))
3037 requires _S_ref_is_glvalue && forward_range<_Base>
3038 && forward_range<range_reference_t<_Base>>
3045 constexpr _Iterator&
3047 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3048 && bidirectional_range<range_reference_t<_Base>>
3049 && common_range<range_reference_t<_Base>>
3051 if (_M_outer == ranges::end(_M_parent->_M_base))
3052 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3053 while (*_M_inner == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3054 *_M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3061 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3062 && bidirectional_range<range_reference_t<_Base>>
3063 && common_range<range_reference_t<_Base>>
3070 friend constexpr bool
3071 operator==(const _Iterator& __x, const _Iterator& __y)
3072 requires _S_ref_is_glvalue
3073 && forward_range<_Base>
3074 && equality_comparable<_Inner_iter>
3076 return (__x._M_outer == __y._M_outer
3077 && __x._M_inner == __y._M_inner);
3080 friend constexpr decltype(auto)
3081 iter_move(const _Iterator& __i)
3082 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
3083 { return ranges::iter_move(*__i._M_inner); }
3085 friend constexpr void
3086 iter_swap(const _Iterator& __x, const _Iterator& __y)
3087 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
3088 requires indirectly_swappable<_Inner_iter>
3089 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
3091 friend _Iterator<!_Const>;
3092 template<bool> friend struct _Sentinel;
3095 template<bool _Const>
3099 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3100 using _Base = join_view::_Base<_Const>;
3102 template<bool _Const2>
3104 __equal(const _Iterator<_Const2>& __i) const
3105 { return __i._M_get_outer() == _M_end; }
3107 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3110 _Sentinel() = default;
3113 _Sentinel(_Parent* __parent)
3114 : _M_end(ranges::end(__parent->_M_base))
3118 _Sentinel(_Sentinel<!_Const> __s)
3119 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3120 : _M_end(std::move(__s._M_end))
3123 template<bool _Const2>
3124 requires sentinel_for<sentinel_t<_Base>,
3125 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3126 friend constexpr bool
3127 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3128 { return __y.__equal(__x); }
3130 friend _Sentinel<!_Const>;
3133 _Vp _M_base = _Vp();
3134 [[no_unique_address]]
3135 __detail::__maybe_present_t<!forward_range<_Vp>,
3136 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3137 [[no_unique_address]]
3138 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3141 join_view() requires default_initializable<_Vp> = default;
3144 join_view(_Vp __base)
3145 : _M_base(std::move(__base))
3149 base() const& requires copy_constructible<_Vp>
3154 { return std::move(_M_base); }
3159 if constexpr (forward_range<_Vp>)
3161 constexpr bool __use_const
3162 = (__detail::__simple_view<_Vp>
3163 && is_reference_v<range_reference_t<_Vp>>);
3164 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3168 _M_outer = ranges::begin(_M_base);
3169 return _Iterator<false>{this};
3175 requires forward_range<const _Vp>
3176 && is_reference_v<range_reference_t<const _Vp>>
3177 && input_range<range_reference_t<const _Vp>>
3179 return _Iterator<true>{this, ranges::begin(_M_base)};
3185 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3186 && forward_range<_InnerRange>
3187 && common_range<_Vp> && common_range<_InnerRange>)
3188 return _Iterator<__detail::__simple_view<_Vp>>{this,
3189 ranges::end(_M_base)};
3191 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3196 requires forward_range<const _Vp>
3197 && is_reference_v<range_reference_t<const _Vp>>
3198 && input_range<range_reference_t<const _Vp>>
3200 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3201 && forward_range<range_reference_t<const _Vp>>
3202 && common_range<const _Vp>
3203 && common_range<range_reference_t<const _Vp>>)
3204 return _Iterator<true>{this, ranges::end(_M_base)};
3206 return _Sentinel<true>{this};
3210 template<typename _Range>
3211 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3217 template<typename _Range>
3218 concept __can_join_view
3219 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3220 } // namespace __detail
3222 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3224 template<viewable_range _Range>
3225 requires __detail::__can_join_view<_Range>
3227 operator() [[nodiscard]] (_Range&& __r) const
3229 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3230 // 3474. Nesting join_views is broken because of CTAD
3231 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3234 static constexpr bool _S_has_simple_call_op = true;
3237 inline constexpr _Join join;
3238 } // namespace views
3243 struct __require_constant;
3245 template<typename _Range>
3246 concept __tiny_range = sized_range<_Range>
3248 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3249 && (remove_reference_t<_Range>::size() <= 1);
3251 template<typename _Base>
3252 struct __lazy_split_view_outer_iter_cat
3255 template<forward_range _Base>
3256 struct __lazy_split_view_outer_iter_cat<_Base>
3257 { using iterator_category = input_iterator_tag; };
3259 template<typename _Base>
3260 struct __lazy_split_view_inner_iter_cat
3263 template<forward_range _Base>
3264 struct __lazy_split_view_inner_iter_cat<_Base>
3267 static constexpr auto
3270 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3271 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3272 return forward_iterator_tag{};
3277 using iterator_category = decltype(_S_iter_cat());
3281 template<input_range _Vp, forward_range _Pattern>
3282 requires view<_Vp> && view<_Pattern>
3283 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3285 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3286 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3289 template<bool _Const>
3290 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3292 template<bool _Const>
3295 template<bool _Const>
3297 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3300 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3301 using _Base = lazy_split_view::_Base<_Const>;
3305 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3307 // [range.lazy.split.outer] p1
3308 // Many of the following specifications refer to the notional member
3309 // current of outer-iterator. current is equivalent to current_ if
3310 // V models forward_range, and parent_->current_ otherwise.
3312 __current() noexcept
3314 if constexpr (forward_range<_Vp>)
3317 return *_M_parent->_M_current;
3321 __current() const noexcept
3323 if constexpr (forward_range<_Vp>)
3326 return *_M_parent->_M_current;
3329 _Parent* _M_parent = nullptr;
3331 [[no_unique_address]]
3332 __detail::__maybe_present_t<forward_range<_Vp>,
3333 iterator_t<_Base>> _M_current;
3334 bool _M_trailing_empty = false;
3337 using iterator_concept = __conditional_t<forward_range<_Base>,
3338 forward_iterator_tag,
3339 input_iterator_tag>;
3340 // iterator_category defined in __lazy_split_view_outer_iter_cat
3341 using difference_type = range_difference_t<_Base>;
3343 struct value_type : view_interface<value_type>
3346 _OuterIter _M_i = _OuterIter();
3349 value_type() = default;
3352 value_type(_OuterIter __i)
3353 : _M_i(std::move(__i))
3356 constexpr _InnerIter<_Const>
3358 { return _InnerIter<_Const>{_M_i}; }
3360 constexpr default_sentinel_t
3361 end() const noexcept
3362 { return default_sentinel; }
3365 _OuterIter() = default;
3368 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3369 : _M_parent(__parent)
3373 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3374 requires forward_range<_Base>
3375 : _M_parent(__parent),
3376 _M_current(std::move(__current))
3380 _OuterIter(_OuterIter<!_Const> __i)
3382 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3383 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3384 _M_trailing_empty(__i._M_trailing_empty)
3387 constexpr value_type
3389 { return value_type{*this}; }
3391 constexpr _OuterIter&
3394 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3395 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3396 const auto __end = ranges::end(_M_parent->_M_base);
3397 if (__current() == __end)
3399 _M_trailing_empty = false;
3402 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3403 if (__pbegin == __pend)
3405 else if constexpr (__detail::__tiny_range<_Pattern>)
3407 __current() = ranges::find(std::move(__current()), __end,
3409 if (__current() != __end)
3412 if (__current() == __end)
3413 _M_trailing_empty = true;
3420 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3424 if (__current() == __end)
3425 _M_trailing_empty = true;
3428 } while (++__current() != __end);
3432 constexpr decltype(auto)
3435 if constexpr (forward_range<_Base>)
3445 friend constexpr bool
3446 operator==(const _OuterIter& __x, const _OuterIter& __y)
3447 requires forward_range<_Base>
3449 return __x._M_current == __y._M_current
3450 && __x._M_trailing_empty == __y._M_trailing_empty;
3453 friend constexpr bool
3454 operator==(const _OuterIter& __x, default_sentinel_t)
3455 { return __x.__at_end(); };
3457 friend _OuterIter<!_Const>;
3458 friend _InnerIter<_Const>;
3461 template<bool _Const>
3463 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3466 using _Base = lazy_split_view::_Base<_Const>;
3471 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3472 auto __end = ranges::end(_M_i._M_parent->_M_base);
3473 if constexpr (__detail::__tiny_range<_Pattern>)
3475 const auto& __cur = _M_i_current();
3478 if (__pcur == __pend)
3479 return _M_incremented;
3480 return *__cur == *__pcur;
3484 auto __cur = _M_i_current();
3487 if (__pcur == __pend)
3488 return _M_incremented;
3491 if (*__cur != *__pcur)
3493 if (++__pcur == __pend)
3495 } while (++__cur != __end);
3501 _M_i_current() noexcept
3502 { return _M_i.__current(); }
3505 _M_i_current() const noexcept
3506 { return _M_i.__current(); }
3508 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3509 bool _M_incremented = false;
3512 using iterator_concept
3513 = typename _OuterIter<_Const>::iterator_concept;
3514 // iterator_category defined in __lazy_split_view_inner_iter_cat
3515 using value_type = range_value_t<_Base>;
3516 using difference_type = range_difference_t<_Base>;
3518 _InnerIter() = default;
3521 _InnerIter(_OuterIter<_Const> __i)
3522 : _M_i(std::move(__i))
3525 constexpr const iterator_t<_Base>&
3526 base() const& noexcept
3527 { return _M_i_current(); }
3529 constexpr iterator_t<_Base>
3530 base() && requires forward_range<_Vp>
3531 { return std::move(_M_i_current()); }
3533 constexpr decltype(auto)
3535 { return *_M_i_current(); }
3537 constexpr _InnerIter&
3540 _M_incremented = true;
3541 if constexpr (!forward_range<_Base>)
3542 if constexpr (_Pattern::size() == 0)
3548 constexpr decltype(auto)
3551 if constexpr (forward_range<_Base>)
3561 friend constexpr bool
3562 operator==(const _InnerIter& __x, const _InnerIter& __y)
3563 requires forward_range<_Base>
3564 { return __x._M_i == __y._M_i; }
3566 friend constexpr bool
3567 operator==(const _InnerIter& __x, default_sentinel_t)
3568 { return __x.__at_end(); }
3570 friend constexpr decltype(auto)
3571 iter_move(const _InnerIter& __i)
3572 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3573 { return ranges::iter_move(__i._M_i_current()); }
3575 friend constexpr void
3576 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3577 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3578 __y._M_i_current())))
3579 requires indirectly_swappable<iterator_t<_Base>>
3580 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3583 _Vp _M_base = _Vp();
3584 _Pattern _M_pattern = _Pattern();
3585 [[no_unique_address]]
3586 __detail::__maybe_present_t<!forward_range<_Vp>,
3587 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3591 lazy_split_view() requires (default_initializable<_Vp>
3592 && default_initializable<_Pattern>)
3596 lazy_split_view(_Vp __base, _Pattern __pattern)
3597 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3600 template<input_range _Range>
3601 requires constructible_from<_Vp, views::all_t<_Range>>
3602 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3604 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3605 : _M_base(views::all(std::forward<_Range>(__r))),
3606 _M_pattern(views::single(std::move(__e)))
3610 base() const& requires copy_constructible<_Vp>
3615 { return std::move(_M_base); }
3620 if constexpr (forward_range<_Vp>)
3622 constexpr bool __simple
3623 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3624 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3628 _M_current = ranges::begin(_M_base);
3629 return _OuterIter<false>{this};
3634 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3636 return _OuterIter<true>{this, ranges::begin(_M_base)};
3640 end() requires forward_range<_Vp> && common_range<_Vp>
3642 constexpr bool __simple
3643 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3644 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3650 if constexpr (forward_range<_Vp>
3651 && forward_range<const _Vp>
3652 && common_range<const _Vp>)
3653 return _OuterIter<true>{this, ranges::end(_M_base)};
3655 return default_sentinel;
3659 template<typename _Range, typename _Pattern>
3660 lazy_split_view(_Range&&, _Pattern&&)
3661 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3663 template<input_range _Range>
3664 lazy_split_view(_Range&&, range_value_t<_Range>)
3665 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3671 template<typename _Range, typename _Pattern>
3672 concept __can_lazy_split_view
3673 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3674 } // namespace __detail
3676 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3678 template<viewable_range _Range, typename _Pattern>
3679 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3681 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3683 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3686 using _RangeAdaptor<_LazySplit>::operator();
3687 static constexpr int _S_arity = 2;
3688 // The pattern argument of views::lazy_split is not always simple -- it can be
3689 // a non-view range, the value category of which affects whether the call
3690 // is well-formed. But a scalar or a view pattern argument is surely
3692 template<typename _Pattern>
3693 static constexpr bool _S_has_simple_extra_args
3694 = is_scalar_v<_Pattern> || (view<_Pattern>
3695 && copy_constructible<_Pattern>);
3698 inline constexpr _LazySplit lazy_split;
3699 } // namespace views
3701 template<forward_range _Vp, forward_range _Pattern>
3702 requires view<_Vp> && view<_Pattern>
3703 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3705 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3708 _Vp _M_base = _Vp();
3709 _Pattern _M_pattern = _Pattern();
3710 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3716 split_view() requires (default_initializable<_Vp>
3717 && default_initializable<_Pattern>)
3721 split_view(_Vp __base, _Pattern __pattern)
3722 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3725 template<forward_range _Range>
3726 requires constructible_from<_Vp, views::all_t<_Range>>
3727 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3729 split_view(_Range&& __r, range_value_t<_Range> __e)
3730 : _M_base(views::all(std::forward<_Range>(__r))),
3731 _M_pattern(views::single(std::move(__e)))
3735 base() const& requires copy_constructible<_Vp>
3740 { return std::move(_M_base); }
3745 if (!_M_cached_begin)
3746 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3747 return {this, ranges::begin(_M_base), *_M_cached_begin};
3753 if constexpr (common_range<_Vp>)
3754 return _Iterator{this, ranges::end(_M_base), {}};
3756 return _Sentinel{this};
3759 constexpr subrange<iterator_t<_Vp>>
3760 _M_find_next(iterator_t<_Vp> __it)
3762 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3763 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3775 split_view* _M_parent = nullptr;
3776 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3777 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3778 bool _M_trailing_empty = false;
3780 friend struct _Sentinel;
3783 using iterator_concept = forward_iterator_tag;
3784 using iterator_category = input_iterator_tag;
3785 using value_type = subrange<iterator_t<_Vp>>;
3786 using difference_type = range_difference_t<_Vp>;
3788 _Iterator() = default;
3791 _Iterator(split_view* __parent,
3792 iterator_t<_Vp> __current,
3793 subrange<iterator_t<_Vp>> __next)
3794 : _M_parent(__parent),
3795 _M_cur(std::move(__current)),
3796 _M_next(std::move(__next))
3799 constexpr iterator_t<_Vp>
3803 constexpr value_type
3805 { return {_M_cur, _M_next.begin()}; }
3807 constexpr _Iterator&
3810 _M_cur = _M_next.begin();
3811 if (_M_cur != ranges::end(_M_parent->_M_base))
3813 _M_cur = _M_next.end();
3814 if (_M_cur == ranges::end(_M_parent->_M_base))
3816 _M_trailing_empty = true;
3817 _M_next = {_M_cur, _M_cur};
3820 _M_next = _M_parent->_M_find_next(_M_cur);
3823 _M_trailing_empty = false;
3835 friend constexpr bool
3836 operator==(const _Iterator& __x, const _Iterator& __y)
3838 return __x._M_cur == __y._M_cur
3839 && __x._M_trailing_empty == __y._M_trailing_empty;
3846 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3849 _M_equal(const _Iterator& __x) const
3850 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3853 _Sentinel() = default;
3856 _Sentinel(split_view* __parent)
3857 : _M_end(ranges::end(__parent->_M_base))
3860 friend constexpr bool
3861 operator==(const _Iterator& __x, const _Sentinel& __y)
3862 { return __y._M_equal(__x); }
3866 template<typename _Range, typename _Pattern>
3867 split_view(_Range&&, _Pattern&&)
3868 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3870 template<forward_range _Range>
3871 split_view(_Range&&, range_value_t<_Range>)
3872 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3878 template<typename _Range, typename _Pattern>
3879 concept __can_split_view
3880 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3881 } // namespace __detail
3883 struct _Split : __adaptor::_RangeAdaptor<_Split>
3885 template<viewable_range _Range, typename _Pattern>
3886 requires __detail::__can_split_view<_Range, _Pattern>
3888 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3890 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3893 using _RangeAdaptor<_Split>::operator();
3894 static constexpr int _S_arity = 2;
3895 template<typename _Pattern>
3896 static constexpr bool _S_has_simple_extra_args
3897 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3900 inline constexpr _Split split;
3901 } // namespace views
3907 template<input_or_output_iterator _Iter>
3909 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3911 if constexpr (contiguous_iterator<_Iter>)
3912 return span(std::__to_address(__i), __n);
3913 else if constexpr (random_access_iterator<_Iter>)
3914 return subrange(__i, __i + __n);
3916 return subrange(counted_iterator(std::move(__i), __n),
3921 inline constexpr _Counted counted{};
3922 } // namespace views
3925 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3926 class common_view : public view_interface<common_view<_Vp>>
3929 _Vp _M_base = _Vp();
3932 common_view() requires default_initializable<_Vp> = default;
3935 common_view(_Vp __r)
3936 : _M_base(std::move(__r))
3940 base() const& requires copy_constructible<_Vp>
3945 { return std::move(_M_base); }
3950 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3951 return ranges::begin(_M_base);
3953 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3954 (ranges::begin(_M_base));
3958 begin() const requires range<const _Vp>
3960 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3961 return ranges::begin(_M_base);
3963 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3964 (ranges::begin(_M_base));
3970 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3971 return ranges::begin(_M_base) + ranges::size(_M_base);
3973 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3974 (ranges::end(_M_base));
3978 end() const requires range<const _Vp>
3980 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3981 return ranges::begin(_M_base) + ranges::size(_M_base);
3983 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3984 (ranges::end(_M_base));
3988 size() requires sized_range<_Vp>
3989 { return ranges::size(_M_base); }
3992 size() const requires sized_range<const _Vp>
3993 { return ranges::size(_M_base); }
3996 template<typename _Range>
3997 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3999 template<typename _Tp>
4000 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4001 = enable_borrowed_range<_Tp>;
4007 template<typename _Range>
4008 concept __already_common = common_range<_Range>
4009 && requires { views::all(std::declval<_Range>()); };
4011 template<typename _Range>
4012 concept __can_common_view
4013 = requires { common_view{std::declval<_Range>()}; };
4014 } // namespace __detail
4016 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4018 template<viewable_range _Range>
4019 requires __detail::__already_common<_Range>
4020 || __detail::__can_common_view<_Range>
4022 operator() [[nodiscard]] (_Range&& __r) const
4024 if constexpr (__detail::__already_common<_Range>)
4025 return views::all(std::forward<_Range>(__r));
4027 return common_view{std::forward<_Range>(__r)};
4030 static constexpr bool _S_has_simple_call_op = true;
4033 inline constexpr _Common common;
4034 } // namespace views
4037 requires bidirectional_range<_Vp>
4038 class reverse_view : public view_interface<reverse_view<_Vp>>
4041 static constexpr bool _S_needs_cached_begin
4042 = !common_range<_Vp> && !(random_access_range<_Vp>
4043 && sized_sentinel_for<sentinel_t<_Vp>,
4046 _Vp _M_base = _Vp();
4047 [[no_unique_address]]
4048 __detail::__maybe_present_t<_S_needs_cached_begin,
4049 __detail::_CachedPosition<_Vp>>
4053 reverse_view() requires default_initializable<_Vp> = default;
4056 reverse_view(_Vp __r)
4057 : _M_base(std::move(__r))
4061 base() const& requires copy_constructible<_Vp>
4066 { return std::move(_M_base); }
4068 constexpr reverse_iterator<iterator_t<_Vp>>
4071 if constexpr (_S_needs_cached_begin)
4072 if (_M_cached_begin._M_has_value())
4073 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
4075 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4076 if constexpr (_S_needs_cached_begin)
4077 _M_cached_begin._M_set(_M_base, __it);
4078 return std::make_reverse_iterator(std::move(__it));
4082 begin() requires common_range<_Vp>
4083 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4086 begin() const requires common_range<const _Vp>
4087 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4089 constexpr reverse_iterator<iterator_t<_Vp>>
4091 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4094 end() const requires common_range<const _Vp>
4095 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4098 size() requires sized_range<_Vp>
4099 { return ranges::size(_M_base); }
4102 size() const requires sized_range<const _Vp>
4103 { return ranges::size(_M_base); }
4106 template<typename _Range>
4107 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4109 template<typename _Tp>
4110 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4111 = enable_borrowed_range<_Tp>;
4118 inline constexpr bool __is_reversible_subrange = false;
4120 template<typename _Iter, subrange_kind _Kind>
4121 inline constexpr bool
4122 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4123 reverse_iterator<_Iter>,
4127 inline constexpr bool __is_reverse_view = false;
4129 template<typename _Vp>
4130 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
4132 template<typename _Range>
4133 concept __can_reverse_view
4134 = requires { reverse_view{std::declval<_Range>()}; };
4135 } // namespace __detail
4137 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4139 template<viewable_range _Range>
4140 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4141 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4142 || __detail::__can_reverse_view<_Range>
4144 operator() [[nodiscard]] (_Range&& __r) const
4146 using _Tp = remove_cvref_t<_Range>;
4147 if constexpr (__detail::__is_reverse_view<_Tp>)
4148 return std::forward<_Range>(__r).base();
4149 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4151 using _Iter = decltype(ranges::begin(__r).base());
4152 if constexpr (sized_range<_Tp>)
4153 return subrange<_Iter, _Iter, subrange_kind::sized>
4154 {__r.end().base(), __r.begin().base(), __r.size()};
4156 return subrange<_Iter, _Iter, subrange_kind::unsized>
4157 {__r.end().base(), __r.begin().base()};
4160 return reverse_view{std::forward<_Range>(__r)};
4163 static constexpr bool _S_has_simple_call_op = true;
4166 inline constexpr _Reverse reverse;
4167 } // namespace views
4171#if __cpp_lib_tuple_like // >= C++23
4172 template<typename _Tp, size_t _Nm>
4173 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4175 template<typename _Tp, size_t _Nm>
4176 concept __has_tuple_element = requires(_Tp __t)
4178 typename tuple_size<_Tp>::type;
4179 requires _Nm < tuple_size_v<_Tp>;
4180 typename tuple_element_t<_Nm, _Tp>;
4181 { std::get<_Nm>(__t) }
4182 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4186 template<typename _Tp, size_t _Nm>
4187 concept __returnable_element
4188 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4191 template<input_range _Vp, size_t _Nm>
4193 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4194 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4196 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4197 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4200 elements_view() requires default_initializable<_Vp> = default;
4203 elements_view(_Vp __base)
4204 : _M_base(std::move(__base))
4208 base() const& requires copy_constructible<_Vp>
4213 { return std::move(_M_base); }
4216 begin() requires (!__detail::__simple_view<_Vp>)
4217 { return _Iterator<false>(ranges::begin(_M_base)); }
4220 begin() const requires range<const _Vp>
4221 { return _Iterator<true>(ranges::begin(_M_base)); }
4224 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4225 { return _Sentinel<false>{ranges::end(_M_base)}; }
4228 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4229 { return _Iterator<false>{ranges::end(_M_base)}; }
4232 end() const requires range<const _Vp>
4233 { return _Sentinel<true>{ranges::end(_M_base)}; }
4236 end() const requires common_range<const _Vp>
4237 { return _Iterator<true>{ranges::end(_M_base)}; }
4240 size() requires sized_range<_Vp>
4241 { return ranges::size(_M_base); }
4244 size() const requires sized_range<const _Vp>
4245 { return ranges::size(_M_base); }
4248 template<bool _Const>
4249 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4251 template<bool _Const>
4255 template<bool _Const>
4256 requires forward_range<_Base<_Const>>
4257 struct __iter_cat<_Const>
4260 static auto _S_iter_cat()
4262 using _Base = elements_view::_Base<_Const>;
4263 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4264 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4265 if constexpr (!is_lvalue_reference_v<_Res>)
4266 return input_iterator_tag{};
4267 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4268 return random_access_iterator_tag{};
4273 using iterator_category = decltype(_S_iter_cat());
4276 template<bool _Const>
4279 template<bool _Const>
4280 struct _Iterator : __iter_cat<_Const>
4283 using _Base = elements_view::_Base<_Const>;
4285 iterator_t<_Base> _M_current = iterator_t<_Base>();
4287 static constexpr decltype(auto)
4288 _S_get_element(const iterator_t<_Base>& __i)
4290 if constexpr (is_reference_v<range_reference_t<_Base>>)
4291 return std::get<_Nm>(*__i);
4294 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4295 return static_cast<_Et>(std::get<_Nm>(*__i));
4302 if constexpr (random_access_range<_Base>)
4303 return random_access_iterator_tag{};
4304 else if constexpr (bidirectional_range<_Base>)
4305 return bidirectional_iterator_tag{};
4306 else if constexpr (forward_range<_Base>)
4307 return forward_iterator_tag{};
4309 return input_iterator_tag{};
4312 friend _Iterator<!_Const>;
4315 using iterator_concept = decltype(_S_iter_concept());
4316 // iterator_category defined in elements_view::__iter_cat
4318 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4319 using difference_type = range_difference_t<_Base>;
4321 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4324 _Iterator(iterator_t<_Base> __current)
4325 : _M_current(std::move(__current))
4329 _Iterator(_Iterator<!_Const> __i)
4330 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4331 : _M_current(std::move(__i._M_current))
4334 constexpr const iterator_t<_Base>&
4335 base() const& noexcept
4336 { return _M_current; }
4338 constexpr iterator_t<_Base>
4340 { return std::move(_M_current); }
4342 constexpr decltype(auto)
4344 { return _S_get_element(_M_current); }
4346 constexpr _Iterator&
4358 operator++(int) requires forward_range<_Base>
4365 constexpr _Iterator&
4366 operator--() requires bidirectional_range<_Base>
4373 operator--(int) requires bidirectional_range<_Base>
4380 constexpr _Iterator&
4381 operator+=(difference_type __n)
4382 requires random_access_range<_Base>
4388 constexpr _Iterator&
4389 operator-=(difference_type __n)
4390 requires random_access_range<_Base>
4396 constexpr decltype(auto)
4397 operator[](difference_type __n) const
4398 requires random_access_range<_Base>
4399 { return _S_get_element(_M_current + __n); }
4401 friend constexpr bool
4402 operator==(const _Iterator& __x, const _Iterator& __y)
4403 requires equality_comparable<iterator_t<_Base>>
4404 { return __x._M_current == __y._M_current; }
4406 friend constexpr bool
4407 operator<(const _Iterator& __x, const _Iterator& __y)
4408 requires random_access_range<_Base>
4409 { return __x._M_current < __y._M_current; }
4411 friend constexpr bool
4412 operator>(const _Iterator& __x, const _Iterator& __y)
4413 requires random_access_range<_Base>
4414 { return __y._M_current < __x._M_current; }
4416 friend constexpr bool
4417 operator<=(const _Iterator& __x, const _Iterator& __y)
4418 requires random_access_range<_Base>
4419 { return !(__y._M_current > __x._M_current); }
4421 friend constexpr bool
4422 operator>=(const _Iterator& __x, const _Iterator& __y)
4423 requires random_access_range<_Base>
4424 { return !(__x._M_current > __y._M_current); }
4426#ifdef __cpp_lib_three_way_comparison
4427 friend constexpr auto
4428 operator<=>(const _Iterator& __x, const _Iterator& __y)
4429 requires random_access_range<_Base>
4430 && three_way_comparable<iterator_t<_Base>>
4431 { return __x._M_current <=> __y._M_current; }
4434 friend constexpr _Iterator
4435 operator+(const _Iterator& __x, difference_type __y)
4436 requires random_access_range<_Base>
4437 { return _Iterator{__x} += __y; }
4439 friend constexpr _Iterator
4440 operator+(difference_type __x, const _Iterator& __y)
4441 requires random_access_range<_Base>
4442 { return __y + __x; }
4444 friend constexpr _Iterator
4445 operator-(const _Iterator& __x, difference_type __y)
4446 requires random_access_range<_Base>
4447 { return _Iterator{__x} -= __y; }
4449 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4450 // 3483. transform_view::iterator's difference is overconstrained
4451 friend constexpr difference_type
4452 operator-(const _Iterator& __x, const _Iterator& __y)
4453 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4454 { return __x._M_current - __y._M_current; }
4456 template <bool> friend struct _Sentinel;
4459 template<bool _Const>
4463 template<bool _Const2>
4465 _M_equal(const _Iterator<_Const2>& __x) const
4466 { return __x._M_current == _M_end; }
4468 template<bool _Const2>
4470 _M_distance_from(const _Iterator<_Const2>& __i) const
4471 { return _M_end - __i._M_current; }
4473 using _Base = elements_view::_Base<_Const>;
4474 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4477 _Sentinel() = default;
4480 _Sentinel(sentinel_t<_Base> __end)
4481 : _M_end(std::move(__end))
4485 _Sentinel(_Sentinel<!_Const> __other)
4487 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4488 : _M_end(std::move(__other._M_end))
4491 constexpr sentinel_t<_Base>
4495 template<bool _Const2>
4496 requires sentinel_for<sentinel_t<_Base>,
4497 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4498 friend constexpr bool
4499 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4500 { return __y._M_equal(__x); }
4502 template<bool _Const2,
4503 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4504 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4505 friend constexpr range_difference_t<_Base2>
4506 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4507 { return -__y._M_distance_from(__x); }
4509 template<bool _Const2,
4510 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4511 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4512 friend constexpr range_difference_t<_Base2>
4513 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4514 { return __x._M_distance_from(__y); }
4516 friend _Sentinel<!_Const>;
4519 _Vp _M_base = _Vp();
4522 template<typename _Tp, size_t _Nm>
4523 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4524 = enable_borrowed_range<_Tp>;
4526 template<typename _Range>
4527 using keys_view = elements_view<views::all_t<_Range>, 0>;
4529 template<typename _Range>
4530 using values_view = elements_view<views::all_t<_Range>, 1>;
4536 template<size_t _Nm, typename _Range>
4537 concept __can_elements_view
4538 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4539 } // namespace __detail
4541 template<size_t _Nm>
4542 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4544 template<viewable_range _Range>
4545 requires __detail::__can_elements_view<_Nm, _Range>
4547 operator() [[nodiscard]] (_Range&& __r) const
4549 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4552 static constexpr bool _S_has_simple_call_op = true;
4555 template<size_t _Nm>
4556 inline constexpr _Elements<_Nm> elements;
4557 inline constexpr auto keys = elements<0>;
4558 inline constexpr auto values = elements<1>;
4559 } // namespace views
4561#ifdef __cpp_lib_ranges_zip // C++ >= 23
4564 template<typename... _Rs>
4565 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4566 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4567 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4569 template<typename _Fp, typename _Tuple>
4571 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4573 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4574 return tuple<invoke_result_t<_Fp&, _Ts>...>
4575 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4576 }, std::forward<_Tuple>(__tuple));
4579 template<typename _Fp, typename _Tuple>
4581 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4583 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4584 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4585 }, std::forward<_Tuple>(__tuple));
4587 } // namespace __detail
4589 template<input_range... _Vs>
4590 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4591 class zip_view : public view_interface<zip_view<_Vs...>>
4593 tuple<_Vs...> _M_views;
4595 template<bool> class _Iterator;
4596 template<bool> class _Sentinel;
4599 zip_view() = default;
4602 zip_view(_Vs... __views)
4603 : _M_views(std::move(__views)...)
4607 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4608 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4611 begin() const requires (range<const _Vs> && ...)
4612 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4615 end() requires (!(__detail::__simple_view<_Vs> && ...))
4617 if constexpr (!__detail::__zip_is_common<_Vs...>)
4618 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4619 else if constexpr ((random_access_range<_Vs> && ...))
4620 return begin() + iter_difference_t<_Iterator<false>>(size());
4622 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4626 end() const requires (range<const _Vs> && ...)
4628 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4629 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4630 else if constexpr ((random_access_range<const _Vs> && ...))
4631 return begin() + iter_difference_t<_Iterator<true>>(size());
4633 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4637 size() requires (sized_range<_Vs> && ...)
4639 return std::apply([](auto... sizes) {
4640 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4641 return ranges::min({_CT(sizes)...});
4642 }, __detail::__tuple_transform(ranges::size, _M_views));
4646 size() const requires (sized_range<const _Vs> && ...)
4648 return std::apply([](auto... sizes) {
4649 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4650 return ranges::min({_CT(sizes)...});
4651 }, __detail::__tuple_transform(ranges::size, _M_views));
4655 template<typename... _Rs>
4656 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4658 template<typename... _Views>
4659 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4660 = (enable_borrowed_range<_Views> && ...);
4664 template<bool _Const, typename... _Vs>
4665 concept __all_random_access
4666 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4668 template<bool _Const, typename... _Vs>
4669 concept __all_bidirectional
4670 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4672 template<bool _Const, typename... _Vs>
4673 concept __all_forward
4674 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4676 template<bool _Const, typename... _Views>
4677 struct __zip_view_iter_cat
4680 template<bool _Const, typename... _Views>
4681 requires __all_forward<_Const, _Views...>
4682 struct __zip_view_iter_cat<_Const, _Views...>
4683 { using iterator_category = input_iterator_tag; };
4684 } // namespace __detail
4686 template<input_range... _Vs>
4687 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4688 template<bool _Const>
4689 class zip_view<_Vs...>::_Iterator
4690 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4692#ifdef __clang__ // LLVM-61763 workaround
4695 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4698 _Iterator(decltype(_M_current) __current)
4699 : _M_current(std::move(__current))
4705 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4706 return random_access_iterator_tag{};
4707 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4708 return bidirectional_iterator_tag{};
4709 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4710 return forward_iterator_tag{};
4712 return input_iterator_tag{};
4715#ifndef __clang__ // LLVM-61763 workaround
4716 template<move_constructible _Fp, input_range... _Ws>
4717 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4718 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4719 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4720 friend class zip_transform_view;
4724 // iterator_category defined in __zip_view_iter_cat
4725 using iterator_concept = decltype(_S_iter_concept());
4727 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4728 using difference_type
4729 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4731 _Iterator() = default;
4734 _Iterator(_Iterator<!_Const> __i)
4736 && (convertible_to<iterator_t<_Vs>,
4737 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4738 : _M_current(std::move(__i._M_current))
4744 auto __f = [](auto& __i) -> decltype(auto) {
4747 return __detail::__tuple_transform(__f, _M_current);
4750 constexpr _Iterator&
4753 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4763 requires __detail::__all_forward<_Const, _Vs...>
4770 constexpr _Iterator&
4772 requires __detail::__all_bidirectional<_Const, _Vs...>
4774 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4780 requires __detail::__all_bidirectional<_Const, _Vs...>
4787 constexpr _Iterator&
4788 operator+=(difference_type __x)
4789 requires __detail::__all_random_access<_Const, _Vs...>
4791 auto __f = [&]<typename _It>(_It& __i) {
4792 __i += iter_difference_t<_It>(__x);
4794 __detail::__tuple_for_each(__f, _M_current);
4798 constexpr _Iterator&
4799 operator-=(difference_type __x)
4800 requires __detail::__all_random_access<_Const, _Vs...>
4802 auto __f = [&]<typename _It>(_It& __i) {
4803 __i -= iter_difference_t<_It>(__x);
4805 __detail::__tuple_for_each(__f, _M_current);
4810 operator[](difference_type __n) const
4811 requires __detail::__all_random_access<_Const, _Vs...>
4813 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4814 return __i[iter_difference_t<_It>(__n)];
4816 return __detail::__tuple_transform(__f, _M_current);
4819 friend constexpr bool
4820 operator==(const _Iterator& __x, const _Iterator& __y)
4821 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4823 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4824 return __x._M_current == __y._M_current;
4826 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4827 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4828 }(make_index_sequence<sizeof...(_Vs)>{});
4831 friend constexpr auto
4832 operator<=>(const _Iterator& __x, const _Iterator& __y)
4833 requires __detail::__all_random_access<_Const, _Vs...>
4834 { return __x._M_current <=> __y._M_current; }
4836 friend constexpr _Iterator
4837 operator+(const _Iterator& __i, difference_type __n)
4838 requires __detail::__all_random_access<_Const, _Vs...>
4845 friend constexpr _Iterator
4846 operator+(difference_type __n, const _Iterator& __i)
4847 requires __detail::__all_random_access<_Const, _Vs...>
4854 friend constexpr _Iterator
4855 operator-(const _Iterator& __i, difference_type __n)
4856 requires __detail::__all_random_access<_Const, _Vs...>
4863 friend constexpr difference_type
4864 operator-(const _Iterator& __x, const _Iterator& __y)
4865 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4866 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4868 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4869 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4870 - std::get<_Is>(__y._M_current))...},
4872 [](difference_type __i) {
4873 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4875 }(make_index_sequence<sizeof...(_Vs)>{});
4878 friend constexpr auto
4879 iter_move(const _Iterator& __i)
4880 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4882 friend constexpr void
4883 iter_swap(const _Iterator& __l, const _Iterator& __r)
4884 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4886 [&]<size_t... _Is>(index_sequence<_Is...>) {
4887 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4888 }(make_index_sequence<sizeof...(_Vs)>{});
4891 friend class zip_view;
4894 template<input_range... _Vs>
4895 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4896 template<bool _Const>
4897 class zip_view<_Vs...>::_Sentinel
4899 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4902 _Sentinel(decltype(_M_end) __end)
4906 friend class zip_view;
4909 _Sentinel() = default;
4912 _Sentinel(_Sentinel<!_Const> __i)
4914 && (convertible_to<sentinel_t<_Vs>,
4915 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4916 : _M_end(std::move(__i._M_end))
4919 template<bool _OtherConst>
4920 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4921 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4922 friend constexpr bool
4923 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4925 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4926 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4927 }(make_index_sequence<sizeof...(_Vs)>{});
4930 template<bool _OtherConst>
4931 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4932 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4933 friend constexpr auto
4934 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4937 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4938 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4939 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4942 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4944 }(make_index_sequence<sizeof...(_Vs)>{});
4947 template<bool _OtherConst>
4948 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4949 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4950 friend constexpr auto
4951 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4952 { return -(__x - __y); }
4959 template<typename... _Ts>
4960 concept __can_zip_view
4961 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4966 template<typename... _Ts>
4967 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4969 operator() [[nodiscard]] (_Ts&&... __ts) const
4971 if constexpr (sizeof...(_Ts) == 0)
4972 return views::empty<tuple<>>;
4974 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4978 inline constexpr _Zip zip;
4983 template<typename _Range, bool _Const>
4984 using __range_iter_cat
4985 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
4988 template<move_constructible _Fp, input_range... _Vs>
4989 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4990 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4991 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4992 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
4994 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
4995 zip_view<_Vs...> _M_zip;
4997 using _InnerView = zip_view<_Vs...>;
4999 template<bool _Const>
5000 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5002 template<bool _Const>
5003 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5005 template<bool _Const>
5006 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5008 template<bool _Const>
5012 template<bool _Const>
5013 requires forward_range<_Base<_Const>>
5014 struct __iter_cat<_Const>
5020 using __detail::__maybe_const_t;
5021 using __detail::__range_iter_cat;
5022 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5023 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5024 if constexpr (!is_lvalue_reference_v<_Res>)
5025 return input_iterator_tag{};
5026 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5027 random_access_iterator_tag> && ...))
5028 return random_access_iterator_tag{};
5029 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5030 bidirectional_iterator_tag> && ...))
5031 return bidirectional_iterator_tag{};
5032 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5033 forward_iterator_tag> && ...))
5034 return forward_iterator_tag{};
5036 return input_iterator_tag{};
5039 using iterator_category = decltype(_S_iter_cat());
5042 template<bool> class _Iterator;
5043 template<bool> class _Sentinel;
5046 zip_transform_view() = default;
5049 zip_transform_view(_Fp __fun, _Vs... __views)
5050 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5055 { return _Iterator<false>(*this, _M_zip.begin()); }
5059 requires range<const _InnerView>
5060 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5061 { return _Iterator<true>(*this, _M_zip.begin()); }
5066 if constexpr (common_range<_InnerView>)
5067 return _Iterator<false>(*this, _M_zip.end());
5069 return _Sentinel<false>(_M_zip.end());
5074 requires range<const _InnerView>
5075 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5077 if constexpr (common_range<const _InnerView>)
5078 return _Iterator<true>(*this, _M_zip.end());
5080 return _Sentinel<true>(_M_zip.end());
5084 size() requires sized_range<_InnerView>
5085 { return _M_zip.size(); }
5088 size() const requires sized_range<const _InnerView>
5089 { return _M_zip.size(); }
5092 template<class _Fp, class... Rs>
5093 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5095 template<move_constructible _Fp, input_range... _Vs>
5096 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5097 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5098 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5099 template<bool _Const>
5100 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5102 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5104 _Parent* _M_parent = nullptr;
5105 __ziperator<_Const> _M_inner;
5108 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5109 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5112 friend class zip_transform_view;
5115 // iterator_category defined in zip_transform_view::__iter_cat
5116 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
5118 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5119 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5120 using difference_type = range_difference_t<_Base<_Const>>;
5122 _Iterator() = default;
5125 _Iterator(_Iterator<!_Const> __i)
5126 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5127 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5130 constexpr decltype(auto)
5133 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5134 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5135 }, _M_inner._M_current);
5138 constexpr _Iterator&
5150 operator++(int) requires forward_range<_Base<_Const>>
5157 constexpr _Iterator&
5158 operator--() requires bidirectional_range<_Base<_Const>>
5165 operator--(int) requires bidirectional_range<_Base<_Const>>
5172 constexpr _Iterator&
5173 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5179 constexpr _Iterator&
5180 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5186 constexpr decltype(auto)
5187 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5189 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5190 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5191 }, _M_inner._M_current);
5194 friend constexpr bool
5195 operator==(const _Iterator& __x, const _Iterator& __y)
5196 requires equality_comparable<__ziperator<_Const>>
5197 { return __x._M_inner == __y._M_inner; }
5199 friend constexpr auto
5200 operator<=>(const _Iterator& __x, const _Iterator& __y)
5201 requires random_access_range<_Base<_Const>>
5202 { return __x._M_inner <=> __y._M_inner; }
5204 friend constexpr _Iterator
5205 operator+(const _Iterator& __i, difference_type __n)
5206 requires random_access_range<_Base<_Const>>
5207 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5209 friend constexpr _Iterator
5210 operator+(difference_type __n, const _Iterator& __i)
5211 requires random_access_range<_Base<_Const>>
5212 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5214 friend constexpr _Iterator
5215 operator-(const _Iterator& __i, difference_type __n)
5216 requires random_access_range<_Base<_Const>>
5217 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5219 friend constexpr difference_type
5220 operator-(const _Iterator& __x, const _Iterator& __y)
5221 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5222 { return __x._M_inner - __y._M_inner; }
5225 template<move_constructible _Fp, input_range... _Vs>
5226 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5227 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5228 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5229 template<bool _Const>
5230 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5232 __zentinel<_Const> _M_inner;
5235 _Sentinel(__zentinel<_Const> __inner)
5239 friend class zip_transform_view;
5242 _Sentinel() = default;
5245 _Sentinel(_Sentinel<!_Const> __i)
5246 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5247 : _M_inner(std::move(__i._M_inner))
5250 template<bool _OtherConst>
5251 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5252 friend constexpr bool
5253 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5254 { return __x._M_inner == __y._M_inner; }
5256 template<bool _OtherConst>
5257 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5258 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5259 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5260 { return __x._M_inner - __y._M_inner; }
5262 template<bool _OtherConst>
5263 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5264 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5265 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5266 { return __x._M_inner - __y._M_inner; }
5273 template<typename _Fp, typename... _Ts>
5274 concept __can_zip_transform_view
5275 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5278 struct _ZipTransform
5280 template<typename _Fp, typename... _Ts>
5281 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5283 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5285 if constexpr (sizeof...(_Ts) == 0)
5286 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5288 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5292 inline constexpr _ZipTransform zip_transform;
5295 template<forward_range _Vp, size_t _Nm>
5296 requires view<_Vp> && (_Nm > 0)
5297 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5299 _Vp _M_base = _Vp();
5301 template<bool> class _Iterator;
5302 template<bool> class _Sentinel;
5304 struct __as_sentinel
5308 adjacent_view() requires default_initializable<_Vp> = default;
5311 adjacent_view(_Vp __base)
5312 : _M_base(std::move(__base))
5316 begin() requires (!__detail::__simple_view<_Vp>)
5317 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5320 begin() const requires range<const _Vp>
5321 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5324 end() requires (!__detail::__simple_view<_Vp>)
5326 if constexpr (common_range<_Vp>)
5327 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5329 return _Sentinel<false>(ranges::end(_M_base));
5333 end() const requires range<const _Vp>
5335 if constexpr (common_range<const _Vp>)
5336 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5338 return _Sentinel<true>(ranges::end(_M_base));
5342 size() requires sized_range<_Vp>
5344 using _ST = decltype(ranges::size(_M_base));
5345 using _CT = common_type_t<_ST, size_t>;
5346 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5347 __sz -= std::min<_CT>(__sz, _Nm - 1);
5348 return static_cast<_ST>(__sz);
5352 size() const requires sized_range<const _Vp>
5354 using _ST = decltype(ranges::size(_M_base));
5355 using _CT = common_type_t<_ST, size_t>;
5356 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5357 __sz -= std::min<_CT>(__sz, _Nm - 1);
5358 return static_cast<_ST>(__sz);
5362 template<typename _Vp, size_t _Nm>
5363 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5364 = enable_borrowed_range<_Vp>;
5368 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5369 template<typename _Tp, size_t _Nm>
5370 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5372 // For a functor F that is callable with N arguments, the expression
5373 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5374 template<typename _Fp, size_t _Nm>
5377 template<typename... _Ts>
5378 static invoke_result_t<_Fp, _Ts...>
5379 __tuple_apply(const tuple<_Ts...>&); // not defined
5381 template<typename _Tp>
5382 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5383 operator()(_Tp&&); // not defined
5387 template<forward_range _Vp, size_t _Nm>
5388 requires view<_Vp> && (_Nm > 0)
5389 template<bool _Const>
5390 class adjacent_view<_Vp, _Nm>::_Iterator
5392#ifdef __clang__ // LLVM-61763 workaround
5395 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5396 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5399 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5401 for (auto& __i : _M_current)
5404 ranges::advance(__first, 1, __last);
5409 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5411 if constexpr (!bidirectional_range<_Base>)
5412 for (auto& __it : _M_current)
5415 for (size_t __i = 0; __i < _Nm; ++__i)
5417 _M_current[_Nm - 1 - __i] = __last;
5418 ranges::advance(__last, -1, __first);
5425 if constexpr (random_access_range<_Base>)
5426 return random_access_iterator_tag{};
5427 else if constexpr (bidirectional_range<_Base>)
5428 return bidirectional_iterator_tag{};
5430 return forward_iterator_tag{};
5433 friend class adjacent_view;
5435#ifndef __clang__ // LLVM-61763 workaround
5436 template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
5437 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5438 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5439 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5440 range_reference_t<_Wp>>>
5441 friend class adjacent_transform_view;
5445 using iterator_category = input_iterator_tag;
5446 using iterator_concept = decltype(_S_iter_concept());
5447 using value_type = conditional_t<_Nm == 2,
5448 pair<range_value_t<_Base>, range_value_t<_Base>>,
5449 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5450 using difference_type = range_difference_t<_Base>;
5452 _Iterator() = default;
5455 _Iterator(_Iterator<!_Const> __i)
5456 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5458 for (size_t __j = 0; __j < _Nm; ++__j)
5459 _M_current[__j] = std::move(__i._M_current[__j]);
5465 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5466 return __detail::__tuple_transform(__f, _M_current);
5469 constexpr _Iterator&
5472 for (auto& __i : _M_current)
5485 constexpr _Iterator&
5486 operator--() requires bidirectional_range<_Base>
5488 for (auto& __i : _M_current)
5494 operator--(int) requires bidirectional_range<_Base>
5501 constexpr _Iterator&
5502 operator+=(difference_type __x)
5503 requires random_access_range<_Base>
5505 for (auto& __i : _M_current)
5510 constexpr _Iterator&
5511 operator-=(difference_type __x)
5512 requires random_access_range<_Base>
5514 for (auto& __i : _M_current)
5520 operator[](difference_type __n) const
5521 requires random_access_range<_Base>
5523 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5524 return __detail::__tuple_transform(__f, _M_current);
5527 friend constexpr bool
5528 operator==(const _Iterator& __x, const _Iterator& __y)
5529 { return __x._M_current.back() == __y._M_current.back(); }
5531 friend constexpr bool
5532 operator<(const _Iterator& __x, const _Iterator& __y)
5533 requires random_access_range<_Base>
5534 { return __x._M_current.back() < __y._M_current.back(); }
5536 friend constexpr bool
5537 operator>(const _Iterator& __x, const _Iterator& __y)
5538 requires random_access_range<_Base>
5539 { return __y < __x; }
5541 friend constexpr bool
5542 operator<=(const _Iterator& __x, const _Iterator& __y)
5543 requires random_access_range<_Base>
5544 { return !(__y < __x); }
5546 friend constexpr bool
5547 operator>=(const _Iterator& __x, const _Iterator& __y)
5548 requires random_access_range<_Base>
5549 { return !(__x < __y); }
5551 friend constexpr auto
5552 operator<=>(const _Iterator& __x, const _Iterator& __y)
5553 requires random_access_range<_Base>
5554 && three_way_comparable<iterator_t<_Base>>
5555 { return __x._M_current.back() <=> __y._M_current.back(); }
5557 friend constexpr _Iterator
5558 operator+(const _Iterator& __i, difference_type __n)
5559 requires random_access_range<_Base>
5566 friend constexpr _Iterator
5567 operator+(difference_type __n, const _Iterator& __i)
5568 requires random_access_range<_Base>
5575 friend constexpr _Iterator
5576 operator-(const _Iterator& __i, difference_type __n)
5577 requires random_access_range<_Base>
5584 friend constexpr difference_type
5585 operator-(const _Iterator& __x, const _Iterator& __y)
5586 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5587 { return __x._M_current.back() - __y._M_current.back(); }
5589 friend constexpr auto
5590 iter_move(const _Iterator& __i)
5591 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5593 friend constexpr void
5594 iter_swap(const _Iterator& __l, const _Iterator& __r)
5595 requires indirectly_swappable<iterator_t<_Base>>
5597 for (size_t __i = 0; __i < _Nm; __i++)
5598 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5602 template<forward_range _Vp, size_t _Nm>
5603 requires view<_Vp> && (_Nm > 0)
5604 template<bool _Const>
5605 class adjacent_view<_Vp, _Nm>::_Sentinel
5607 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5609 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5612 _Sentinel(sentinel_t<_Base> __end)
5616 friend class adjacent_view;
5619 _Sentinel() = default;
5622 _Sentinel(_Sentinel<!_Const> __i)
5623 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5624 : _M_end(std::move(__i._M_end))
5627 template<bool _OtherConst>
5628 requires sentinel_for<sentinel_t<_Base>,
5629 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5630 friend constexpr bool
5631 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5632 { return __x._M_current.back() == __y._M_end; }
5634 template<bool _OtherConst>
5635 requires sized_sentinel_for<sentinel_t<_Base>,
5636 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5637 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5638 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5639 { return __x._M_current.back() - __y._M_end; }
5641 template<bool _OtherConst>
5642 requires sized_sentinel_for<sentinel_t<_Base>,
5643 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5644 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5645 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5646 { return __y._M_end - __x._M_current.back(); }
5653 template<size_t _Nm, typename _Range>
5654 concept __can_adjacent_view
5655 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5658 template<size_t _Nm>
5659 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5661 template<viewable_range _Range>
5662 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5664 operator() [[nodiscard]] (_Range&& __r) const
5666 if constexpr (_Nm == 0)
5667 return views::empty<tuple<>>;
5669 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5673 template<size_t _Nm>
5674 inline constexpr _Adjacent<_Nm> adjacent;
5676 inline constexpr auto pairwise = adjacent<2>;
5679 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5680 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5681 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5682 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5683 range_reference_t<_Vp>>>
5684 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5686 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5687 adjacent_view<_Vp, _Nm> _M_inner;
5689 using _InnerView = adjacent_view<_Vp, _Nm>;
5691 template<bool _Const>
5692 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5694 template<bool _Const>
5695 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5697 template<bool> class _Iterator;
5698 template<bool> class _Sentinel;
5701 adjacent_transform_view() = default;
5704 adjacent_transform_view(_Vp __base, _Fp __fun)
5705 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5710 { return _Iterator<false>(*this, _M_inner.begin()); }
5714 requires range<const _InnerView>
5715 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5716 range_reference_t<const _Vp>>
5717 { return _Iterator<true>(*this, _M_inner.begin()); }
5722 if constexpr (common_range<_InnerView>)
5723 return _Iterator<false>(*this, _M_inner.end());
5725 return _Sentinel<false>(_M_inner.end());
5730 requires range<const _InnerView>
5731 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5732 range_reference_t<const _Vp>>
5734 if constexpr (common_range<const _InnerView>)
5735 return _Iterator<true>(*this, _M_inner.end());
5737 return _Sentinel<true>(_M_inner.end());
5741 size() requires sized_range<_InnerView>
5742 { return _M_inner.size(); }
5745 size() const requires sized_range<const _InnerView>
5746 { return _M_inner.size(); }
5749 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5750 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5751 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5752 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5753 range_reference_t<_Vp>>>
5754 template<bool _Const>
5755 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5757 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5758 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5760 _Parent* _M_parent = nullptr;
5761 _InnerIter<_Const> _M_inner;
5764 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5765 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5771 using __detail::__maybe_const_t;
5772 using __detail::__unarize;
5773 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5774 range_reference_t<_Base>>;
5775 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5776 if constexpr (!is_lvalue_reference_v<_Res>)
5777 return input_iterator_tag{};
5778 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5779 return random_access_iterator_tag{};
5780 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5781 return bidirectional_iterator_tag{};
5782 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5783 return forward_iterator_tag{};
5785 return input_iterator_tag{};
5788 friend class adjacent_transform_view;
5791 using iterator_category = decltype(_S_iter_cat());
5792 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5794 = remove_cvref_t<invoke_result_t
5795 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5796 range_reference_t<_Base>>>;
5797 using difference_type = range_difference_t<_Base>;
5799 _Iterator() = default;
5802 _Iterator(_Iterator<!_Const> __i)
5803 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5804 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5807 constexpr decltype(auto)
5810 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5811 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5812 }, _M_inner._M_current);
5815 constexpr _Iterator&
5830 constexpr _Iterator&
5831 operator--() requires bidirectional_range<_Base>
5838 operator--(int) requires bidirectional_range<_Base>
5845 constexpr _Iterator&
5846 operator+=(difference_type __x) requires random_access_range<_Base>
5852 constexpr _Iterator&
5853 operator-=(difference_type __x) requires random_access_range<_Base>
5859 constexpr decltype(auto)
5860 operator[](difference_type __n) const requires random_access_range<_Base>
5862 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5863 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5864 }, _M_inner._M_current);
5867 friend constexpr bool
5868 operator==(const _Iterator& __x, const _Iterator& __y)
5869 { return __x._M_inner == __y._M_inner; }
5871 friend constexpr bool
5872 operator<(const _Iterator& __x, const _Iterator& __y)
5873 requires random_access_range<_Base>
5874 { return __x._M_inner < __y._M_inner; }
5876 friend constexpr bool
5877 operator>(const _Iterator& __x, const _Iterator& __y)
5878 requires random_access_range<_Base>
5879 { return __x._M_inner > __y._M_inner; }
5881 friend constexpr bool
5882 operator<=(const _Iterator& __x, const _Iterator& __y)
5883 requires random_access_range<_Base>
5884 { return __x._M_inner <= __y._M_inner; }
5886 friend constexpr bool
5887 operator>=(const _Iterator& __x, const _Iterator& __y)
5888 requires random_access_range<_Base>
5889 { return __x._M_inner >= __y._M_inner; }
5891 friend constexpr auto
5892 operator<=>(const _Iterator& __x, const _Iterator& __y)
5893 requires random_access_range<_Base> &&
5894 three_way_comparable<_InnerIter<_Const>>
5895 { return __x._M_inner <=> __y._M_inner; }
5897 friend constexpr _Iterator
5898 operator+(const _Iterator& __i, difference_type __n)
5899 requires random_access_range<_Base>
5900 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5902 friend constexpr _Iterator
5903 operator+(difference_type __n, const _Iterator& __i)
5904 requires random_access_range<_Base>
5905 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5907 friend constexpr _Iterator
5908 operator-(const _Iterator& __i, difference_type __n)
5909 requires random_access_range<_Base>
5910 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5912 friend constexpr difference_type
5913 operator-(const _Iterator& __x, const _Iterator& __y)
5914 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5915 { return __x._M_inner - __y._M_inner; }
5918 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5919 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5920 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5921 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5922 range_reference_t<_Vp>>>
5923 template<bool _Const>
5924 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5926 _InnerSent<_Const> _M_inner;
5929 _Sentinel(_InnerSent<_Const> __inner)
5933 friend class adjacent_transform_view;
5936 _Sentinel() = default;
5939 _Sentinel(_Sentinel<!_Const> __i)
5940 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5941 : _M_inner(std::move(__i._M_inner))
5944 template<bool _OtherConst>
5945 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5946 friend constexpr bool
5947 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5948 { return __x._M_inner == __y._M_inner; }
5950 template<bool _OtherConst>
5951 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5952 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5953 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5954 { return __x._M_inner - __y._M_inner; }
5956 template<bool _OtherConst>
5957 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5958 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5959 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5960 { return __x._M_inner - __y._M_inner; }
5967 template<size_t _Nm, typename _Range, typename _Fp>
5968 concept __can_adjacent_transform_view
5969 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5970 (std::declval<_Range>(), std::declval<_Fp>()); };
5973 template<size_t _Nm>
5974 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
5976 template<viewable_range _Range, typename _Fp>
5977 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
5979 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
5981 if constexpr (_Nm == 0)
5982 return zip_transform(std::forward<_Fp>(__f));
5984 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5985 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
5988 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
5989 static constexpr int _S_arity = 2;
5990 static constexpr bool _S_has_simple_extra_args = true;
5993 template<size_t _Nm>
5994 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
5996 inline constexpr auto pairwise_transform = adjacent_transform<2>;
5998#endif // __cpp_lib_ranges_zip
6000#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6003 template<typename _Tp>
6004 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6006 _Tp __r = __num / __denom;
6007 if (__num % __denom)
6014 requires input_range<_Vp>
6015 class chunk_view : public view_interface<chunk_view<_Vp>>
6018 range_difference_t<_Vp> _M_n;
6019 range_difference_t<_Vp> _M_remainder = 0;
6020 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6027 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6028 : _M_base(std::move(__base)), _M_n(__n)
6029 { __glibcxx_assert(__n >= 0); }
6032 base() const & requires copy_constructible<_Vp>
6037 { return std::move(_M_base); }
6039 constexpr _OuterIter
6042 _M_current = ranges::begin(_M_base);
6043 _M_remainder = _M_n;
6044 return _OuterIter(*this);
6047 constexpr default_sentinel_t
6048 end() const noexcept
6049 { return default_sentinel; }
6052 size() requires sized_range<_Vp>
6054 return __detail::__to_unsigned_like(__detail::__div_ceil
6055 (ranges::distance(_M_base), _M_n));
6059 size() const requires sized_range<const _Vp>
6061 return __detail::__to_unsigned_like(__detail::__div_ceil
6062 (ranges::distance(_M_base), _M_n));
6066 template<typename _Range>
6067 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6070 requires input_range<_Vp>
6071 class chunk_view<_Vp>::_OuterIter
6073 chunk_view* _M_parent;
6076 _OuterIter(chunk_view& __parent) noexcept
6077 : _M_parent(std::__addressof(__parent))
6083 using iterator_concept = input_iterator_tag;
6084 using difference_type = range_difference_t<_Vp>;
6088 _OuterIter(_OuterIter&&) = default;
6089 _OuterIter& operator=(_OuterIter&&) = default;
6091 constexpr value_type
6094 __glibcxx_assert(*this != default_sentinel);
6095 return value_type(*_M_parent);
6098 constexpr _OuterIter&
6101 __glibcxx_assert(*this != default_sentinel);
6102 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6103 ranges::end(_M_parent->_M_base));
6104 _M_parent->_M_remainder = _M_parent->_M_n;
6112 friend constexpr bool
6113 operator==(const _OuterIter& __x, default_sentinel_t)
6115 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6116 && __x._M_parent->_M_remainder != 0;
6119 friend constexpr difference_type
6120 operator-(default_sentinel_t, const _OuterIter& __x)
6121 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6123 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6125 if (__dist < __x._M_parent->_M_remainder)
6126 return __dist == 0 ? 0 : 1;
6128 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6129 __x._M_parent->_M_n);
6132 friend constexpr difference_type
6133 operator-(const _OuterIter& __x, default_sentinel_t __y)
6134 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6135 { return -(__y - __x); }
6139 requires input_range<_Vp>
6140 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6143 chunk_view* _M_parent;
6146 value_type(chunk_view& __parent) noexcept
6147 : _M_parent(std::__addressof(__parent))
6153 constexpr _InnerIter
6154 begin() const noexcept
6155 { return _InnerIter(*_M_parent); }
6157 constexpr default_sentinel_t
6158 end() const noexcept
6159 { return default_sentinel; }
6163 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6165 return __detail::__to_unsigned_like
6166 (ranges::min(_M_parent->_M_remainder,
6167 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6172 requires input_range<_Vp>
6173 class chunk_view<_Vp>::_InnerIter
6175 chunk_view* _M_parent;
6178 _InnerIter(chunk_view& __parent) noexcept
6179 : _M_parent(std::__addressof(__parent))
6182 friend _OuterIter::value_type;
6185 using iterator_concept = input_iterator_tag;
6186 using difference_type = range_difference_t<_Vp>;
6187 using value_type = range_value_t<_Vp>;
6189 _InnerIter(_InnerIter&&) = default;
6190 _InnerIter& operator=(_InnerIter&&) = default;
6192 constexpr const iterator_t<_Vp>&
6194 { return *_M_parent->_M_current; }
6196 constexpr range_reference_t<_Vp>
6199 __glibcxx_assert(*this != default_sentinel);
6200 return **_M_parent->_M_current;
6203 constexpr _InnerIter&
6206 __glibcxx_assert(*this != default_sentinel);
6207 ++*_M_parent->_M_current;
6208 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6209 _M_parent->_M_remainder = 0;
6211 --_M_parent->_M_remainder;
6219 friend constexpr bool
6220 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6221 { return __x._M_parent->_M_remainder == 0; }
6223 friend constexpr difference_type
6224 operator-(default_sentinel_t, const _InnerIter& __x)
6225 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6227 return ranges::min(__x._M_parent->_M_remainder,
6228 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6231 friend constexpr difference_type
6232 operator-(const _InnerIter& __x, default_sentinel_t __y)
6233 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6234 { return -(__y - __x); }
6238 requires forward_range<_Vp>
6239 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6242 range_difference_t<_Vp> _M_n;
6243 template<bool> class _Iterator;
6247 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6248 : _M_base(std::move(__base)), _M_n(__n)
6249 { __glibcxx_assert(__n > 0); }
6252 base() const & requires copy_constructible<_Vp>
6257 { return std::move(_M_base); }
6260 begin() requires (!__detail::__simple_view<_Vp>)
6261 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6264 begin() const requires forward_range<const _Vp>
6265 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6268 end() requires (!__detail::__simple_view<_Vp>)
6270 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6272 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6273 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6275 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6276 return _Iterator<false>(this, ranges::end(_M_base));
6278 return default_sentinel;
6282 end() const requires forward_range<const _Vp>
6284 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6286 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6287 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6289 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6290 return _Iterator<true>(this, ranges::end(_M_base));
6292 return default_sentinel;
6296 size() requires sized_range<_Vp>
6298 return __detail::__to_unsigned_like(__detail::__div_ceil
6299 (ranges::distance(_M_base), _M_n));
6303 size() const requires sized_range<const _Vp>
6305 return __detail::__to_unsigned_like(__detail::__div_ceil
6306 (ranges::distance(_M_base), _M_n));
6310 template<typename _Vp>
6311 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6312 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6315 requires forward_range<_Vp>
6316 template<bool _Const>
6317 class chunk_view<_Vp>::_Iterator
6319 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6320 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6322 iterator_t<_Base> _M_current = iterator_t<_Base>();
6323 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6324 range_difference_t<_Base> _M_n = 0;
6325 range_difference_t<_Base> _M_missing = 0;
6328 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6329 range_difference_t<_Base> __missing = 0)
6330 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6331 _M_n(__parent->_M_n), _M_missing(__missing)
6337 if constexpr (random_access_range<_Base>)
6338 return random_access_iterator_tag{};
6339 else if constexpr (bidirectional_range<_Base>)
6340 return bidirectional_iterator_tag{};
6342 return forward_iterator_tag{};
6348 using iterator_category = input_iterator_tag;
6349 using iterator_concept = decltype(_S_iter_cat());
6350 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6351 using difference_type = range_difference_t<_Base>;
6353 _Iterator() = default;
6355 constexpr _Iterator(_Iterator<!_Const> __i)
6357 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6358 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6359 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6360 _M_n(__i._M_n), _M_missing(__i._M_missing)
6363 constexpr iterator_t<_Base>
6365 { return _M_current; }
6367 constexpr value_type
6370 __glibcxx_assert(_M_current != _M_end);
6371 return views::take(subrange(_M_current, _M_end), _M_n);
6374 constexpr _Iterator&
6377 __glibcxx_assert(_M_current != _M_end);
6378 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6390 constexpr _Iterator&
6391 operator--() requires bidirectional_range<_Base>
6393 ranges::advance(_M_current, _M_missing - _M_n);
6399 operator--(int) requires bidirectional_range<_Base>
6406 constexpr _Iterator&
6407 operator+=(difference_type __x)
6408 requires random_access_range<_Base>
6412 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6413 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6417 ranges::advance(_M_current, _M_n * __x + _M_missing);
6423 constexpr _Iterator&
6424 operator-=(difference_type __x)
6425 requires random_access_range<_Base>
6426 { return *this += -__x; }
6428 constexpr value_type
6429 operator[](difference_type __n) const
6430 requires random_access_range<_Base>
6431 { return *(*this + __n); }
6433 friend constexpr bool
6434 operator==(const _Iterator& __x, const _Iterator& __y)
6435 { return __x._M_current == __y._M_current; }
6437 friend constexpr bool
6438 operator==(const _Iterator& __x, default_sentinel_t)
6439 { return __x._M_current == __x._M_end; }
6441 friend constexpr bool
6442 operator<(const _Iterator& __x, const _Iterator& __y)
6443 requires random_access_range<_Base>
6444 { return __x._M_current > __y._M_current; }
6446 friend constexpr bool
6447 operator>(const _Iterator& __x, const _Iterator& __y)
6448 requires random_access_range<_Base>
6449 { return __y < __x; }
6451 friend constexpr bool
6452 operator<=(const _Iterator& __x, const _Iterator& __y)
6453 requires random_access_range<_Base>
6454 { return !(__y < __x); }
6456 friend constexpr bool
6457 operator>=(const _Iterator& __x, const _Iterator& __y)
6458 requires random_access_range<_Base>
6459 { return !(__x < __y); }
6461 friend constexpr auto
6462 operator<=>(const _Iterator& __x, const _Iterator& __y)
6463 requires random_access_range<_Base>
6464 && three_way_comparable<iterator_t<_Base>>
6465 { return __x._M_current <=> __y._M_current; }
6467 friend constexpr _Iterator
6468 operator+(const _Iterator& __i, difference_type __n)
6469 requires random_access_range<_Base>
6476 friend constexpr _Iterator
6477 operator+(difference_type __n, const _Iterator& __i)
6478 requires random_access_range<_Base>
6485 friend constexpr _Iterator
6486 operator-(const _Iterator& __i, difference_type __n)
6487 requires random_access_range<_Base>
6494 friend constexpr difference_type
6495 operator-(const _Iterator& __x, const _Iterator& __y)
6496 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6498 return (__x._M_current - __y._M_current
6499 + __x._M_missing - __y._M_missing) / __x._M_n;
6502 friend constexpr difference_type
6503 operator-(default_sentinel_t __y, const _Iterator& __x)
6504 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6505 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6507 friend constexpr difference_type
6508 operator-(const _Iterator& __x, default_sentinel_t __y)
6509 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6510 { return -(__y - __x); }
6517 template<typename _Range, typename _Dp>
6518 concept __can_chunk_view
6519 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6522 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6524 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6525 requires __detail::__can_chunk_view<_Range, _Dp>
6527 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6528 { return chunk_view(std::forward<_Range>(__r), __n); }
6530 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6531 static constexpr int _S_arity = 2;
6532 static constexpr bool _S_has_simple_extra_args = true;
6535 inline constexpr _Chunk chunk;
6537#endif // __cpp_lib_ranges_chunk
6539#ifdef __cpp_lib_ranges_slide // C++ >= 23
6542 template<typename _Vp>
6543 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6545 template<typename _Vp>
6546 concept __slide_caches_last
6547 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6549 template<typename _Vp>
6550 concept __slide_caches_first
6551 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6554 template<forward_range _Vp>
6556 class slide_view : public view_interface<slide_view<_Vp>>
6559 range_difference_t<_Vp> _M_n;
6560 [[no_unique_address]]
6561 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6562 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6563 [[no_unique_address]]
6564 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6565 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6567 template<bool> class _Iterator;
6572 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6573 : _M_base(std::move(__base)), _M_n(__n)
6574 { __glibcxx_assert(__n > 0); }
6577 begin() requires (!(__detail::__simple_view<_Vp>
6578 && __detail::__slide_caches_nothing<const _Vp>))
6580 if constexpr (__detail::__slide_caches_first<_Vp>)
6582 iterator_t<_Vp> __it;
6583 if (_M_cached_begin._M_has_value())
6584 __it = _M_cached_begin._M_get(_M_base);
6587 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6588 _M_cached_begin._M_set(_M_base, __it);
6590 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6593 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6597 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6598 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6601 end() requires (!(__detail::__simple_view<_Vp>
6602 && __detail::__slide_caches_nothing<const _Vp>))
6604 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6605 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6607 else if constexpr (__detail::__slide_caches_last<_Vp>)
6609 iterator_t<_Vp> __it;
6610 if (_M_cached_end._M_has_value())
6611 __it = _M_cached_end._M_get(_M_base);
6614 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6615 _M_cached_end._M_set(_M_base, __it);
6617 return _Iterator<false>(std::move(__it), _M_n);
6619 else if constexpr (common_range<_Vp>)
6620 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6622 return _Sentinel(ranges::end(_M_base));
6626 end() const requires __detail::__slide_caches_nothing<const _Vp>
6627 { return begin() + range_difference_t<const _Vp>(size()); }
6630 size() requires sized_range<_Vp>
6632 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6635 return __detail::__to_unsigned_like(__sz);
6639 size() const requires sized_range<const _Vp>
6641 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6644 return __detail::__to_unsigned_like(__sz);
6648 template<typename _Range>
6649 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6651 template<typename _Vp>
6652 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6653 = enable_borrowed_range<_Vp>;
6655 template<forward_range _Vp>
6657 template<bool _Const>
6658 class slide_view<_Vp>::_Iterator
6660 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6661 static constexpr bool _S_last_elt_present
6662 = __detail::__slide_caches_first<_Base>;
6664 iterator_t<_Base> _M_current = iterator_t<_Base>();
6665 [[no_unique_address]]
6666 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6667 _M_last_elt = decltype(_M_last_elt)();
6668 range_difference_t<_Base> _M_n = 0;
6671 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6672 requires (!_S_last_elt_present)
6673 : _M_current(__current), _M_n(__n)
6677 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6678 range_difference_t<_Base> __n)
6679 requires _S_last_elt_present
6680 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6686 if constexpr (random_access_range<_Base>)
6687 return random_access_iterator_tag{};
6688 else if constexpr (bidirectional_range<_Base>)
6689 return bidirectional_iterator_tag{};
6691 return forward_iterator_tag{};
6695 friend slide_view::_Sentinel;
6698 using iterator_category = input_iterator_tag;
6699 using iterator_concept = decltype(_S_iter_concept());
6700 using value_type = decltype(views::counted(_M_current, _M_n));
6701 using difference_type = range_difference_t<_Base>;
6703 _Iterator() = default;
6706 _Iterator(_Iterator<!_Const> __i)
6707 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6708 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6713 { return views::counted(_M_current, _M_n); }
6715 constexpr _Iterator&
6719 if constexpr (_S_last_elt_present)
6732 constexpr _Iterator&
6733 operator--() requires bidirectional_range<_Base>
6736 if constexpr (_S_last_elt_present)
6742 operator--(int) requires bidirectional_range<_Base>
6749 constexpr _Iterator&
6750 operator+=(difference_type __x)
6751 requires random_access_range<_Base>
6754 if constexpr (_S_last_elt_present)
6759 constexpr _Iterator&
6760 operator-=(difference_type __x)
6761 requires random_access_range<_Base>
6764 if constexpr (_S_last_elt_present)
6770 operator[](difference_type __n) const
6771 requires random_access_range<_Base>
6772 { return views::counted(_M_current + __n, _M_n); }
6774 friend constexpr bool
6775 operator==(const _Iterator& __x, const _Iterator& __y)
6777 if constexpr (_S_last_elt_present)
6778 return __x._M_last_elt == __y._M_last_elt;
6780 return __x._M_current == __y._M_current;
6783 friend constexpr bool
6784 operator<(const _Iterator& __x, const _Iterator& __y)
6785 requires random_access_range<_Base>
6786 { return __x._M_current < __y._M_current; }
6788 friend constexpr bool
6789 operator>(const _Iterator& __x, const _Iterator& __y)
6790 requires random_access_range<_Base>
6791 { return __y < __x; }
6793 friend constexpr bool
6794 operator<=(const _Iterator& __x, const _Iterator& __y)
6795 requires random_access_range<_Base>
6796 { return !(__y < __x); }
6798 friend constexpr bool
6799 operator>=(const _Iterator& __x, const _Iterator& __y)
6800 requires random_access_range<_Base>
6801 { return !(__x < __y); }
6803 friend constexpr auto
6804 operator<=>(const _Iterator& __x, const _Iterator& __y)
6805 requires random_access_range<_Base>
6806 && three_way_comparable<iterator_t<_Base>>
6807 { return __x._M_current <=> __y._M_current; }
6809 friend constexpr _Iterator
6810 operator+(const _Iterator& __i, difference_type __n)
6811 requires random_access_range<_Base>
6818 friend constexpr _Iterator
6819 operator+(difference_type __n, const _Iterator& __i)
6820 requires random_access_range<_Base>
6827 friend constexpr _Iterator
6828 operator-(const _Iterator& __i, difference_type __n)
6829 requires random_access_range<_Base>
6836 friend constexpr difference_type
6837 operator-(const _Iterator& __x, const _Iterator& __y)
6838 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6840 if constexpr (_S_last_elt_present)
6841 return __x._M_last_elt - __y._M_last_elt;
6843 return __x._M_current - __y._M_current;
6847 template<forward_range _Vp>
6849 class slide_view<_Vp>::_Sentinel
6851 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6854 _Sentinel(sentinel_t<_Vp> __end)
6861 _Sentinel() = default;
6863 friend constexpr bool
6864 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6865 { return __x._M_last_elt == __y._M_end; }
6867 friend constexpr range_difference_t<_Vp>
6868 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6869 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6870 { return __x._M_last_elt - __y._M_end; }
6872 friend constexpr range_difference_t<_Vp>
6873 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6874 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6875 { return __y._M_end -__x._M_last_elt; }
6882 template<typename _Range, typename _Dp>
6883 concept __can_slide_view
6884 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6887 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6889 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6890 requires __detail::__can_slide_view<_Range, _Dp>
6892 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6893 { return slide_view(std::forward<_Range>(__r), __n); }
6895 using __adaptor::_RangeAdaptor<_Slide>::operator();
6896 static constexpr int _S_arity = 2;
6897 static constexpr bool _S_has_simple_extra_args = true;
6900 inline constexpr _Slide slide;
6902#endif // __cpp_lib_ranges_slide
6904#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
6905 template<forward_range _Vp,
6906 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6907 requires view<_Vp> && is_object_v<_Pred>
6908 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6910 _Vp _M_base = _Vp();
6911 __detail::__box<_Pred> _M_pred;
6912 __detail::_CachedPosition<_Vp> _M_cached_begin;
6914 constexpr iterator_t<_Vp>
6915 _M_find_next(iterator_t<_Vp> __current)
6917 __glibcxx_assert(_M_pred.has_value());
6918 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6919 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6921 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6922 return ranges::next(__it, 1, ranges::end(_M_base));
6925 constexpr iterator_t<_Vp>
6926 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
6928 __glibcxx_assert(_M_pred.has_value());
6929 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6930 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
6932 auto __rbegin = std::make_reverse_iterator(__current);
6933 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
6934 __glibcxx_assert(__rbegin != __rend);
6935 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
6936 return ranges::prev(__it, 1, ranges::begin(_M_base));
6942 chunk_by_view() requires (default_initializable<_Vp>
6943 && default_initializable<_Pred>)
6947 chunk_by_view(_Vp __base, _Pred __pred)
6948 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
6952 base() const & requires copy_constructible<_Vp>
6957 { return std::move(_M_base); }
6959 constexpr const _Pred&
6961 { return *_M_pred; }
6966 __glibcxx_assert(_M_pred.has_value());
6967 iterator_t<_Vp> __it;
6968 if (_M_cached_begin._M_has_value())
6969 __it = _M_cached_begin._M_get(_M_base);
6972 __it = _M_find_next(ranges::begin(_M_base));
6973 _M_cached_begin._M_set(_M_base, __it);
6975 return _Iterator(*this, ranges::begin(_M_base), __it);
6981 if constexpr (common_range<_Vp>)
6982 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
6984 return default_sentinel;
6988 template<typename _Range, typename _Pred>
6989 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
6991 template<forward_range _Vp,
6992 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6993 requires view<_Vp> && is_object_v<_Pred>
6994 class chunk_by_view<_Vp, _Pred>::_Iterator
6996 chunk_by_view* _M_parent = nullptr;
6997 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
6998 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7001 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7002 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7008 if constexpr (bidirectional_range<_Vp>)
7009 return bidirectional_iterator_tag{};
7011 return forward_iterator_tag{};
7014 friend chunk_by_view;
7017 using value_type = subrange<iterator_t<_Vp>>;
7018 using difference_type = range_difference_t<_Vp>;
7019 using iterator_category = input_iterator_tag;
7020 using iterator_concept = decltype(_S_iter_concept());
7022 _Iterator() = default;
7024 constexpr value_type
7027 __glibcxx_assert(_M_current != _M_next);
7028 return ranges::subrange(_M_current, _M_next);
7031 constexpr _Iterator&
7034 __glibcxx_assert(_M_current != _M_next);
7035 _M_current = _M_next;
7036 _M_next = _M_parent->_M_find_next(_M_current);
7048 constexpr _Iterator&
7049 operator--() requires bidirectional_range<_Vp>
7051 _M_next = _M_current;
7052 _M_current = _M_parent->_M_find_prev(_M_next);
7057 operator--(int) requires bidirectional_range<_Vp>
7064 friend constexpr bool
7065 operator==(const _Iterator& __x, const _Iterator& __y)
7066 { return __x._M_current == __y._M_current; }
7068 friend constexpr bool
7069 operator==(const _Iterator& __x, default_sentinel_t)
7070 { return __x._M_current == __x._M_next; }
7077 template<typename _Range, typename _Pred>
7078 concept __can_chunk_by_view
7079 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7082 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7084 template<viewable_range _Range, typename _Pred>
7085 requires __detail::__can_chunk_by_view<_Range, _Pred>
7087 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7088 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7090 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7091 static constexpr int _S_arity = 2;
7092 static constexpr bool _S_has_simple_extra_args = true;
7095 inline constexpr _ChunkBy chunk_by;
7097#endif // __cpp_lib_ranges_chunk_by
7099#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7102 template<typename _Range, typename _Pattern>
7103 concept __compatible_joinable_ranges
7104 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7105 && common_reference_with<range_reference_t<_Range>,
7106 range_reference_t<_Pattern>>
7107 && common_reference_with<range_rvalue_reference_t<_Range>,
7108 range_rvalue_reference_t<_Pattern>>;
7110 template<typename _Range>
7111 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7114 template<input_range _Vp, forward_range _Pattern>
7115 requires view<_Vp> && view<_Pattern>
7116 && input_range<range_reference_t<_Vp>>
7117 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7118 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7120 using _InnerRange = range_reference_t<_Vp>;
7122 _Vp _M_base = _Vp();
7123 [[no_unique_address]]
7124 __detail::__maybe_present_t<!forward_range<_Vp>,
7125 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7126 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7127 _Pattern _M_pattern = _Pattern();
7129 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7130 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7131 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7133 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7134 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7135 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7137 template<bool _Const>
7138 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7140 template<bool _Const>
7144 template<bool _Const>
7145 requires _S_ref_is_glvalue<_Const>
7146 && forward_range<_Base<_Const>>
7147 && forward_range<_InnerBase<_Const>>
7148 struct __iter_cat<_Const>
7154 using _OuterIter = join_with_view::_OuterIter<_Const>;
7155 using _InnerIter = join_with_view::_InnerIter<_Const>;
7156 using _PatternIter = join_with_view::_PatternIter<_Const>;
7157 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7158 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7159 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7160 if constexpr (!is_lvalue_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7161 iter_reference_t<_PatternIter>>>)
7162 return input_iterator_tag{};
7163 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7164 && derived_from<_InnerCat, bidirectional_iterator_tag>
7165 && derived_from<_PatternCat, bidirectional_iterator_tag>
7166 && common_range<_InnerBase<_Const>>
7167 && common_range<_PatternBase<_Const>>)
7168 return bidirectional_iterator_tag{};
7169 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7170 && derived_from<_InnerCat, forward_iterator_tag>
7171 && derived_from<_PatternCat, forward_iterator_tag>)
7172 return forward_iterator_tag{};
7174 return input_iterator_tag{};
7177 using iterator_category = decltype(_S_iter_cat());
7180 template<bool> struct _Iterator;
7181 template<bool> struct _Sentinel;
7184 join_with_view() requires (default_initializable<_Vp>
7185 && default_initializable<_Pattern>)
7189 join_with_view(_Vp __base, _Pattern __pattern)
7190 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7193 template<input_range _Range>
7194 requires constructible_from<_Vp, views::all_t<_Range>>
7195 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7197 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7198 : _M_base(views::all(std::forward<_Range>(__r))),
7199 _M_pattern(views::single(std::move(__e)))
7203 base() const& requires copy_constructible<_Vp>
7208 { return std::move(_M_base); }
7213 if constexpr (forward_range<_Vp>)
7215 constexpr bool __use_const = is_reference_v<_InnerRange>
7216 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7217 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7221 _M_outer_it = ranges::begin(_M_base);
7222 return _Iterator<false>{*this};
7228 requires forward_range<const _Vp>
7229 && forward_range<const _Pattern>
7230 && is_reference_v<range_reference_t<const _Vp>>
7231 && input_range<range_reference_t<const _Vp>>
7232 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7237 constexpr bool __use_const
7238 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7239 if constexpr (is_reference_v<_InnerRange>
7240 && forward_range<_Vp> && common_range<_Vp>
7241 && forward_range<_InnerRange> && common_range<_InnerRange>)
7242 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7244 return _Sentinel<__use_const>{*this};
7249 requires forward_range<const _Vp>
7250 && forward_range<const _Pattern>
7251 && is_reference_v<range_reference_t<const _Vp>>
7252 && input_range<range_reference_t<const _Vp>>
7254 using _InnerConstRange = range_reference_t<const _Vp>;
7255 if constexpr (forward_range<_InnerConstRange>
7256 && common_range<const _Vp>
7257 && common_range<_InnerConstRange>)
7258 return _Iterator<true>{*this, ranges::end(_M_base)};
7260 return _Sentinel<true>{*this};
7264 template<typename _Range, typename _Pattern>
7265 join_with_view(_Range&&, _Pattern&&)
7266 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7268 template<input_range _Range>
7269 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7270 -> join_with_view<views::all_t<_Range>,
7271 single_view<range_value_t<range_reference_t<_Range>>>>;
7273 template<input_range _Vp, forward_range _Pattern>
7274 requires view<_Vp> && view<_Pattern>
7275 && input_range<range_reference_t<_Vp>>
7276 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7277 template<bool _Const>
7278 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7280 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7281 using _Base = join_with_view::_Base<_Const>;
7282 using _InnerBase = join_with_view::_InnerBase<_Const>;
7283 using _PatternBase = join_with_view::_PatternBase<_Const>;
7285 using _OuterIter = join_with_view::_OuterIter<_Const>;
7286 using _InnerIter = join_with_view::_InnerIter<_Const>;
7287 using _PatternIter = join_with_view::_PatternIter<_Const>;
7289 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7291 _Parent* _M_parent = nullptr;
7292 [[no_unique_address]]
7293 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it;
7294 variant<_PatternIter, _InnerIter> _M_inner_it;
7296 constexpr _OuterIter&
7299 if constexpr (forward_range<_Base>)
7302 return *_M_parent->_M_outer_it;
7305 constexpr const _OuterIter&
7306 _M_get_outer() const
7308 if constexpr (forward_range<_Base>)
7311 return *_M_parent->_M_outer_it;
7315 _Iterator(_Parent& __parent, _OuterIter __outer)
7316 requires forward_range<_Base>
7317 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7319 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7321 auto&& __inner = _M_update_inner();
7322 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7328 _Iterator(_Parent& __parent)
7329 requires (!forward_range<_Base>)
7330 : _M_parent(std::__addressof(__parent))
7332 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7334 auto&& __inner = _M_update_inner();
7335 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7343 _OuterIter& __outer = _M_get_outer();
7344 if constexpr (_S_ref_is_glvalue)
7345 return __detail::__as_lvalue(*__outer);
7347 return _M_parent->_M_inner._M_emplace_deref(__outer);
7353 if constexpr (_S_ref_is_glvalue)
7354 return __detail::__as_lvalue(*_M_get_outer());
7356 return *_M_parent->_M_inner;
7364 if (_M_inner_it.index() == 0)
7366 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7369 auto&& __inner = _M_update_inner();
7370 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7374 auto&& __inner = _M_get_inner();
7375 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7378 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7380 if constexpr (_S_ref_is_glvalue)
7381 _M_inner_it.template emplace<0>();
7385 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7393 if constexpr (_S_ref_is_glvalue
7394 && bidirectional_range<_Base>
7395 && __detail::__bidirectional_common<_InnerBase>
7396 && __detail::__bidirectional_common<_PatternBase>)
7397 return bidirectional_iterator_tag{};
7398 else if constexpr (_S_ref_is_glvalue
7399 && forward_range<_Base>
7400 && forward_range<_InnerBase>)
7401 return forward_iterator_tag{};
7403 return input_iterator_tag{};
7406 friend join_with_view;
7409 using iterator_concept = decltype(_S_iter_concept());
7410 // iterator_category defined in join_with_view::__iter_cat
7411 using value_type = common_type_t<iter_value_t<_InnerIter>,
7412 iter_value_t<_PatternIter>>;
7413 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7414 iter_difference_t<_InnerIter>,
7415 iter_difference_t<_PatternIter>>;
7417 _Iterator() = default;
7420 _Iterator(_Iterator<!_Const> __i)
7422 && convertible_to<iterator_t<_Vp>, _OuterIter>
7423 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7424 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7425 : _M_parent(__i._M_parent),
7426 _M_outer_it(std::move(__i._M_outer_it))
7428 if (__i._M_inner_it.index() == 0)
7429 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7431 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7434 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7435 iter_reference_t<_PatternIter>>
7438 if (_M_inner_it.index() == 0)
7439 return *std::get<0>(_M_inner_it);
7441 return *std::get<1>(_M_inner_it);
7444 constexpr _Iterator&
7447 if (_M_inner_it.index() == 0)
7448 ++std::get<0>(_M_inner_it);
7450 ++std::get<1>(_M_inner_it);
7461 requires _S_ref_is_glvalue
7462 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7464 _Iterator __tmp = *this;
7469 constexpr _Iterator&
7471 requires _S_ref_is_glvalue
7472 && bidirectional_range<_Base>
7473 && __detail::__bidirectional_common<_InnerBase>
7474 && __detail::__bidirectional_common<_PatternBase>
7476 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7478 auto&& __inner = *--_M_outer_it;
7479 _M_inner_it.template emplace<1>(ranges::end(__inner));
7484 if (_M_inner_it.index() == 0)
7486 auto& __it = std::get<0>(_M_inner_it);
7487 if (__it == ranges::begin(_M_parent->_M_pattern))
7489 auto&& __inner = *--_M_outer_it;
7490 _M_inner_it.template emplace<1>(ranges::end(__inner));
7497 auto& __it = std::get<1>(_M_inner_it);
7498 auto&& __inner = *_M_outer_it;
7499 if (__it == ranges::begin(__inner))
7500 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7506 if (_M_inner_it.index() == 0)
7507 --std::get<0>(_M_inner_it);
7509 --std::get<1>(_M_inner_it);
7515 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7516 && __detail::__bidirectional_common<_InnerBase>
7517 && __detail::__bidirectional_common<_PatternBase>
7519 _Iterator __tmp = *this;
7524 friend constexpr bool
7525 operator==(const _Iterator& __x, const _Iterator& __y)
7526 requires _S_ref_is_glvalue
7527 && forward_range<_Base> && equality_comparable<_InnerIter>
7528 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7530 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7531 iter_rvalue_reference_t<_PatternIter>>
7532 iter_move(const _Iterator& __x)
7534 if (__x._M_inner_it.index() == 0)
7535 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7537 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7540 friend constexpr void
7541 iter_swap(const _Iterator& __x, const _Iterator& __y)
7542 requires indirectly_swappable<_InnerIter, _PatternIter>
7544 if (__x._M_inner_it.index() == 0)
7546 if (__y._M_inner_it.index() == 0)
7547 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7549 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7553 if (__y._M_inner_it.index() == 0)
7554 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7556 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7561 template<input_range _Vp, forward_range _Pattern>
7562 requires view<_Vp> && view<_Pattern>
7563 && input_range<range_reference_t<_Vp>>
7564 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7565 template<bool _Const>
7566 class join_with_view<_Vp, _Pattern>::_Sentinel
7568 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7569 using _Base = join_with_view::_Base<_Const>;
7571 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7574 _Sentinel(_Parent& __parent)
7575 : _M_end(ranges::end(__parent._M_base))
7578 friend join_with_view;
7581 _Sentinel() = default;
7584 _Sentinel(_Sentinel<!_Const> __s)
7585 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7586 : _M_end(std::move(__s._M_end))
7589 template<bool _OtherConst>
7590 requires sentinel_for<sentinel_t<_Base>,
7591 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7592 friend constexpr bool
7593 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7594 { return __x._M_get_outer() == __y._M_end; }
7601 template<typename _Range, typename _Pattern>
7602 concept __can_join_with_view
7603 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7604 } // namespace __detail
7606 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7608 template<viewable_range _Range, typename _Pattern>
7609 requires __detail::__can_join_with_view<_Range, _Pattern>
7611 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7613 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7616 using _RangeAdaptor<_JoinWith>::operator();
7617 static constexpr int _S_arity = 2;
7618 template<typename _Pattern>
7619 static constexpr bool _S_has_simple_extra_args
7620 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7623 inline constexpr _JoinWith join_with;
7624 } // namespace views
7625#endif // __cpp_lib_ranges_join_with
7627#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7628 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7629 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7630 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7631 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7633 __detail::__box<_Tp> _M_value;
7634 [[no_unique_address]] _Bound _M_bound = _Bound();
7638 template<typename _Range>
7639 friend constexpr auto
7640 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7642 template<typename _Range>
7643 friend constexpr auto
7644 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7647 repeat_view() requires default_initializable<_Tp> = default;
7650 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7651 requires copy_constructible<_Tp>
7652 : _M_value(__value), _M_bound(__bound)
7654 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7655 __glibcxx_assert(__bound >= 0);
7659 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7660 : _M_value(std::move(__value)), _M_bound(__bound)
7663 template<typename... _Args, typename... _BoundArgs>
7664 requires constructible_from<_Tp, _Args...>
7665 && constructible_from<_Bound, _BoundArgs...>
7667 repeat_view(piecewise_construct_t,
7668 tuple<_Args...> __args,
7669 tuple<_BoundArgs...> __bound_args = tuple<>{})
7670 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7671 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7676 { return _Iterator(std::__addressof(*_M_value)); }
7679 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7680 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7682 constexpr unreachable_sentinel_t
7683 end() const noexcept
7684 { return unreachable_sentinel; }
7687 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7688 { return __detail::__to_unsigned_like(_M_bound); }
7691 template<typename _Tp, typename _Bound>
7692 repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
7694 template<move_constructible _Tp, semiregular _Bound>
7695 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7696 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7697 class repeat_view<_Tp, _Bound>::_Iterator
7700 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7702 const _Tp* _M_value = nullptr;
7703 __index_type _M_current = __index_type();
7706 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7707 : _M_value(__value), _M_current(__bound)
7709 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7710 __glibcxx_assert(__bound >= 0);
7716 using iterator_concept = random_access_iterator_tag;
7717 using iterator_category = random_access_iterator_tag;
7718 using value_type = _Tp;
7719 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7721 __detail::__iota_diff_t<__index_type>>;
7723 _Iterator() = default;
7725 constexpr const _Tp&
7726 operator*() const noexcept
7727 { return *_M_value; }
7729 constexpr _Iterator&
7744 constexpr _Iterator&
7747 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7748 __glibcxx_assert(_M_current > 0);
7761 constexpr _Iterator&
7762 operator+=(difference_type __n)
7764 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7765 __glibcxx_assert(_M_current + __n >= 0);
7770 constexpr _Iterator&
7771 operator-=(difference_type __n)
7773 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7774 __glibcxx_assert(_M_current - __n >= 0);
7779 constexpr const _Tp&
7780 operator[](difference_type __n) const noexcept
7781 { return *(*this + __n); }
7783 friend constexpr bool
7784 operator==(const _Iterator& __x, const _Iterator& __y)
7785 { return __x._M_current == __y._M_current; }
7787 friend constexpr auto
7788 operator<=>(const _Iterator& __x, const _Iterator& __y)
7789 { return __x._M_current <=> __y._M_current; }
7791 friend constexpr _Iterator
7792 operator+(_Iterator __i, difference_type __n)
7798 friend constexpr _Iterator
7799 operator+(difference_type __n, _Iterator __i)
7800 { return __i + __n; }
7802 friend constexpr _Iterator
7803 operator-(_Iterator __i, difference_type __n)
7809 friend constexpr difference_type
7810 operator-(const _Iterator& __x, const _Iterator& __y)
7812 return (static_cast<difference_type>(__x._M_current)
7813 - static_cast<difference_type>(__y._M_current));
7821 template<typename _Tp, typename _Bound>
7822 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7824 template<typename _Tp>
7825 concept __can_repeat_view
7826 = requires { repeat_view(std::declval<_Tp>()); };
7828 template<typename _Tp, typename _Bound>
7829 concept __can_bounded_repeat_view
7830 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7835 template<typename _Tp>
7836 requires __detail::__can_repeat_view<_Tp>
7838 operator() [[nodiscard]] (_Tp&& __value) const
7839 { return repeat_view(std::forward<_Tp>(__value)); }
7841 template<typename _Tp, typename _Bound>
7842 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7844 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7845 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7848 inline constexpr _Repeat repeat;
7852 template<typename _Range>
7854 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7856 using _Tp = remove_cvref_t<_Range>;
7857 static_assert(__is_repeat_view<_Tp>);
7858 if constexpr (sized_range<_Tp>)
7859 return views::repeat(*std::forward<_Range>(__r)._M_value,
7860 std::min(ranges::distance(__r), __n));
7862 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7865 template<typename _Range>
7867 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7869 using _Tp = remove_cvref_t<_Range>;
7870 static_assert(__is_repeat_view<_Tp>);
7871 if constexpr (sized_range<_Tp>)
7873 auto __sz = ranges::distance(__r);
7874 return views::repeat(*std::forward<_Range>(__r)._M_value,
7875 __sz - std::min(__sz, __n));
7882#endif // __cpp_lib_ranges_repeat
7884#ifdef __cpp_lib_ranges_stride // C++ >= 23
7885 template<input_range _Vp>
7887 class stride_view : public view_interface<stride_view<_Vp>>
7890 range_difference_t<_Vp> _M_stride;
7892 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7894 template<bool _Const>
7898 template<bool _Const>
7899 requires forward_range<_Base<_Const>>
7900 struct __iter_cat<_Const>
7906 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7907 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7908 return random_access_iterator_tag{};
7913 using iterator_category = decltype(_S_iter_cat());
7916 template<bool> class _Iterator;
7920 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7921 : _M_base(std::move(__base)), _M_stride(__stride)
7922 { __glibcxx_assert(__stride > 0); }
7925 base() const& requires copy_constructible<_Vp>
7930 { return std::move(_M_base); }
7932 constexpr range_difference_t<_Vp>
7933 stride() const noexcept
7934 { return _M_stride; }
7937 begin() requires (!__detail::__simple_view<_Vp>)
7938 { return _Iterator<false>(this, ranges::begin(_M_base)); }
7941 begin() const requires range<const _Vp>
7942 { return _Iterator<true>(this, ranges::begin(_M_base)); }
7945 end() requires (!__detail::__simple_view<_Vp>)
7947 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
7949 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7950 return _Iterator<false>(this, ranges::end(_M_base), __missing);
7952 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
7953 return _Iterator<false>(this, ranges::end(_M_base));
7955 return default_sentinel;
7959 end() const requires range<const _Vp>
7961 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
7962 && forward_range<const _Vp>)
7964 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7965 return _Iterator<true>(this, ranges::end(_M_base), __missing);
7967 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
7968 return _Iterator<true>(this, ranges::end(_M_base));
7970 return default_sentinel;
7974 size() requires sized_range<_Vp>
7976 return __detail::__to_unsigned_like
7977 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7981 size() const requires sized_range<const _Vp>
7983 return __detail::__to_unsigned_like
7984 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7988 template<typename _Range>
7989 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
7991 template<typename _Vp>
7992 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
7993 = enable_borrowed_range<_Vp>;
7995 template<input_range _Vp>
7997 template<bool _Const>
7998 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8000 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8001 using _Base = stride_view::_Base<_Const>;
8003 iterator_t<_Base> _M_current = iterator_t<_Base>();
8004 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8005 range_difference_t<_Base> _M_stride = 0;
8006 range_difference_t<_Base> _M_missing = 0;
8009 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8010 range_difference_t<_Base> __missing = 0)
8011 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8012 _M_stride(__parent->_M_stride), _M_missing(__missing)
8018 if constexpr (random_access_range<_Base>)
8019 return random_access_iterator_tag{};
8020 else if constexpr (bidirectional_range<_Base>)
8021 return bidirectional_iterator_tag{};
8022 else if constexpr (forward_range<_Base>)
8023 return forward_iterator_tag{};
8025 return input_iterator_tag{};
8031 using difference_type = range_difference_t<_Base>;
8032 using value_type = range_value_t<_Base>;
8033 using iterator_concept = decltype(_S_iter_concept());
8034 // iterator_category defined in stride_view::__iter_cat
8036 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8039 _Iterator(_Iterator<!_Const> __other)
8041 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8042 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8043 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8044 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8047 constexpr iterator_t<_Base>
8049 { return std::move(_M_current); }
8051 constexpr const iterator_t<_Base>&
8052 base() const & noexcept
8053 { return _M_current; }
8055 constexpr decltype(auto)
8057 { return *_M_current; }
8059 constexpr _Iterator&
8062 __glibcxx_assert(_M_current != _M_end);
8063 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8072 operator++(int) requires forward_range<_Base>
8079 constexpr _Iterator&
8080 operator--() requires bidirectional_range<_Base>
8082 ranges::advance(_M_current, _M_missing - _M_stride);
8088 operator--(int) requires bidirectional_range<_Base>
8095 constexpr _Iterator&
8096 operator+=(difference_type __n) requires random_access_range<_Base>
8100 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8101 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8105 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8111 constexpr _Iterator&
8112 operator-=(difference_type __n) requires random_access_range<_Base>
8113 { return *this += -__n; }
8115 constexpr decltype(auto) operator[](difference_type __n) const
8116 requires random_access_range<_Base>
8117 { return *(*this + __n); }
8119 friend constexpr bool
8120 operator==(const _Iterator& __x, default_sentinel_t)
8121 { return __x._M_current == __x._M_end; }
8123 friend constexpr bool
8124 operator==(const _Iterator& __x, const _Iterator& __y)
8125 requires equality_comparable<iterator_t<_Base>>
8126 { return __x._M_current == __y._M_current; }
8128 friend constexpr bool
8129 operator<(const _Iterator& __x, const _Iterator& __y)
8130 requires random_access_range<_Base>
8131 { return __x._M_current < __y._M_current; }
8133 friend constexpr bool
8134 operator>(const _Iterator& __x, const _Iterator& __y)
8135 requires random_access_range<_Base>
8136 { return __y._M_current < __x._M_current; }
8138 friend constexpr bool
8139 operator<=(const _Iterator& __x, const _Iterator& __y)
8140 requires random_access_range<_Base>
8141 { return !(__y._M_current < __x._M_current); }
8143 friend constexpr bool
8144 operator>=(const _Iterator& __x, const _Iterator& __y)
8145 requires random_access_range<_Base>
8146 { return !(__x._M_current < __y._M_current); }
8148 friend constexpr auto
8149 operator<=>(const _Iterator& __x, const _Iterator& __y)
8150 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8151 { return __x._M_current <=> __y._M_current; }
8153 friend constexpr _Iterator
8154 operator+(const _Iterator& __i, difference_type __n)
8155 requires random_access_range<_Base>
8162 friend constexpr _Iterator
8163 operator+(difference_type __n, const _Iterator& __i)
8164 requires random_access_range<_Base>
8165 { return __i + __n; }
8167 friend constexpr _Iterator
8168 operator-(const _Iterator& __i, difference_type __n)
8169 requires random_access_range<_Base>
8176 friend constexpr difference_type
8177 operator-(const _Iterator& __x, const _Iterator& __y)
8178 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8180 auto __n = __x._M_current - __y._M_current;
8181 if constexpr (forward_range<_Base>)
8182 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8184 return -__detail::__div_ceil(-__n, __x._M_stride);
8186 return __detail::__div_ceil(__n, __x._M_stride);
8189 friend constexpr difference_type
8190 operator-(default_sentinel_t __y, const _Iterator& __x)
8191 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8192 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8194 friend constexpr difference_type
8195 operator-(const _Iterator& __x, default_sentinel_t __y)
8196 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8197 { return -(__y - __x); }
8199 friend constexpr range_rvalue_reference_t<_Base>
8200 iter_move(const _Iterator& __i)
8201 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8202 { return ranges::iter_move(__i._M_current); }
8204 friend constexpr void
8205 iter_swap(const _Iterator& __x, const _Iterator& __y)
8206 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8207 requires indirectly_swappable<iterator_t<_Base>>
8208 { ranges::iter_swap(__x._M_current, __y._M_current); }
8215 template<typename _Range, typename _Dp>
8216 concept __can_stride_view
8217 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8220 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8222 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8223 requires __detail::__can_stride_view<_Range, _Dp>
8225 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8226 { return stride_view(std::forward<_Range>(__r), __n); }
8228 using __adaptor::_RangeAdaptor<_Stride>::operator();
8229 static constexpr int _S_arity = 2;
8230 static constexpr bool _S_has_simple_extra_args = true;
8233 inline constexpr _Stride stride;
8235#endif // __cpp_lib_ranges_stride
8237#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8240 template<bool _Const, typename _First, typename... _Vs>
8241 concept __cartesian_product_is_random_access
8242 = (random_access_range<__maybe_const_t<_Const, _First>>
8244 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8245 && sized_range<__maybe_const_t<_Const, _Vs>>));
8247 template<typename _Range>
8248 concept __cartesian_product_common_arg
8249 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8251 template<bool _Const, typename _First, typename... _Vs>
8252 concept __cartesian_product_is_bidirectional
8253 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8255 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8256 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8258 template<typename _First, typename... _Vs>
8259 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8261 template<typename... _Vs>
8262 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8264 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8265 concept __cartesian_is_sized_sentinel
8266 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8267 iterator_t<__maybe_const_t<_Const, _First>>>
8269 && (sized_range<__maybe_const_t<_Const, _Vs>>
8270 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8271 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8273 template<__cartesian_product_common_arg _Range>
8275 __cartesian_common_arg_end(_Range& __r)
8277 if constexpr (common_range<_Range>)
8278 return ranges::end(__r);
8280 return ranges::begin(__r) + ranges::distance(__r);
8282 } // namespace __detail
8284 template<input_range _First, forward_range... _Vs>
8285 requires (view<_First> && ... && view<_Vs>)
8286 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8288 tuple<_First, _Vs...> _M_bases;
8290 template<bool> class _Iterator;
8293 _S_difference_type()
8295 // TODO: Implement the recommended practice of using the smallest
8296 // sufficiently wide type according to the maximum sizes of the
8297 // underlying ranges?
8298 return common_type_t<ptrdiff_t,
8299 range_difference_t<_First>,
8300 range_difference_t<_Vs>...>{};
8304 cartesian_product_view() = default;
8307 cartesian_product_view(_First __first, _Vs... __rest)
8308 : _M_bases(std::move(__first), std::move(__rest)...)
8311 constexpr _Iterator<false>
8312 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8313 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8315 constexpr _Iterator<true>
8316 begin() const requires (range<const _First> && ... && range<const _Vs>)
8317 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8319 constexpr _Iterator<false>
8320 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8321 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8323 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8324 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8325 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8326 auto& __first = std::get<0>(_M_bases);
8327 return _Ret{(__empty_tail
8328 ? ranges::begin(__first)
8329 : __detail::__cartesian_common_arg_end(__first)),
8330 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8331 }(make_index_sequence<sizeof...(_Vs)>{});
8333 return _Iterator<false>{*this, std::move(__its)};
8336 constexpr _Iterator<true>
8337 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8339 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8340 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8341 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8342 auto& __first = std::get<0>(_M_bases);
8343 return _Ret{(__empty_tail
8344 ? ranges::begin(__first)
8345 : __detail::__cartesian_common_arg_end(__first)),
8346 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8347 }(make_index_sequence<sizeof...(_Vs)>{});
8349 return _Iterator<true>{*this, std::move(__its)};
8352 constexpr default_sentinel_t
8353 end() const noexcept
8354 { return default_sentinel; }
8357 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8359 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8360 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8361 auto __size = static_cast<_ST>(1);
8362#ifdef _GLIBCXX_ASSERTIONS
8363 if constexpr (integral<_ST>)
8366 = (__builtin_mul_overflow(__size,
8367 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8370 __glibcxx_assert(!__overflow);
8374 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8376 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8380 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8382 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8383 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8384 auto __size = static_cast<_ST>(1);
8385#ifdef _GLIBCXX_ASSERTIONS
8386 if constexpr (integral<_ST>)
8389 = (__builtin_mul_overflow(__size,
8390 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8393 __glibcxx_assert(!__overflow);
8397 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8399 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8403 template<typename... _Vs>
8404 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8406 template<input_range _First, forward_range... _Vs>
8407 requires (view<_First> && ... && view<_Vs>)
8408 template<bool _Const>
8409 class cartesian_product_view<_First, _Vs...>::_Iterator
8411 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8412 _Parent* _M_parent = nullptr;
8413 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8414 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8417 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8418 : _M_parent(std::__addressof(__parent)),
8419 _M_current(std::move(__current))
8425 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8426 return random_access_iterator_tag{};
8427 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8428 return bidirectional_iterator_tag{};
8429 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8430 return forward_iterator_tag{};
8432 return input_iterator_tag{};
8435 friend cartesian_product_view;
8438 using iterator_category = input_iterator_tag;
8439 using iterator_concept = decltype(_S_iter_concept());
8441 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8442 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8444 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8445 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8446 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8448 _Iterator() = default;
8451 _Iterator(_Iterator<!_Const> __i)
8453 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8454 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8455 : _M_parent(std::__addressof(__i._M_parent)),
8456 _M_current(std::move(__i._M_current))
8462 auto __f = [](auto& __i) -> decltype(auto) {
8465 return __detail::__tuple_transform(__f, _M_current);
8468 constexpr _Iterator&
8480 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8487 constexpr _Iterator&
8489 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8497 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8504 constexpr _Iterator&
8505 operator+=(difference_type __x)
8506 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8512 constexpr _Iterator&
8513 operator-=(difference_type __x)
8514 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8515 { return *this += -__x; }
8518 operator[](difference_type __n) const
8519 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8520 { return *((*this) + __n); }
8522 friend constexpr bool
8523 operator==(const _Iterator& __x, const _Iterator& __y)
8524 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8525 { return __x._M_current == __y._M_current; }
8527 friend constexpr bool
8528 operator==(const _Iterator& __x, default_sentinel_t)
8530 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8531 return ((std::get<_Is>(__x._M_current)
8532 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8534 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8537 friend constexpr auto
8538 operator<=>(const _Iterator& __x, const _Iterator& __y)
8539 requires __detail::__all_random_access<_Const, _First, _Vs...>
8540 { return __x._M_current <=> __y._M_current; }
8542 friend constexpr _Iterator
8543 operator+(_Iterator __x, difference_type __y)
8544 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8545 { return __x += __y; }
8547 friend constexpr _Iterator
8548 operator+(difference_type __x, _Iterator __y)
8549 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8550 { return __y += __x; }
8552 friend constexpr _Iterator
8553 operator-(_Iterator __x, difference_type __y)
8554 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8555 { return __x -= __y; }
8557 friend constexpr difference_type
8558 operator-(const _Iterator& __x, const _Iterator& __y)
8559 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8560 { return __x._M_distance_from(__y._M_current); }
8562 friend constexpr difference_type
8563 operator-(const _Iterator& __i, default_sentinel_t)
8564 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8566 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8567 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8568 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8569 }(make_index_sequence<sizeof...(_Vs)>{});
8570 return __i._M_distance_from(__end_tuple);
8573 friend constexpr difference_type
8574 operator-(default_sentinel_t, const _Iterator& __i)
8575 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8576 { return -(__i - default_sentinel); }
8578 friend constexpr auto
8579 iter_move(const _Iterator& __i)
8580 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8582 friend constexpr void
8583 iter_swap(const _Iterator& __l, const _Iterator& __r)
8584 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8586 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8588 [&]<size_t... _Is>(index_sequence<_Is...>) {
8589 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8590 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8594 template<size_t _Nm = sizeof...(_Vs)>
8598 auto& __it = std::get<_Nm>(_M_current);
8600 if constexpr (_Nm > 0)
8601 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8603 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8608 template<size_t _Nm = sizeof...(_Vs)>
8612 auto& __it = std::get<_Nm>(_M_current);
8613 if constexpr (_Nm > 0)
8614 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8616 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8622 template<size_t _Nm = sizeof...(_Vs)>
8624 _M_advance(difference_type __x)
8625 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8633 // Constant time iterator advancement.
8634 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8635 auto& __it = std::get<_Nm>(_M_current);
8636 if constexpr (_Nm == 0)
8638#ifdef _GLIBCXX_ASSERTIONS
8639 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8641 auto __size = ranges::ssize(__r);
8642 auto __begin = ranges::begin(__r);
8643 auto __offset = __it - __begin;
8644 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8651 auto __size = ranges::ssize(__r);
8652 auto __begin = ranges::begin(__r);
8653 auto __offset = __it - __begin;
8655 __x = __offset / __size;
8659 __offset = __size + __offset;
8662 __it = __begin + __offset;
8663 _M_advance<_Nm - 1>(__x);
8668 template<typename _Tuple>
8669 constexpr difference_type
8670 _M_distance_from(const _Tuple& __t) const
8672 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8673 auto __sum = static_cast<difference_type>(0);
8674#ifdef _GLIBCXX_ASSERTIONS
8675 if constexpr (integral<difference_type>)
8678 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8680 __glibcxx_assert(!__overflow);
8684 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8686 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8689 template<size_t _Nm, typename _Tuple>
8690 constexpr difference_type
8691 _M_scaled_distance(const _Tuple& __t) const
8693 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8694 - std::get<_Nm>(__t));
8695#ifdef _GLIBCXX_ASSERTIONS
8696 if constexpr (integral<difference_type>)
8698 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8699 __glibcxx_assert(!__overflow);
8703 __dist *= _M_scaled_size<_Nm+1>();
8707 template<size_t _Nm>
8708 constexpr difference_type
8709 _M_scaled_size() const
8711 if constexpr (_Nm <= sizeof...(_Vs))
8713 auto __size = static_cast<difference_type>(ranges::size
8714 (std::get<_Nm>(_M_parent->_M_bases)));
8715#ifdef _GLIBCXX_ASSERTIONS
8716 if constexpr (integral<difference_type>)
8718 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8719 __glibcxx_assert(!__overflow);
8723 __size *= _M_scaled_size<_Nm+1>();
8727 return static_cast<difference_type>(1);
8735 template<typename... _Ts>
8736 concept __can_cartesian_product_view
8737 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8740 struct _CartesianProduct
8742 template<typename... _Ts>
8743 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8745 operator() [[nodiscard]] (_Ts&&... __ts) const
8747 if constexpr (sizeof...(_Ts) == 0)
8748 return views::single(tuple{});
8750 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8754 inline constexpr _CartesianProduct cartesian_product;
8756#endif // __cpp_lib_ranges_cartesian_product
8758#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8759 template<input_range _Vp>
8761 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8763 _Vp _M_base = _Vp();
8766 as_rvalue_view() requires default_initializable<_Vp> = default;
8769 as_rvalue_view(_Vp __base)
8770 : _M_base(std::move(__base))
8774 base() const& requires copy_constructible<_Vp>
8779 { return std::move(_M_base); }
8782 begin() requires (!__detail::__simple_view<_Vp>)
8783 { return move_iterator(ranges::begin(_M_base)); }
8786 begin() const requires range<const _Vp>
8787 { return move_iterator(ranges::begin(_M_base)); }
8790 end() requires (!__detail::__simple_view<_Vp>)
8792 if constexpr (common_range<_Vp>)
8793 return move_iterator(ranges::end(_M_base));
8795 return move_sentinel(ranges::end(_M_base));
8799 end() const requires range<const _Vp>
8801 if constexpr (common_range<const _Vp>)
8802 return move_iterator(ranges::end(_M_base));
8804 return move_sentinel(ranges::end(_M_base));
8808 size() requires sized_range<_Vp>
8809 { return ranges::size(_M_base); }
8812 size() const requires sized_range<const _Vp>
8813 { return ranges::size(_M_base); }
8816 template<typename _Range>
8817 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8819 template<typename _Tp>
8820 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8821 = enable_borrowed_range<_Tp>;
8827 template<typename _Tp>
8828 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8831 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8833 template<viewable_range _Range>
8834 requires __detail::__can_as_rvalue_view<_Range>
8836 operator() [[nodiscard]] (_Range&& __r) const
8838 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8839 range_reference_t<_Range>>)
8840 return views::all(std::forward<_Range>(__r));
8842 return as_rvalue_view(std::forward<_Range>(__r));
8846 inline constexpr _AsRvalue as_rvalue;
8848#endif // __cpp_lib_as_rvalue
8850#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8853 template<typename _Range>
8854 concept __range_with_movable_reference = input_range<_Range>
8855 && move_constructible<range_reference_t<_Range>>
8856 && move_constructible<range_rvalue_reference_t<_Range>>;
8860 requires __detail::__range_with_movable_reference<_Vp>
8861 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8863 _Vp _M_base = _Vp();
8865 template<bool _Const> class _Iterator;
8866 template<bool _Const> class _Sentinel;
8869 enumerate_view() requires default_initializable<_Vp> = default;
8872 enumerate_view(_Vp __base)
8873 : _M_base(std::move(__base))
8877 begin() requires (!__detail::__simple_view<_Vp>)
8878 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8881 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8882 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8885 end() requires (!__detail::__simple_view<_Vp>)
8887 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8888 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8890 return _Sentinel<false>(ranges::end(_M_base));
8894 end() const requires __detail::__range_with_movable_reference<const _Vp>
8896 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8897 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8899 return _Sentinel<true>(ranges::end(_M_base));
8903 size() requires sized_range<_Vp>
8904 { return ranges::size(_M_base); }
8907 size() const requires sized_range<const _Vp>
8908 { return ranges::size(_M_base); }
8911 base() const & requires copy_constructible<_Vp>
8916 { return std::move(_M_base); }
8919 template<typename _Range>
8920 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
8922 template<typename _Tp>
8923 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
8924 = enable_borrowed_range<_Tp>;
8927 requires __detail::__range_with_movable_reference<_Vp>
8928 template<bool _Const>
8929 class enumerate_view<_Vp>::_Iterator
8931 using _Base = __maybe_const_t<_Const, _Vp>;
8936 if constexpr (random_access_range<_Base>)
8937 return random_access_iterator_tag{};
8938 else if constexpr (bidirectional_range<_Base>)
8939 return bidirectional_iterator_tag{};
8940 else if constexpr (forward_range<_Base>)
8941 return forward_iterator_tag{};
8943 return input_iterator_tag{};
8946 friend enumerate_view;
8949 using iterator_category = input_iterator_tag;
8950 using iterator_concept = decltype(_S_iter_concept());
8951 using difference_type = range_difference_t<_Base>;
8952 using value_type = tuple<difference_type, range_value_t<_Base>>;
8955 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
8957 iterator_t<_Base> _M_current = iterator_t<_Base>();
8958 difference_type _M_pos = 0;
8961 _Iterator(iterator_t<_Base> __current, difference_type __pos)
8962 : _M_current(std::move(__current)), _M_pos(__pos)
8966 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8969 _Iterator(_Iterator<!_Const> __i)
8970 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8971 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
8974 constexpr const iterator_t<_Base> &
8975 base() const & noexcept
8976 { return _M_current; }
8978 constexpr iterator_t<_Base>
8980 { return std::move(_M_current); }
8982 constexpr difference_type
8983 index() const noexcept
8988 { return __reference_type(_M_pos, *_M_current); }
8990 constexpr _Iterator&
9003 operator++(int) requires forward_range<_Base>
9010 constexpr _Iterator&
9011 operator--() requires bidirectional_range<_Base>
9019 operator--(int) requires bidirectional_range<_Base>
9026 constexpr _Iterator&
9027 operator+=(difference_type __n) requires random_access_range<_Base>
9034 constexpr _Iterator&
9035 operator-=(difference_type __n) requires random_access_range<_Base>
9043 operator[](difference_type __n) const requires random_access_range<_Base>
9044 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9046 friend constexpr bool
9047 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9048 { return __x._M_pos == __y._M_pos; }
9050 friend constexpr strong_ordering
9051 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9052 { return __x._M_pos <=> __y._M_pos; }
9054 friend constexpr _Iterator
9055 operator+(const _Iterator& __x, difference_type __y)
9056 requires random_access_range<_Base>
9057 { return (auto(__x) += __y); }
9059 friend constexpr _Iterator
9060 operator+(difference_type __x, const _Iterator& __y)
9061 requires random_access_range<_Base>
9062 { return auto(__y) += __x; }
9064 friend constexpr _Iterator
9065 operator-(const _Iterator& __x, difference_type __y)
9066 requires random_access_range<_Base>
9067 { return auto(__x) -= __y; }
9069 friend constexpr difference_type
9070 operator-(const _Iterator& __x, const _Iterator& __y)
9071 { return __x._M_pos - __y._M_pos; }
9073 friend constexpr auto
9074 iter_move(const _Iterator& __i)
9075 noexcept(noexcept(ranges::iter_move(__i._M_current))
9076 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9078 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9079 (__i._M_pos, ranges::iter_move(__i._M_current));
9084 requires __detail::__range_with_movable_reference<_Vp>
9085 template<bool _Const>
9086 class enumerate_view<_Vp>::_Sentinel
9088 using _Base = __maybe_const_t<_Const, _Vp>;
9090 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9093 _Sentinel(sentinel_t<_Base> __end)
9094 : _M_end(std::move(__end))
9097 friend enumerate_view;
9100 _Sentinel() = default;
9103 _Sentinel(_Sentinel<!_Const> __other)
9104 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9105 : _M_end(std::move(__other._M_end))
9108 constexpr sentinel_t<_Base>
9112 template<bool _OtherConst>
9113 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9114 friend constexpr bool
9115 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9116 { return __x._M_current == __y._M_end; }
9118 template<bool _OtherConst>
9119 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9120 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9121 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9122 { return __x._M_current - __y._M_end; }
9124 template<bool _OtherConst>
9125 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9126 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9127 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9128 { return __x._M_end - __y._M_current; }
9135 template<typename _Tp>
9136 concept __can_enumerate_view
9137 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9140 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9142 template<viewable_range _Range>
9143 requires __detail::__can_enumerate_view<_Range>
9145 operator() [[nodiscard]] (_Range&& __r) const
9146 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9149 inline constexpr _Enumerate enumerate;
9151#endif // __cpp_lib_ranges_enumerate
9153#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9155 requires input_range<_Vp>
9156 class as_const_view : public view_interface<as_const_view<_Vp>>
9158 _Vp _M_base = _Vp();
9161 as_const_view() requires default_initializable<_Vp> = default;
9164 as_const_view(_Vp __base)
9165 noexcept(is_nothrow_move_constructible_v<_Vp>)
9166 : _M_base(std::move(__base))
9171 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9172 requires copy_constructible<_Vp>
9177 noexcept(is_nothrow_move_constructible_v<_Vp>)
9178 { return std::move(_M_base); }
9181 begin() requires (!__detail::__simple_view<_Vp>)
9182 { return ranges::cbegin(_M_base); }
9185 begin() const requires range<const _Vp>
9186 { return ranges::cbegin(_M_base); }
9189 end() requires (!__detail::__simple_view<_Vp>)
9190 { return ranges::cend(_M_base); }
9193 end() const requires range<const _Vp>
9194 { return ranges::cend(_M_base); }
9197 size() requires sized_range<_Vp>
9198 { return ranges::size(_M_base); }
9201 size() const requires sized_range<const _Vp>
9202 { return ranges::size(_M_base); }
9205 template<typename _Range>
9206 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9208 template<typename _Tp>
9209 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9210 = enable_borrowed_range<_Tp>;
9216 template<typename _Tp>
9217 inline constexpr bool __is_ref_view = false;
9219 template<typename _Range>
9220 inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
9222 template<typename _Range>
9223 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9226 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9228 template<viewable_range _Range>
9230 operator()(_Range&& __r) const
9231 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9232 requires __detail::__can_as_const_view<_Range>
9234 using _Tp = remove_cvref_t<_Range>;
9235 using element_type = remove_reference_t<range_reference_t<_Range>>;
9236 if constexpr (constant_range<views::all_t<_Range>>)
9237 return views::all(std::forward<_Range>(__r));
9238 else if constexpr (__detail::__is_empty_view<_Tp>)
9239 return views::empty<const element_type>;
9240 else if constexpr (std::__detail::__is_span<_Tp>)
9241 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9242 else if constexpr (__detail::__is_ref_view<_Tp>
9243 && constant_range<const element_type>)
9244 return ref_view(static_cast<const element_type&>
9245 (std::forward<_Range>(__r).base()));
9246 else if constexpr (is_lvalue_reference_v<_Range>
9247 && constant_range<const _Tp>
9249 return ref_view(static_cast<const _Tp&>(__r));
9251 return as_const_view(std::forward<_Range>(__r));
9255 inline constexpr _AsConst as_const;
9257#endif // __cpp_lib_as_const
9258} // namespace ranges
9260 namespace views = ranges::views;
9262#if __cpp_lib_ranges_to_container // C++ >= 23
9265/// @cond undocumented
9268 template<typename _Container>
9269 constexpr bool __reservable_container
9270 = sized_range<_Container>
9271 && requires(_Container& __c, range_size_t<_Container> __n) {
9273 { __c.capacity() } -> same_as<decltype(__n)>;
9274 { __c.max_size() } -> same_as<decltype(__n)>;
9277 template<typename _Cont, typename _Range>
9278 constexpr bool __toable = requires {
9279 requires (!input_range<_Cont>
9280 || convertible_to<range_reference_t<_Range>,
9281 range_value_t<_Cont>>);
9283} // namespace __detail
9286 /// Convert a range to a container.
9288 * @tparam _Cont A container type.
9289 * @param __r A range that models the `input_range` concept.
9290 * @param __args... Arguments to pass to the container constructor.
9293 * This function converts a range to the `_Cont` type.
9295 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9296 * will convert the view to `std::vector<int>`.
9298 * Additional constructor arguments for the container can be supplied after
9299 * the input range argument, e.g.
9300 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9302 template<typename _Cont, input_range _Rg, typename... _Args>
9303 requires (!view<_Cont>)
9305 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9307 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9308 static_assert(is_class_v<_Cont>);
9310 if constexpr (__detail::__toable<_Cont, _Rg>)
9312 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9313 return _Cont(std::forward<_Rg>(__r),
9314 std::forward<_Args>(__args)...);
9315 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9316 return _Cont(from_range, std::forward<_Rg>(__r),
9317 std::forward<_Args>(__args)...);
9318 else if constexpr (requires { requires common_range<_Rg>;
9319 typename __iter_category_t<iterator_t<_Rg>>;
9320 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9321 input_iterator_tag>;
9322 requires constructible_from<_Cont, iterator_t<_Rg>,
9323 sentinel_t<_Rg>, _Args...>;
9325 return _Cont(ranges::begin(__r), ranges::end(__r),
9326 std::forward<_Args>(__args)...);
9329 using _RefT = range_reference_t<_Rg>;
9330 static_assert(constructible_from<_Cont, _Args...>);
9331 _Cont __c(std::forward<_Args>(__args)...);
9332 if constexpr (sized_range<_Rg>
9333 && __detail::__reservable_container<_Cont>)
9334 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9335 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9336 // 4016. container-insertable checks do not match what
9337 // container-inserter does
9338 auto __it = ranges::begin(__r);
9339 const auto __sent = ranges::end(__r);
9340 while (__it != __sent)
9342 if constexpr (requires { __c.emplace_back(*__it); })
9343 __c.emplace_back(*__it);
9344 else if constexpr (requires { __c.push_back(*__it); })
9345 __c.push_back(*__it);
9346 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9347 __c.emplace(__c.end(), *__it);
9349 __c.insert(__c.end(), *__it);
9357 static_assert(input_range<range_reference_t<_Rg>>);
9358 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9359 // 3984. ranges::to's recursion branch may be ill-formed
9360 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9361 []<typename _Elt>(_Elt&& __elem) {
9362 using _ValT = range_value_t<_Cont>;
9363 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9364 }), std::forward<_Args>(__args)...);
9368/// @cond undocumented
9371 template<typename _Rg>
9374 using iterator_category = input_iterator_tag;
9375 using value_type = range_value_t<_Rg>;
9376 using difference_type = ptrdiff_t;
9377 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9378 using reference = range_reference_t<_Rg>;
9379 reference operator*() const;
9380 pointer operator->() const;
9381 _InputIter& operator++();
9382 _InputIter operator++(int);
9383 bool operator==(const _InputIter&) const;
9386 template<template<typename...> typename _Cont, input_range _Rg,
9389 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9391 template<template<typename...> typename _Cont, input_range _Rg,
9394 = decltype(_Cont(from_range, std::declval<_Rg>(),
9395 std::declval<_Args>()...));
9397 template<template<typename...> typename _Cont, input_range _Rg,
9400 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9401 std::declval<_InputIter<_Rg>>(),
9402 std::declval<_Args>()...));
9404} // namespace __detail
9407 template<template<typename...> typename _Cont, input_range _Rg,
9410 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9412 using __detail::_DeduceExpr1;
9413 using __detail::_DeduceExpr2;
9414 using __detail::_DeduceExpr3;
9415 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9416 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9417 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9418 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9419 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9420 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9421 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9422 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9423 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9425 static_assert(false); // Cannot deduce container specialization.
9428/// @cond undocumented
9431 template<typename _Cont>
9434 template<typename _Range, typename... _Args>
9435 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9436 std::declval<_Args>()...); }
9438 operator()(_Range&& __r, _Args&&... __args) const
9440 return ranges::to<_Cont>(std::forward<_Range>(__r),
9441 std::forward<_Args>(__args)...);
9444} // namespace __detail
9447 /// ranges::to adaptor for converting a range to a container type
9449 * @tparam _Cont A container type.
9450 * @param __args... Arguments to pass to the container constructor.
9453 * This range adaptor returns a range adaptor closure object that converts
9454 * a range to the `_Cont` type.
9456 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9457 * will convert the view to `std::vector<int>`.
9459 * Additional constructor arguments for the container can be supplied, e.g.
9460 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9462 template<typename _Cont, typename... _Args>
9463 requires (!view<_Cont>)
9465 to [[nodiscard]] (_Args&&... __args)
9467 using __detail::_To;
9468 using views::__adaptor::_Partial;
9469 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9472/// @cond undocumented
9475 template<template<typename...> typename _Cont>
9478 template<typename _Range, typename... _Args>
9479 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9480 std::declval<_Args>()...); }
9482 operator()(_Range&& __r, _Args&&... __args) const
9484 return ranges::to<_Cont>(std::forward<_Range>(__r),
9485 std::forward<_Args>(__args)...);
9488} // namespace __detail
9491 /// ranges::to adaptor for converting a range to a deduced container type.
9493 * @tparam _Cont A container template.
9494 * @param __args... Arguments to pass to the container constructor.
9497 * This range adaptor returns a range adaptor closure object that converts
9498 * a range to a specialization of the `_Cont` class template. The specific
9499 * specialization of `_Cont` to be used is deduced automatically.
9501 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9502 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9503 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9505 * Additional constructor arguments for the container can be supplied, e.g.
9506 * `r | std::ranges::to<std::vector>(an_allocator)`.
9508 template<template<typename...> typename _Cont, typename... _Args>
9510 to [[nodiscard]] (_Args&&... __args)
9512 using __detail::_To2;
9513 using views::__adaptor::_Partial;
9514 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9517} // namespace ranges
9518#endif // __cpp_lib_ranges_to_container
9520_GLIBCXX_END_NAMESPACE_VERSION
9522#endif // library concepts
9524#endif /* _GLIBCXX_RANGES */