1 // <ranges> -*- C++ -*-
3 // Copyright (C) 2019-2022 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
39 #if __cpp_lib_concepts
42 #include <initializer_list>
47 #include <bits/ranges_util.h>
48 #include <bits/refwrap.h>
51 * @defgroup ranges Ranges
53 * Components for dealing with ranges of elements.
56 namespace std _GLIBCXX_VISIBILITY(default)
58 _GLIBCXX_BEGIN_NAMESPACE_VERSION
61 // [range.access] customization point objects
62 // [range.req] range and view concepts
63 // [range.dangling] dangling iterator handling
64 // Defined in <bits/ranges_base.h>
66 // [view.interface] View interface
67 // [range.subrange] Sub-ranges
68 // Defined in <bits/ranges_util.h>
70 // C++20 24.6 [range.factories] Range factories
72 /// A view that contains no elements.
73 template<typename _Tp> requires is_object_v<_Tp>
75 : public view_interface<empty_view<_Tp>>
78 static constexpr _Tp* begin() noexcept { return nullptr; }
79 static constexpr _Tp* end() noexcept { return nullptr; }
80 static constexpr _Tp* data() noexcept { return nullptr; }
81 static constexpr size_t size() noexcept { return 0; }
82 static constexpr bool empty() noexcept { return true; }
85 template<typename _Tp>
86 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
90 template<typename _Tp>
91 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
93 template<__boxable _Tp>
94 struct __box : std::optional<_Tp>
96 using std::optional<_Tp>::optional;
100 noexcept(is_nothrow_default_constructible_v<_Tp>)
101 requires default_initializable<_Tp>
102 : std::optional<_Tp>{std::in_place}
105 __box(const __box&) = default;
106 __box(__box&&) = default;
108 using std::optional<_Tp>::operator=;
110 // _GLIBCXX_RESOLVE_LIB_DEFECTS
111 // 3477. Simplify constraints for semiregular-box
112 // 3572. copyable-box should be fully constexpr
114 operator=(const __box& __that)
115 noexcept(is_nothrow_copy_constructible_v<_Tp>)
116 requires (!copyable<_Tp>)
118 if (this != std::__addressof(__that))
121 this->emplace(*__that);
129 operator=(__box&& __that)
130 noexcept(is_nothrow_move_constructible_v<_Tp>)
131 requires (!movable<_Tp>)
133 if (this != std::__addressof(__that))
136 this->emplace(std::move(*__that));
144 // For types which are already copyable, this specialization of the
145 // copyable wrapper stores the object directly without going through
146 // std::optional. It provides just the subset of the primary template's
147 // API that we currently use.
148 template<__boxable _Tp>
149 requires copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
150 && is_nothrow_copy_constructible_v<_Tp>)
154 [[no_unique_address]] _Tp _M_value = _Tp();
157 __box() requires default_initializable<_Tp> = default;
160 __box(const _Tp& __t)
161 noexcept(is_nothrow_copy_constructible_v<_Tp>)
167 noexcept(is_nothrow_move_constructible_v<_Tp>)
168 : _M_value(std::move(__t))
171 template<typename... _Args>
172 requires constructible_from<_Tp, _Args...>
174 __box(in_place_t, _Args&&... __args)
175 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
176 : _M_value(std::forward<_Args>(__args)...)
179 __box(const __box&) = default;
180 __box(__box&&) = default;
181 __box& operator=(const __box&) requires copyable<_Tp> = default;
182 __box& operator=(__box&&) requires copyable<_Tp> = default;
184 // When _Tp is nothrow_copy_constructible but not copy_assignable,
185 // copy assignment is implemented via destroy-then-copy-construct.
187 operator=(const __box& __that) noexcept
189 static_assert(is_nothrow_copy_constructible_v<_Tp>);
190 if (this != std::__addressof(__that))
193 std::construct_at(std::__addressof(_M_value), *__that);
198 // Likewise for move assignment.
200 operator=(__box&& __that) noexcept
202 static_assert(is_nothrow_move_constructible_v<_Tp>);
203 if (this != std::__addressof(__that))
206 std::construct_at(std::__addressof(_M_value), std::move(*__that));
212 has_value() const noexcept
220 operator*() const noexcept
224 operator->() noexcept
225 { return std::__addressof(_M_value); }
228 operator->() const noexcept
229 { return std::__addressof(_M_value); }
231 } // namespace __detail
233 /// A view that contains exactly one element.
234 template<copy_constructible _Tp> requires is_object_v<_Tp>
235 class single_view : public view_interface<single_view<_Tp>>
238 single_view() requires default_initializable<_Tp> = default;
241 single_view(const _Tp& __t)
242 noexcept(is_nothrow_copy_constructible_v<_Tp>)
247 single_view(_Tp&& __t)
248 noexcept(is_nothrow_move_constructible_v<_Tp>)
249 : _M_value(std::move(__t))
252 // _GLIBCXX_RESOLVE_LIB_DEFECTS
253 // 3428. single_view's in place constructor should be explicit
254 template<typename... _Args>
255 requires constructible_from<_Tp, _Args...>
257 single_view(in_place_t, _Args&&... __args)
258 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
259 : _M_value{in_place, std::forward<_Args>(__args)...}
267 begin() const noexcept
272 { return data() + 1; }
276 { return data() + 1; }
278 static constexpr size_t
284 { return _M_value.operator->(); }
287 data() const noexcept
288 { return _M_value.operator->(); }
291 [[no_unique_address]] __detail::__box<_Tp> _M_value;
294 template<typename _Tp>
295 single_view(_Tp) -> single_view<_Tp>;
299 template<typename _Wp>
300 constexpr auto __to_signed_like(_Wp __w) noexcept
302 if constexpr (!integral<_Wp>)
303 return iter_difference_t<_Wp>();
304 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
305 return iter_difference_t<_Wp>(__w);
306 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
307 return ptrdiff_t(__w);
308 else if constexpr (sizeof(long long) > sizeof(_Wp))
309 return (long long)(__w);
310 #ifdef __SIZEOF_INT128__
311 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
312 return __int128(__w);
315 return __max_diff_type(__w);
318 template<typename _Wp>
319 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
321 template<typename _It>
322 concept __decrementable = incrementable<_It>
325 { --__i } -> same_as<_It&>;
326 { __i-- } -> same_as<_It>;
329 template<typename _It>
330 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
331 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
333 { __i += __n } -> same_as<_It&>;
334 { __i -= __n } -> same_as<_It&>;
338 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
341 template<typename _Winc>
342 struct __iota_view_iter_cat
345 template<incrementable _Winc>
346 struct __iota_view_iter_cat<_Winc>
347 { using iterator_category = input_iterator_tag; };
348 } // namespace __detail
350 template<weakly_incrementable _Winc,
351 semiregular _Bound = unreachable_sentinel_t>
352 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
354 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
359 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
365 using namespace __detail;
366 if constexpr (__advanceable<_Winc>)
367 return random_access_iterator_tag{};
368 else if constexpr (__decrementable<_Winc>)
369 return bidirectional_iterator_tag{};
370 else if constexpr (incrementable<_Winc>)
371 return forward_iterator_tag{};
373 return input_iterator_tag{};
377 using iterator_concept = decltype(_S_iter_concept());
378 // iterator_category defined in __iota_view_iter_cat
379 using value_type = _Winc;
380 using difference_type = __detail::__iota_diff_t<_Winc>;
382 _Iterator() requires default_initializable<_Winc> = default;
385 _Iterator(_Winc __value)
386 : _M_value(__value) { }
389 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
404 operator++(int) requires incrementable<_Winc>
412 operator--() requires __detail::__decrementable<_Winc>
419 operator--(int) requires __detail::__decrementable<_Winc>
427 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
429 using __detail::__is_integer_like;
430 using __detail::__is_signed_integer_like;
431 if constexpr (__is_integer_like<_Winc>
432 && !__is_signed_integer_like<_Winc>)
434 if (__n >= difference_type(0))
435 _M_value += static_cast<_Winc>(__n);
437 _M_value -= static_cast<_Winc>(-__n);
445 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
447 using __detail::__is_integer_like;
448 using __detail::__is_signed_integer_like;
449 if constexpr (__is_integer_like<_Winc>
450 && !__is_signed_integer_like<_Winc>)
452 if (__n >= difference_type(0))
453 _M_value -= static_cast<_Winc>(__n);
455 _M_value += static_cast<_Winc>(-__n);
463 operator[](difference_type __n) const
464 requires __detail::__advanceable<_Winc>
465 { return _Winc(_M_value + __n); }
467 friend constexpr bool
468 operator==(const _Iterator& __x, const _Iterator& __y)
469 requires equality_comparable<_Winc>
470 { return __x._M_value == __y._M_value; }
472 friend constexpr bool
473 operator<(const _Iterator& __x, const _Iterator& __y)
474 requires totally_ordered<_Winc>
475 { return __x._M_value < __y._M_value; }
477 friend constexpr bool
478 operator>(const _Iterator& __x, const _Iterator& __y)
479 requires totally_ordered<_Winc>
480 { return __y < __x; }
482 friend constexpr bool
483 operator<=(const _Iterator& __x, const _Iterator& __y)
484 requires totally_ordered<_Winc>
485 { return !(__y < __x); }
487 friend constexpr bool
488 operator>=(const _Iterator& __x, const _Iterator& __y)
489 requires totally_ordered<_Winc>
490 { return !(__x < __y); }
492 #ifdef __cpp_lib_three_way_comparison
493 friend constexpr auto
494 operator<=>(const _Iterator& __x, const _Iterator& __y)
495 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
496 { return __x._M_value <=> __y._M_value; }
499 friend constexpr _Iterator
500 operator+(_Iterator __i, difference_type __n)
501 requires __detail::__advanceable<_Winc>
507 friend constexpr _Iterator
508 operator+(difference_type __n, _Iterator __i)
509 requires __detail::__advanceable<_Winc>
510 { return __i += __n; }
512 friend constexpr _Iterator
513 operator-(_Iterator __i, difference_type __n)
514 requires __detail::__advanceable<_Winc>
520 friend constexpr difference_type
521 operator-(const _Iterator& __x, const _Iterator& __y)
522 requires __detail::__advanceable<_Winc>
524 using __detail::__is_integer_like;
525 using __detail::__is_signed_integer_like;
526 using _Dt = difference_type;
527 if constexpr (__is_integer_like<_Winc>)
529 if constexpr (__is_signed_integer_like<_Winc>)
530 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
532 return (__y._M_value > __x._M_value)
533 ? _Dt(-_Dt(__y._M_value - __x._M_value))
534 : _Dt(__x._M_value - __y._M_value);
537 return __x._M_value - __y._M_value;
541 _Winc _M_value = _Winc();
551 _M_equal(const _Iterator& __x) const
552 { return __x._M_value == _M_bound; }
555 _M_distance_from(const _Iterator& __x) const
556 { return _M_bound - __x._M_value; }
558 _Bound _M_bound = _Bound();
561 _Sentinel() = default;
564 _Sentinel(_Bound __bound)
565 : _M_bound(__bound) { }
567 friend constexpr bool
568 operator==(const _Iterator& __x, const _Sentinel& __y)
569 { return __y._M_equal(__x); }
571 friend constexpr iter_difference_t<_Winc>
572 operator-(const _Iterator& __x, const _Sentinel& __y)
573 requires sized_sentinel_for<_Bound, _Winc>
574 { return -__y._M_distance_from(__x); }
576 friend constexpr iter_difference_t<_Winc>
577 operator-(const _Sentinel& __x, const _Iterator& __y)
578 requires sized_sentinel_for<_Bound, _Winc>
579 { return __x._M_distance_from(__y); }
584 _Winc _M_value = _Winc();
585 [[no_unique_address]] _Bound _M_bound = _Bound();
588 iota_view() requires default_initializable<_Winc> = default;
591 iota_view(_Winc __value)
596 iota_view(type_identity_t<_Winc> __value,
597 type_identity_t<_Bound> __bound)
598 : _M_value(__value), _M_bound(__bound)
600 if constexpr (totally_ordered_with<_Winc, _Bound>)
601 __glibcxx_assert( bool(__value <= __bound) );
605 iota_view(_Iterator __first, _Iterator __last)
606 requires same_as<_Winc, _Bound>
607 : iota_view(__first._M_value, __last._M_value)
611 iota_view(_Iterator __first, unreachable_sentinel_t __last)
612 requires same_as<_Bound, unreachable_sentinel_t>
613 : iota_view(__first._M_value, __last)
617 iota_view(_Iterator __first, _Sentinel __last)
618 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
619 : iota_view(__first._M_value, __last._M_bound)
623 begin() const { return _Iterator{_M_value}; }
628 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
629 return unreachable_sentinel;
631 return _Sentinel{_M_bound};
635 end() const requires same_as<_Winc, _Bound>
636 { return _Iterator{_M_bound}; }
640 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
641 || (integral<_Winc> && integral<_Bound>)
642 || sized_sentinel_for<_Bound, _Winc>
644 using __detail::__is_integer_like;
645 using __detail::__to_unsigned_like;
646 if constexpr (integral<_Winc> && integral<_Bound>)
648 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
649 return _Up(_M_bound) - _Up(_M_value);
651 else if constexpr (__is_integer_like<_Winc>)
652 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
654 return __to_unsigned_like(_M_bound - _M_value);
658 template<typename _Winc, typename _Bound>
659 requires (!__detail::__is_integer_like<_Winc>
660 || !__detail::__is_integer_like<_Bound>
661 || (__detail::__is_signed_integer_like<_Winc>
662 == __detail::__is_signed_integer_like<_Bound>))
663 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
665 template<typename _Winc, typename _Bound>
666 inline constexpr bool
667 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
671 template<typename _Tp>
672 inline constexpr empty_view<_Tp> empty{};
676 template<typename _Tp>
679 operator()(_Tp&& __e) const
680 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
681 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
684 inline constexpr _Single single{};
688 template<typename _Tp>
691 operator()(_Tp&& __e) const
692 { return iota_view(std::forward<_Tp>(__e)); }
694 template<typename _Tp, typename _Up>
697 operator()(_Tp&& __e, _Up&& __f) const
698 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
701 inline constexpr _Iota iota{};
706 template<typename _Val, typename _CharT, typename _Traits>
707 concept __stream_extractable
708 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
709 } // namespace __detail
711 template<movable _Val, typename _CharT,
712 typename _Traits = char_traits<_CharT>>
713 requires default_initializable<_Val>
714 && __detail::__stream_extractable<_Val, _CharT, _Traits>
715 class basic_istream_view
716 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
720 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
721 : _M_stream(std::__addressof(__stream))
727 *_M_stream >> _M_object;
728 return _Iterator{this};
731 constexpr default_sentinel_t
733 { return default_sentinel; }
736 basic_istream<_CharT, _Traits>* _M_stream;
737 _Val _M_object = _Val();
742 using iterator_concept = input_iterator_tag;
743 using difference_type = ptrdiff_t;
744 using value_type = _Val;
747 _Iterator(basic_istream_view* __parent) noexcept
748 : _M_parent(__parent)
751 _Iterator(const _Iterator&) = delete;
752 _Iterator(_Iterator&&) = default;
753 _Iterator& operator=(const _Iterator&) = delete;
754 _Iterator& operator=(_Iterator&&) = default;
759 *_M_parent->_M_stream >> _M_parent->_M_object;
769 { return _M_parent->_M_object; }
772 operator==(const _Iterator& __x, default_sentinel_t)
773 { return __x._M_at_end(); }
776 basic_istream_view* _M_parent;
780 { return !*_M_parent->_M_stream; }
786 template<typename _Val>
787 using istream_view = basic_istream_view<_Val, char>;
789 template<typename _Val>
790 using wistream_view = basic_istream_view<_Val, wchar_t>;
794 template<typename _Tp>
797 template<typename _CharT, typename _Traits>
800 operator()(basic_istream<_CharT, _Traits>& __e) const
801 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
804 template<typename _Tp>
805 inline constexpr _Istream<_Tp> istream;
808 // C++20 24.7 [range.adaptors] Range adaptors
814 // Alias for a type that is conditionally present
815 // (and is an empty type otherwise).
816 // Data members using this alias should use [[no_unique_address]] so that
817 // they take no space when not needed.
818 template<bool _Present, typename _Tp>
819 using __maybe_present_t = __conditional_t<_Present, _Tp, _Empty>;
821 // Alias for a type that is conditionally const.
822 template<bool _Const, typename _Tp>
823 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
825 } // namespace __detail
827 namespace views::__adaptor
829 // True if the range adaptor _Adaptor can be applied with _Args.
830 template<typename _Adaptor, typename... _Args>
831 concept __adaptor_invocable
832 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
834 // True if the range adaptor non-closure _Adaptor can be partially applied
836 template<typename _Adaptor, typename... _Args>
837 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
838 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
839 && (constructible_from<decay_t<_Args>, _Args> && ...);
841 template<typename _Adaptor, typename... _Args>
844 template<typename _Lhs, typename _Rhs>
847 // The base class of every range adaptor closure.
849 // The derived class should define the optional static data member
850 // _S_has_simple_call_op to true if the behavior of this adaptor is
851 // independent of the constness/value category of the adaptor object.
852 struct _RangeAdaptorClosure
854 // range | adaptor is equivalent to adaptor(range).
855 template<typename _Self, typename _Range>
856 requires derived_from<remove_cvref_t<_Self>, _RangeAdaptorClosure>
857 && __adaptor_invocable<_Self, _Range>
858 friend constexpr auto
859 operator|(_Range&& __r, _Self&& __self)
860 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
862 // Compose the adaptors __lhs and __rhs into a pipeline, returning
863 // another range adaptor closure object.
864 template<typename _Lhs, typename _Rhs>
865 requires derived_from<_Lhs, _RangeAdaptorClosure>
866 && derived_from<_Rhs, _RangeAdaptorClosure>
867 friend constexpr auto
868 operator|(_Lhs __lhs, _Rhs __rhs)
869 { return _Pipe<_Lhs, _Rhs>{std::move(__lhs), std::move(__rhs)}; }
872 // The base class of every range adaptor non-closure.
874 // The static data member _Derived::_S_arity must contain the total number of
875 // arguments that the adaptor takes, and the class _Derived must introduce
876 // _RangeAdaptor::operator() into the class scope via a using-declaration.
878 // The optional static data member _Derived::_S_has_simple_extra_args should
879 // be defined to true if the behavior of this adaptor is independent of the
880 // constness/value category of the extra arguments. This data member could
881 // also be defined as a variable template parameterized by the types of the
883 template<typename _Derived>
886 // Partially apply the arguments __args to the range adaptor _Derived,
887 // returning a range adaptor closure object.
888 template<typename... _Args>
889 requires __adaptor_partial_app_viable<_Derived, _Args...>
891 operator()(_Args&&... __args) const
893 return _Partial<_Derived, decay_t<_Args>...>{std::forward<_Args>(__args)...};
897 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
898 // one that's not overloaded according to constness or value category of the
900 template<typename _Adaptor>
901 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
903 // True if the behavior of the range adaptor non-closure _Adaptor is
904 // independent of the value category of its extra arguments _Args.
905 template<typename _Adaptor, typename... _Args>
906 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
907 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
909 // A range adaptor closure that represents partial application of
910 // the range adaptor _Adaptor with arguments _Args.
911 template<typename _Adaptor, typename... _Args>
912 struct _Partial : _RangeAdaptorClosure
914 tuple<_Args...> _M_args;
917 _Partial(_Args... __args)
918 : _M_args(std::move(__args)...)
921 // Invoke _Adaptor with arguments __r, _M_args... according to the
922 // value category of this _Partial object.
923 template<typename _Range>
924 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
926 operator()(_Range&& __r) const &
928 auto __forwarder = [&__r] (const auto&... __args) {
929 return _Adaptor{}(std::forward<_Range>(__r), __args...);
931 return std::apply(__forwarder, _M_args);
934 template<typename _Range>
935 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
937 operator()(_Range&& __r) &&
939 auto __forwarder = [&__r] (auto&... __args) {
940 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
942 return std::apply(__forwarder, _M_args);
945 template<typename _Range>
947 operator()(_Range&& __r) const && = delete;
950 // A lightweight specialization of the above primary template for
951 // the common case where _Adaptor accepts a single extra argument.
952 template<typename _Adaptor, typename _Arg>
953 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
959 : _M_arg(std::move(__arg))
962 template<typename _Range>
963 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
965 operator()(_Range&& __r) const &
966 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
968 template<typename _Range>
969 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
971 operator()(_Range&& __r) &&
972 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
974 template<typename _Range>
976 operator()(_Range&& __r) const && = delete;
979 // Partial specialization of the primary template for the case where the extra
980 // arguments of the adaptor can always be safely and efficiently forwarded by
981 // const reference. This lets us get away with a single operator() overload,
982 // which makes overload resolution failure diagnostics more concise.
983 template<typename _Adaptor, typename... _Args>
984 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
985 && (is_trivially_copyable_v<_Args> && ...)
986 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure
988 tuple<_Args...> _M_args;
991 _Partial(_Args... __args)
992 : _M_args(std::move(__args)...)
995 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
996 // of the value category of this _Partial object.
997 template<typename _Range>
998 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1000 operator()(_Range&& __r) const
1002 auto __forwarder = [&__r] (const auto&... __args) {
1003 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1005 return std::apply(__forwarder, _M_args);
1008 static constexpr bool _S_has_simple_call_op = true;
1011 // A lightweight specialization of the above template for the common case
1012 // where _Adaptor accepts a single extra argument.
1013 template<typename _Adaptor, typename _Arg>
1014 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1015 && is_trivially_copyable_v<_Arg>
1016 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
1021 _Partial(_Arg __arg)
1022 : _M_arg(std::move(__arg))
1025 template<typename _Range>
1026 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1028 operator()(_Range&& __r) const
1029 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1031 static constexpr bool _S_has_simple_call_op = true;
1034 template<typename _Lhs, typename _Rhs, typename _Range>
1035 concept __pipe_invocable
1036 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1038 // A range adaptor closure that represents composition of the range
1039 // adaptor closures _Lhs and _Rhs.
1040 template<typename _Lhs, typename _Rhs>
1041 struct _Pipe : _RangeAdaptorClosure
1043 [[no_unique_address]] _Lhs _M_lhs;
1044 [[no_unique_address]] _Rhs _M_rhs;
1047 _Pipe(_Lhs __lhs, _Rhs __rhs)
1048 : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
1051 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1052 // range adaptor closure object.
1053 template<typename _Range>
1054 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1056 operator()(_Range&& __r) const &
1057 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1059 template<typename _Range>
1060 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1062 operator()(_Range&& __r) &&
1063 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1065 template<typename _Range>
1067 operator()(_Range&& __r) const && = delete;
1070 // A partial specialization of the above primary template for the case where
1071 // both adaptor operands have a simple operator(). This in turn lets us
1072 // implement composition using a single simple operator(), which makes
1073 // overload resolution failure diagnostics more concise.
1074 template<typename _Lhs, typename _Rhs>
1075 requires __closure_has_simple_call_op<_Lhs>
1076 && __closure_has_simple_call_op<_Rhs>
1077 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure
1079 [[no_unique_address]] _Lhs _M_lhs;
1080 [[no_unique_address]] _Rhs _M_rhs;
1083 _Pipe(_Lhs __lhs, _Rhs __rhs)
1084 : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
1087 template<typename _Range>
1088 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1090 operator()(_Range&& __r) const
1091 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1093 static constexpr bool _S_has_simple_call_op = true;
1095 } // namespace views::__adaptor
1097 template<range _Range> requires is_object_v<_Range>
1098 class ref_view : public view_interface<ref_view<_Range>>
1103 static void _S_fun(_Range&); // not defined
1104 static void _S_fun(_Range&&) = delete;
1107 template<__detail::__different_from<ref_view> _Tp>
1108 requires convertible_to<_Tp, _Range&>
1109 && requires { _S_fun(declval<_Tp>()); }
1112 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1113 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1120 constexpr iterator_t<_Range>
1122 { return ranges::begin(*_M_r); }
1124 constexpr sentinel_t<_Range>
1126 { return ranges::end(*_M_r); }
1129 empty() const requires requires { ranges::empty(*_M_r); }
1130 { return ranges::empty(*_M_r); }
1133 size() const requires sized_range<_Range>
1134 { return ranges::size(*_M_r); }
1137 data() const requires contiguous_range<_Range>
1138 { return ranges::data(*_M_r); }
1141 template<typename _Range>
1142 ref_view(_Range&) -> ref_view<_Range>;
1144 template<typename _Tp>
1145 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1147 template<range _Range>
1148 requires movable<_Range>
1149 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1150 class owning_view : public view_interface<owning_view<_Range>>
1153 _Range _M_r = _Range();
1156 owning_view() requires default_initializable<_Range> = default;
1159 owning_view(_Range&& __t)
1160 noexcept(is_nothrow_move_constructible_v<_Range>)
1161 : _M_r(std::move(__t))
1164 owning_view(owning_view&&) = default;
1165 owning_view& operator=(owning_view&&) = default;
1171 constexpr const _Range&
1172 base() const& noexcept
1177 { return std::move(_M_r); }
1179 constexpr const _Range&&
1180 base() const&& noexcept
1181 { return std::move(_M_r); }
1183 constexpr iterator_t<_Range>
1185 { return ranges::begin(_M_r); }
1187 constexpr sentinel_t<_Range>
1189 { return ranges::end(_M_r); }
1192 begin() const requires range<const _Range>
1193 { return ranges::begin(_M_r); }
1196 end() const requires range<const _Range>
1197 { return ranges::end(_M_r); }
1200 empty() requires requires { ranges::empty(_M_r); }
1201 { return ranges::empty(_M_r); }
1204 empty() const requires requires { ranges::empty(_M_r); }
1205 { return ranges::empty(_M_r); }
1208 size() requires sized_range<_Range>
1209 { return ranges::size(_M_r); }
1212 size() const requires sized_range<const _Range>
1213 { return ranges::size(_M_r); }
1216 data() requires contiguous_range<_Range>
1217 { return ranges::data(_M_r); }
1220 data() const requires contiguous_range<const _Range>
1221 { return ranges::data(_M_r); }
1224 template<typename _Tp>
1225 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1226 = enable_borrowed_range<_Tp>;
1232 template<typename _Range>
1233 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1235 template<typename _Range>
1236 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1237 } // namespace __detail
1239 struct _All : __adaptor::_RangeAdaptorClosure
1241 template<typename _Range>
1242 static constexpr bool
1245 if constexpr (view<decay_t<_Range>>)
1246 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1247 else if constexpr (__detail::__can_ref_view<_Range>)
1250 return noexcept(owning_view{std::declval<_Range>()});
1253 template<viewable_range _Range>
1254 requires view<decay_t<_Range>>
1255 || __detail::__can_ref_view<_Range>
1256 || __detail::__can_owning_view<_Range>
1258 operator() [[nodiscard]] (_Range&& __r) const
1259 noexcept(_S_noexcept<_Range>())
1261 if constexpr (view<decay_t<_Range>>)
1262 return std::forward<_Range>(__r);
1263 else if constexpr (__detail::__can_ref_view<_Range>)
1264 return ref_view{std::forward<_Range>(__r)};
1266 return owning_view{std::forward<_Range>(__r)};
1269 static constexpr bool _S_has_simple_call_op = true;
1272 inline constexpr _All all;
1274 template<viewable_range _Range>
1275 using all_t = decltype(all(std::declval<_Range>()));
1276 } // namespace views
1280 template<typename _Tp>
1281 struct __non_propagating_cache
1283 // When _Tp is not an object type (e.g. is a reference type), we make
1284 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1285 // users can easily conditionally declare data members with this type
1286 // (such as join_view::_M_inner).
1289 template<typename _Tp>
1290 requires is_object_v<_Tp>
1291 struct __non_propagating_cache<_Tp>
1292 : protected _Optional_base<_Tp>
1294 __non_propagating_cache() = default;
1297 __non_propagating_cache(const __non_propagating_cache&) noexcept
1301 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1302 { __other._M_reset(); }
1304 constexpr __non_propagating_cache&
1305 operator=(const __non_propagating_cache& __other) noexcept
1307 if (std::__addressof(__other) != this)
1312 constexpr __non_propagating_cache&
1313 operator=(__non_propagating_cache&& __other) noexcept
1320 constexpr __non_propagating_cache&
1321 operator=(_Tp __val)
1324 this->_M_payload._M_construct(std::move(__val));
1329 operator bool() const noexcept
1330 { return this->_M_is_engaged(); }
1333 operator*() noexcept
1334 { return this->_M_get(); }
1336 constexpr const _Tp&
1337 operator*() const noexcept
1338 { return this->_M_get(); }
1340 template<typename _Iter>
1342 _M_emplace_deref(const _Iter& __i)
1345 auto __f = [] (auto& __x) { return *__x; };
1346 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1347 return this->_M_get();
1351 template<range _Range>
1352 struct _CachedPosition
1355 _M_has_value() const
1358 constexpr iterator_t<_Range>
1359 _M_get(const _Range&) const
1361 __glibcxx_assert(false);
1362 __builtin_unreachable();
1366 _M_set(const _Range&, const iterator_t<_Range>&) const
1370 template<forward_range _Range>
1371 struct _CachedPosition<_Range>
1372 : protected __non_propagating_cache<iterator_t<_Range>>
1375 _M_has_value() const
1376 { return this->_M_is_engaged(); }
1378 constexpr iterator_t<_Range>
1379 _M_get(const _Range&) const
1381 __glibcxx_assert(_M_has_value());
1386 _M_set(const _Range&, const iterator_t<_Range>& __it)
1388 __glibcxx_assert(!_M_has_value());
1389 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1391 this->_M_payload._M_engaged = true;
1395 template<random_access_range _Range>
1396 requires (sizeof(range_difference_t<_Range>)
1397 <= sizeof(iterator_t<_Range>))
1398 struct _CachedPosition<_Range>
1401 range_difference_t<_Range> _M_offset = -1;
1404 _CachedPosition() = default;
1407 _CachedPosition(const _CachedPosition&) = default;
1410 _CachedPosition(_CachedPosition&& __other) noexcept
1411 { *this = std::move(__other); }
1413 constexpr _CachedPosition&
1414 operator=(const _CachedPosition&) = default;
1416 constexpr _CachedPosition&
1417 operator=(_CachedPosition&& __other) noexcept
1419 // Propagate the cached offset, but invalidate the source.
1420 _M_offset = __other._M_offset;
1421 __other._M_offset = -1;
1426 _M_has_value() const
1427 { return _M_offset >= 0; }
1429 constexpr iterator_t<_Range>
1430 _M_get(_Range& __r) const
1432 __glibcxx_assert(_M_has_value());
1433 return ranges::begin(__r) + _M_offset;
1437 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1439 __glibcxx_assert(!_M_has_value());
1440 _M_offset = __it - ranges::begin(__r);
1443 } // namespace __detail
1447 template<typename _Base>
1448 struct __filter_view_iter_cat
1451 template<forward_range _Base>
1452 struct __filter_view_iter_cat<_Base>
1458 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1459 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1460 return bidirectional_iterator_tag{};
1461 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1462 return forward_iterator_tag{};
1467 using iterator_category = decltype(_S_iter_cat());
1469 } // namespace __detail
1471 template<input_range _Vp,
1472 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1473 requires view<_Vp> && is_object_v<_Pred>
1474 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1479 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1482 static constexpr auto
1485 if constexpr (bidirectional_range<_Vp>)
1486 return bidirectional_iterator_tag{};
1487 else if constexpr (forward_range<_Vp>)
1488 return forward_iterator_tag{};
1490 return input_iterator_tag{};
1495 using _Vp_iter = iterator_t<_Vp>;
1497 _Vp_iter _M_current = _Vp_iter();
1498 filter_view* _M_parent = nullptr;
1501 using iterator_concept = decltype(_S_iter_concept());
1502 // iterator_category defined in __filter_view_iter_cat
1503 using value_type = range_value_t<_Vp>;
1504 using difference_type = range_difference_t<_Vp>;
1506 _Iterator() requires default_initializable<_Vp_iter> = default;
1509 _Iterator(filter_view* __parent, _Vp_iter __current)
1510 : _M_current(std::move(__current)),
1514 constexpr const _Vp_iter&
1515 base() const & noexcept
1516 { return _M_current; }
1520 { return std::move(_M_current); }
1522 constexpr range_reference_t<_Vp>
1524 { return *_M_current; }
1528 requires __detail::__has_arrow<_Vp_iter>
1529 && copyable<_Vp_iter>
1530 { return _M_current; }
1532 constexpr _Iterator&
1535 _M_current = ranges::find_if(std::move(++_M_current),
1536 ranges::end(_M_parent->_M_base),
1537 std::ref(*_M_parent->_M_pred));
1546 operator++(int) requires forward_range<_Vp>
1553 constexpr _Iterator&
1554 operator--() requires bidirectional_range<_Vp>
1558 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1563 operator--(int) requires bidirectional_range<_Vp>
1570 friend constexpr bool
1571 operator==(const _Iterator& __x, const _Iterator& __y)
1572 requires equality_comparable<_Vp_iter>
1573 { return __x._M_current == __y._M_current; }
1575 friend constexpr range_rvalue_reference_t<_Vp>
1576 iter_move(const _Iterator& __i)
1577 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1578 { return ranges::iter_move(__i._M_current); }
1580 friend constexpr void
1581 iter_swap(const _Iterator& __x, const _Iterator& __y)
1582 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1583 requires indirectly_swappable<_Vp_iter>
1584 { ranges::iter_swap(__x._M_current, __y._M_current); }
1590 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1593 __equal(const _Iterator& __i) const
1594 { return __i._M_current == _M_end; }
1597 _Sentinel() = default;
1600 _Sentinel(filter_view* __parent)
1601 : _M_end(ranges::end(__parent->_M_base))
1604 constexpr sentinel_t<_Vp>
1608 friend constexpr bool
1609 operator==(const _Iterator& __x, const _Sentinel& __y)
1610 { return __y.__equal(__x); }
1613 _Vp _M_base = _Vp();
1614 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1615 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1618 filter_view() requires (default_initializable<_Vp>
1619 && default_initializable<_Pred>)
1623 filter_view(_Vp __base, _Pred __pred)
1624 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1628 base() const& requires copy_constructible<_Vp>
1633 { return std::move(_M_base); }
1635 constexpr const _Pred&
1637 { return *_M_pred; }
1642 if (_M_cached_begin._M_has_value())
1643 return {this, _M_cached_begin._M_get(_M_base)};
1645 __glibcxx_assert(_M_pred.has_value());
1646 auto __it = ranges::find_if(ranges::begin(_M_base),
1647 ranges::end(_M_base),
1648 std::ref(*_M_pred));
1649 _M_cached_begin._M_set(_M_base, __it);
1650 return {this, std::move(__it)};
1656 if constexpr (common_range<_Vp>)
1657 return _Iterator{this, ranges::end(_M_base)};
1659 return _Sentinel{this};
1663 template<typename _Range, typename _Pred>
1664 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1670 template<typename _Range, typename _Pred>
1671 concept __can_filter_view
1672 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1673 } // namespace __detail
1675 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1677 template<viewable_range _Range, typename _Pred>
1678 requires __detail::__can_filter_view<_Range, _Pred>
1680 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1682 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1685 using _RangeAdaptor<_Filter>::operator();
1686 static constexpr int _S_arity = 2;
1687 static constexpr bool _S_has_simple_extra_args = true;
1690 inline constexpr _Filter filter;
1691 } // namespace views
1693 template<input_range _Vp, copy_constructible _Fp>
1694 requires view<_Vp> && is_object_v<_Fp>
1695 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1696 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1697 range_reference_t<_Vp>>>
1698 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1701 template<bool _Const>
1702 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1704 template<bool _Const>
1708 template<bool _Const>
1709 requires forward_range<_Base<_Const>>
1710 struct __iter_cat<_Const>
1716 using _Base = transform_view::_Base<_Const>;
1717 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1718 if constexpr (is_lvalue_reference_v<_Res>)
1721 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1722 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1723 return random_access_iterator_tag{};
1728 return input_iterator_tag{};
1731 using iterator_category = decltype(_S_iter_cat());
1734 template<bool _Const>
1737 template<bool _Const>
1738 struct _Iterator : __iter_cat<_Const>
1741 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1742 using _Base = transform_view::_Base<_Const>;
1747 if constexpr (random_access_range<_Base>)
1748 return random_access_iterator_tag{};
1749 else if constexpr (bidirectional_range<_Base>)
1750 return bidirectional_iterator_tag{};
1751 else if constexpr (forward_range<_Base>)
1752 return forward_iterator_tag{};
1754 return input_iterator_tag{};
1757 using _Base_iter = iterator_t<_Base>;
1759 _Base_iter _M_current = _Base_iter();
1760 _Parent* _M_parent = nullptr;
1763 using iterator_concept = decltype(_S_iter_concept());
1764 // iterator_category defined in __transform_view_iter_cat
1766 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1767 using difference_type = range_difference_t<_Base>;
1769 _Iterator() requires default_initializable<_Base_iter> = default;
1772 _Iterator(_Parent* __parent, _Base_iter __current)
1773 : _M_current(std::move(__current)),
1778 _Iterator(_Iterator<!_Const> __i)
1780 && convertible_to<iterator_t<_Vp>, _Base_iter>
1781 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1784 constexpr const _Base_iter&
1785 base() const & noexcept
1786 { return _M_current; }
1788 constexpr _Base_iter
1790 { return std::move(_M_current); }
1792 constexpr decltype(auto)
1794 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1795 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1797 constexpr _Iterator&
1809 operator++(int) requires forward_range<_Base>
1816 constexpr _Iterator&
1817 operator--() requires bidirectional_range<_Base>
1824 operator--(int) requires bidirectional_range<_Base>
1831 constexpr _Iterator&
1832 operator+=(difference_type __n) requires random_access_range<_Base>
1838 constexpr _Iterator&
1839 operator-=(difference_type __n) requires random_access_range<_Base>
1845 constexpr decltype(auto)
1846 operator[](difference_type __n) const
1847 requires random_access_range<_Base>
1848 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1850 friend constexpr bool
1851 operator==(const _Iterator& __x, const _Iterator& __y)
1852 requires equality_comparable<_Base_iter>
1853 { return __x._M_current == __y._M_current; }
1855 friend constexpr bool
1856 operator<(const _Iterator& __x, const _Iterator& __y)
1857 requires random_access_range<_Base>
1858 { return __x._M_current < __y._M_current; }
1860 friend constexpr bool
1861 operator>(const _Iterator& __x, const _Iterator& __y)
1862 requires random_access_range<_Base>
1863 { return __y < __x; }
1865 friend constexpr bool
1866 operator<=(const _Iterator& __x, const _Iterator& __y)
1867 requires random_access_range<_Base>
1868 { return !(__y < __x); }
1870 friend constexpr bool
1871 operator>=(const _Iterator& __x, const _Iterator& __y)
1872 requires random_access_range<_Base>
1873 { return !(__x < __y); }
1875 #ifdef __cpp_lib_three_way_comparison
1876 friend constexpr auto
1877 operator<=>(const _Iterator& __x, const _Iterator& __y)
1878 requires random_access_range<_Base>
1879 && three_way_comparable<_Base_iter>
1880 { return __x._M_current <=> __y._M_current; }
1883 friend constexpr _Iterator
1884 operator+(_Iterator __i, difference_type __n)
1885 requires random_access_range<_Base>
1886 { return {__i._M_parent, __i._M_current + __n}; }
1888 friend constexpr _Iterator
1889 operator+(difference_type __n, _Iterator __i)
1890 requires random_access_range<_Base>
1891 { return {__i._M_parent, __i._M_current + __n}; }
1893 friend constexpr _Iterator
1894 operator-(_Iterator __i, difference_type __n)
1895 requires random_access_range<_Base>
1896 { return {__i._M_parent, __i._M_current - __n}; }
1898 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1899 // 3483. transform_view::iterator's difference is overconstrained
1900 friend constexpr difference_type
1901 operator-(const _Iterator& __x, const _Iterator& __y)
1902 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
1903 { return __x._M_current - __y._M_current; }
1905 friend constexpr decltype(auto)
1906 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
1908 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
1909 return std::move(*__i);
1914 friend _Iterator<!_Const>;
1915 template<bool> friend struct _Sentinel;
1918 template<bool _Const>
1922 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1923 using _Base = transform_view::_Base<_Const>;
1925 template<bool _Const2>
1927 __distance_from(const _Iterator<_Const2>& __i) const
1928 { return _M_end - __i._M_current; }
1930 template<bool _Const2>
1932 __equal(const _Iterator<_Const2>& __i) const
1933 { return __i._M_current == _M_end; }
1935 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1938 _Sentinel() = default;
1941 _Sentinel(sentinel_t<_Base> __end)
1946 _Sentinel(_Sentinel<!_Const> __i)
1948 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1949 : _M_end(std::move(__i._M_end))
1952 constexpr sentinel_t<_Base>
1956 template<bool _Const2>
1957 requires sentinel_for<sentinel_t<_Base>,
1958 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
1959 friend constexpr bool
1960 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1961 { return __y.__equal(__x); }
1963 template<bool _Const2,
1964 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1965 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1966 friend constexpr range_difference_t<_Base2>
1967 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1968 { return -__y.__distance_from(__x); }
1970 template<bool _Const2,
1971 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1972 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1973 friend constexpr range_difference_t<_Base2>
1974 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
1975 { return __y.__distance_from(__x); }
1977 friend _Sentinel<!_Const>;
1980 _Vp _M_base = _Vp();
1981 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
1984 transform_view() requires (default_initializable<_Vp>
1985 && default_initializable<_Fp>)
1989 transform_view(_Vp __base, _Fp __fun)
1990 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
1994 base() const& requires copy_constructible<_Vp>
1995 { return _M_base ; }
1999 { return std::move(_M_base); }
2001 constexpr _Iterator<false>
2003 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2005 constexpr _Iterator<true>
2007 requires range<const _Vp>
2008 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2009 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2011 constexpr _Sentinel<false>
2013 { return _Sentinel<false>{ranges::end(_M_base)}; }
2015 constexpr _Iterator<false>
2016 end() requires common_range<_Vp>
2017 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2019 constexpr _Sentinel<true>
2021 requires range<const _Vp>
2022 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2023 { return _Sentinel<true>{ranges::end(_M_base)}; }
2025 constexpr _Iterator<true>
2027 requires common_range<const _Vp>
2028 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2029 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2032 size() requires sized_range<_Vp>
2033 { return ranges::size(_M_base); }
2036 size() const requires sized_range<const _Vp>
2037 { return ranges::size(_M_base); }
2040 template<typename _Range, typename _Fp>
2041 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2047 template<typename _Range, typename _Fp>
2048 concept __can_transform_view
2049 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2050 } // namespace __detail
2052 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2054 template<viewable_range _Range, typename _Fp>
2055 requires __detail::__can_transform_view<_Range, _Fp>
2057 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2059 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2062 using _RangeAdaptor<_Transform>::operator();
2063 static constexpr int _S_arity = 2;
2064 static constexpr bool _S_has_simple_extra_args = true;
2067 inline constexpr _Transform transform;
2068 } // namespace views
2071 class take_view : public view_interface<take_view<_Vp>>
2074 template<bool _Const>
2075 using _CI = counted_iterator<
2076 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2078 template<bool _Const>
2082 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2083 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2086 _Sentinel() = default;
2089 _Sentinel(sentinel_t<_Base> __end)
2094 _Sentinel(_Sentinel<!_Const> __s)
2095 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2096 : _M_end(std::move(__s._M_end))
2099 constexpr sentinel_t<_Base>
2103 friend constexpr bool
2104 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2105 { return __y.count() == 0 || __y.base() == __x._M_end; }
2107 template<bool _OtherConst = !_Const,
2108 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2109 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2110 friend constexpr bool
2111 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2112 { return __y.count() == 0 || __y.base() == __x._M_end; }
2114 friend _Sentinel<!_Const>;
2117 _Vp _M_base = _Vp();
2118 range_difference_t<_Vp> _M_count = 0;
2121 take_view() requires default_initializable<_Vp> = default;
2124 take_view(_Vp base, range_difference_t<_Vp> __count)
2125 : _M_base(std::move(base)), _M_count(std::move(__count))
2129 base() const& requires copy_constructible<_Vp>
2134 { return std::move(_M_base); }
2137 begin() requires (!__detail::__simple_view<_Vp>)
2139 if constexpr (sized_range<_Vp>)
2141 if constexpr (random_access_range<_Vp>)
2142 return ranges::begin(_M_base);
2146 return counted_iterator(ranges::begin(_M_base), __sz);
2150 return counted_iterator(ranges::begin(_M_base), _M_count);
2154 begin() const requires range<const _Vp>
2156 if constexpr (sized_range<const _Vp>)
2158 if constexpr (random_access_range<const _Vp>)
2159 return ranges::begin(_M_base);
2163 return counted_iterator(ranges::begin(_M_base), __sz);
2167 return counted_iterator(ranges::begin(_M_base), _M_count);
2171 end() requires (!__detail::__simple_view<_Vp>)
2173 if constexpr (sized_range<_Vp>)
2175 if constexpr (random_access_range<_Vp>)
2176 return ranges::begin(_M_base) + size();
2178 return default_sentinel;
2181 return _Sentinel<false>{ranges::end(_M_base)};
2185 end() const requires range<const _Vp>
2187 if constexpr (sized_range<const _Vp>)
2189 if constexpr (random_access_range<const _Vp>)
2190 return ranges::begin(_M_base) + size();
2192 return default_sentinel;
2195 return _Sentinel<true>{ranges::end(_M_base)};
2199 size() requires sized_range<_Vp>
2201 auto __n = ranges::size(_M_base);
2202 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2206 size() const requires sized_range<const _Vp>
2208 auto __n = ranges::size(_M_base);
2209 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2213 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2214 // 3447. Deduction guides for take_view and drop_view have different
2216 template<typename _Range>
2217 take_view(_Range&&, range_difference_t<_Range>)
2218 -> take_view<views::all_t<_Range>>;
2220 template<typename _Tp>
2221 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2222 = enable_borrowed_range<_Tp>;
2228 template<typename _Range>
2229 inline constexpr bool __is_empty_view = false;
2231 template<typename _Tp>
2232 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2234 template<typename _Range>
2235 inline constexpr bool __is_basic_string_view = false;
2237 template<typename _CharT, typename _Traits>
2238 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2241 template<typename _Range>
2242 inline constexpr bool __is_subrange = false;
2244 template<typename _Iter, typename _Sent, subrange_kind _Kind>
2245 inline constexpr bool __is_subrange<subrange<_Iter, _Sent, _Kind>> = true;
2247 template<typename _Range>
2248 inline constexpr bool __is_iota_view = false;
2250 template<typename _Winc, typename _Bound>
2251 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2253 template<typename _Range, typename _Dp>
2254 concept __can_take_view
2255 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2256 } // namespace __detail
2258 struct _Take : __adaptor::_RangeAdaptor<_Take>
2260 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2261 requires __detail::__can_take_view<_Range, _Dp>
2263 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2265 using _Tp = remove_cvref_t<_Range>;
2266 if constexpr (__detail::__is_empty_view<_Tp>)
2268 else if constexpr (random_access_range<_Tp>
2270 && (std::__detail::__is_span<_Tp>
2271 || __detail::__is_basic_string_view<_Tp>
2272 || __detail::__is_subrange<_Tp>
2273 || __detail::__is_iota_view<_Tp>))
2275 __n = std::min<_Dp>(ranges::distance(__r), __n);
2276 auto __begin = ranges::begin(__r);
2277 auto __end = __begin + __n;
2278 if constexpr (std::__detail::__is_span<_Tp>)
2279 return span<typename _Tp::element_type>(__begin, __end);
2280 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2281 return _Tp(__begin, __end);
2282 else if constexpr (__detail::__is_subrange<_Tp>)
2283 return subrange<iterator_t<_Tp>>(__begin, __end);
2285 return iota_view(*__begin, *__end);
2288 return take_view(std::forward<_Range>(__r), __n);
2291 using _RangeAdaptor<_Take>::operator();
2292 static constexpr int _S_arity = 2;
2293 // The count argument of views::take is not always simple -- it can be
2294 // e.g. a move-only class that's implicitly convertible to the difference
2295 // type. But an integer-like count argument is surely simple.
2296 template<typename _Tp>
2297 static constexpr bool _S_has_simple_extra_args
2298 = ranges::__detail::__is_integer_like<_Tp>;
2301 inline constexpr _Take take;
2302 } // namespace views
2304 template<view _Vp, typename _Pred>
2305 requires input_range<_Vp> && is_object_v<_Pred>
2306 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2307 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2309 template<bool _Const>
2313 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2315 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2316 const _Pred* _M_pred = nullptr;
2319 _Sentinel() = default;
2322 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2323 : _M_end(__end), _M_pred(__pred)
2327 _Sentinel(_Sentinel<!_Const> __s)
2328 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2329 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2332 constexpr sentinel_t<_Base>
2333 base() const { return _M_end; }
2335 friend constexpr bool
2336 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2337 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2339 template<bool _OtherConst = !_Const,
2340 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2341 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2342 friend constexpr bool
2343 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2344 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2346 friend _Sentinel<!_Const>;
2349 _Vp _M_base = _Vp();
2350 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2353 take_while_view() requires (default_initializable<_Vp>
2354 && default_initializable<_Pred>)
2358 take_while_view(_Vp base, _Pred __pred)
2359 : _M_base(std::move(base)), _M_pred(std::move(__pred))
2363 base() const& requires copy_constructible<_Vp>
2368 { return std::move(_M_base); }
2370 constexpr const _Pred&
2372 { return *_M_pred; }
2375 begin() requires (!__detail::__simple_view<_Vp>)
2376 { return ranges::begin(_M_base); }
2379 begin() const requires range<const _Vp>
2380 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2381 { return ranges::begin(_M_base); }
2384 end() requires (!__detail::__simple_view<_Vp>)
2385 { return _Sentinel<false>(ranges::end(_M_base),
2386 std::__addressof(*_M_pred)); }
2389 end() const requires range<const _Vp>
2390 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2391 { return _Sentinel<true>(ranges::end(_M_base),
2392 std::__addressof(*_M_pred)); }
2395 template<typename _Range, typename _Pred>
2396 take_while_view(_Range&&, _Pred)
2397 -> take_while_view<views::all_t<_Range>, _Pred>;
2403 template<typename _Range, typename _Pred>
2404 concept __can_take_while_view
2405 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2406 } // namespace __detail
2408 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2410 template<viewable_range _Range, typename _Pred>
2411 requires __detail::__can_take_while_view<_Range, _Pred>
2413 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2415 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2418 using _RangeAdaptor<_TakeWhile>::operator();
2419 static constexpr int _S_arity = 2;
2420 static constexpr bool _S_has_simple_extra_args = true;
2423 inline constexpr _TakeWhile take_while;
2424 } // namespace views
2427 class drop_view : public view_interface<drop_view<_Vp>>
2430 _Vp _M_base = _Vp();
2431 range_difference_t<_Vp> _M_count = 0;
2433 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2434 // both random_access_range and sized_range. Otherwise, cache its result.
2435 static constexpr bool _S_needs_cached_begin
2436 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2437 [[no_unique_address]]
2438 __detail::__maybe_present_t<_S_needs_cached_begin,
2439 __detail::_CachedPosition<_Vp>>
2443 drop_view() requires default_initializable<_Vp> = default;
2446 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2447 : _M_base(std::move(__base)), _M_count(__count)
2448 { __glibcxx_assert(__count >= 0); }
2451 base() const& requires copy_constructible<_Vp>
2456 { return std::move(_M_base); }
2458 // This overload is disabled for simple views with constant-time begin().
2461 requires (!(__detail::__simple_view<_Vp>
2462 && random_access_range<const _Vp>
2463 && sized_range<const _Vp>))
2465 if constexpr (_S_needs_cached_begin)
2466 if (_M_cached_begin._M_has_value())
2467 return _M_cached_begin._M_get(_M_base);
2469 auto __it = ranges::next(ranges::begin(_M_base),
2470 _M_count, ranges::end(_M_base));
2471 if constexpr (_S_needs_cached_begin)
2472 _M_cached_begin._M_set(_M_base, __it);
2476 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2477 // 3482. drop_view's const begin should additionally require sized_range
2480 requires random_access_range<const _Vp> && sized_range<const _Vp>
2482 return ranges::next(ranges::begin(_M_base), _M_count,
2483 ranges::end(_M_base));
2487 end() requires (!__detail::__simple_view<_Vp>)
2488 { return ranges::end(_M_base); }
2491 end() const requires range<const _Vp>
2492 { return ranges::end(_M_base); }
2495 size() requires sized_range<_Vp>
2497 const auto __s = ranges::size(_M_base);
2498 const auto __c = static_cast<decltype(__s)>(_M_count);
2499 return __s < __c ? 0 : __s - __c;
2503 size() const requires sized_range<const _Vp>
2505 const auto __s = ranges::size(_M_base);
2506 const auto __c = static_cast<decltype(__s)>(_M_count);
2507 return __s < __c ? 0 : __s - __c;
2511 template<typename _Range>
2512 drop_view(_Range&&, range_difference_t<_Range>)
2513 -> drop_view<views::all_t<_Range>>;
2515 template<typename _Tp>
2516 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2517 = enable_borrowed_range<_Tp>;
2523 template<typename _Range, typename _Dp>
2524 concept __can_drop_view
2525 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2526 } // namespace __detail
2528 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2530 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2531 requires __detail::__can_drop_view<_Range, _Dp>
2533 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2535 using _Tp = remove_cvref_t<_Range>;
2536 if constexpr (__detail::__is_empty_view<_Tp>)
2538 else if constexpr (random_access_range<_Tp>
2540 && (std::__detail::__is_span<_Tp>
2541 || __detail::__is_basic_string_view<_Tp>
2542 || __detail::__is_iota_view<_Tp>
2543 || __detail::__is_subrange<_Tp>))
2545 __n = std::min<_Dp>(ranges::distance(__r), __n);
2546 auto __begin = ranges::begin(__r) + __n;
2547 auto __end = ranges::end(__r);
2548 if constexpr (std::__detail::__is_span<_Tp>)
2549 return span<typename _Tp::element_type>(__begin, __end);
2550 else if constexpr (__detail::__is_subrange<_Tp>)
2552 if constexpr (_Tp::_S_store_size)
2554 using ranges::__detail::__to_unsigned_like;
2555 auto __m = ranges::distance(__r) - __n;
2556 return _Tp(__begin, __end, __to_unsigned_like(__m));
2559 return _Tp(__begin, __end);
2562 return _Tp(__begin, __end);
2565 return drop_view(std::forward<_Range>(__r), __n);
2568 using _RangeAdaptor<_Drop>::operator();
2569 static constexpr int _S_arity = 2;
2570 template<typename _Tp>
2571 static constexpr bool _S_has_simple_extra_args
2572 = _Take::_S_has_simple_extra_args<_Tp>;
2575 inline constexpr _Drop drop;
2576 } // namespace views
2578 template<view _Vp, typename _Pred>
2579 requires input_range<_Vp> && is_object_v<_Pred>
2580 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2581 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2584 _Vp _M_base = _Vp();
2585 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2586 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2589 drop_while_view() requires (default_initializable<_Vp>
2590 && default_initializable<_Pred>)
2594 drop_while_view(_Vp __base, _Pred __pred)
2595 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2599 base() const& requires copy_constructible<_Vp>
2604 { return std::move(_M_base); }
2606 constexpr const _Pred&
2608 { return *_M_pred; }
2613 if (_M_cached_begin._M_has_value())
2614 return _M_cached_begin._M_get(_M_base);
2616 __glibcxx_assert(_M_pred.has_value());
2617 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2618 ranges::end(_M_base),
2619 std::cref(*_M_pred));
2620 _M_cached_begin._M_set(_M_base, __it);
2626 { return ranges::end(_M_base); }
2629 template<typename _Range, typename _Pred>
2630 drop_while_view(_Range&&, _Pred)
2631 -> drop_while_view<views::all_t<_Range>, _Pred>;
2633 template<typename _Tp, typename _Pred>
2634 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2635 = enable_borrowed_range<_Tp>;
2641 template<typename _Range, typename _Pred>
2642 concept __can_drop_while_view
2643 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2644 } // namespace __detail
2646 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2648 template<viewable_range _Range, typename _Pred>
2649 requires __detail::__can_drop_while_view<_Range, _Pred>
2651 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2653 return drop_while_view(std::forward<_Range>(__r),
2654 std::forward<_Pred>(__p));
2657 using _RangeAdaptor<_DropWhile>::operator();
2658 static constexpr int _S_arity = 2;
2659 static constexpr bool _S_has_simple_extra_args = true;
2662 inline constexpr _DropWhile drop_while;
2663 } // namespace views
2665 template<input_range _Vp>
2666 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2667 class join_view : public view_interface<join_view<_Vp>>
2670 using _InnerRange = range_reference_t<_Vp>;
2672 template<bool _Const>
2673 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2675 template<bool _Const>
2676 using _Outer_iter = iterator_t<_Base<_Const>>;
2678 template<bool _Const>
2679 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2681 template<bool _Const>
2682 static constexpr bool _S_ref_is_glvalue
2683 = is_reference_v<range_reference_t<_Base<_Const>>>;
2685 template<bool _Const>
2689 template<bool _Const>
2690 requires _S_ref_is_glvalue<_Const>
2691 && forward_range<_Base<_Const>>
2692 && forward_range<range_reference_t<_Base<_Const>>>
2693 struct __iter_cat<_Const>
2696 static constexpr auto
2699 using _Outer_iter = join_view::_Outer_iter<_Const>;
2700 using _Inner_iter = join_view::_Inner_iter<_Const>;
2701 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2702 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2703 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2704 && derived_from<_InnerCat, bidirectional_iterator_tag>
2705 && common_range<range_reference_t<_Base<_Const>>>)
2706 return bidirectional_iterator_tag{};
2707 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2708 && derived_from<_InnerCat, forward_iterator_tag>)
2709 return forward_iterator_tag{};
2711 return input_iterator_tag{};
2714 using iterator_category = decltype(_S_iter_cat());
2717 template<bool _Const>
2720 template<bool _Const>
2721 struct _Iterator : __iter_cat<_Const>
2724 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2725 using _Base = join_view::_Base<_Const>;
2727 static constexpr bool _S_ref_is_glvalue
2728 = join_view::_S_ref_is_glvalue<_Const>;
2733 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2734 if constexpr (_S_ref_is_glvalue)
2737 return _M_parent->_M_inner._M_emplace_deref(__x);
2740 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2742 auto&& __inner = __update_inner(_M_outer);
2743 _M_inner = ranges::begin(__inner);
2744 if (_M_inner != ranges::end(__inner))
2748 if constexpr (_S_ref_is_glvalue)
2749 _M_inner = _Inner_iter();
2752 static constexpr auto
2755 if constexpr (_S_ref_is_glvalue
2756 && bidirectional_range<_Base>
2757 && bidirectional_range<range_reference_t<_Base>>
2758 && common_range<range_reference_t<_Base>>)
2759 return bidirectional_iterator_tag{};
2760 else if constexpr (_S_ref_is_glvalue
2761 && forward_range<_Base>
2762 && forward_range<range_reference_t<_Base>>)
2763 return forward_iterator_tag{};
2765 return input_iterator_tag{};
2768 using _Outer_iter = join_view::_Outer_iter<_Const>;
2769 using _Inner_iter = join_view::_Inner_iter<_Const>;
2771 _Outer_iter _M_outer = _Outer_iter();
2772 _Inner_iter _M_inner = _Inner_iter();
2773 _Parent* _M_parent = nullptr;
2776 using iterator_concept = decltype(_S_iter_concept());
2777 // iterator_category defined in __join_view_iter_cat
2778 using value_type = range_value_t<range_reference_t<_Base>>;
2779 using difference_type
2780 = common_type_t<range_difference_t<_Base>,
2781 range_difference_t<range_reference_t<_Base>>>;
2783 _Iterator() requires (default_initializable<_Outer_iter>
2784 && default_initializable<_Inner_iter>)
2788 _Iterator(_Parent* __parent, _Outer_iter __outer)
2789 : _M_outer(std::move(__outer)),
2794 _Iterator(_Iterator<!_Const> __i)
2796 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2797 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2798 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
2799 _M_parent(__i._M_parent)
2802 constexpr decltype(auto)
2804 { return *_M_inner; }
2806 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2807 // 3500. join_view::iterator::operator->() is bogus
2808 constexpr _Inner_iter
2810 requires __detail::__has_arrow<_Inner_iter>
2811 && copyable<_Inner_iter>
2812 { return _M_inner; }
2814 constexpr _Iterator&
2817 auto&& __inner_range = [this] () -> auto&& {
2818 if constexpr (_S_ref_is_glvalue)
2821 return *_M_parent->_M_inner;
2823 if (++_M_inner == ranges::end(__inner_range))
2837 requires _S_ref_is_glvalue && forward_range<_Base>
2838 && forward_range<range_reference_t<_Base>>
2845 constexpr _Iterator&
2847 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2848 && bidirectional_range<range_reference_t<_Base>>
2849 && common_range<range_reference_t<_Base>>
2851 if (_M_outer == ranges::end(_M_parent->_M_base))
2852 _M_inner = ranges::end(*--_M_outer);
2853 while (_M_inner == ranges::begin(*_M_outer))
2854 _M_inner = ranges::end(*--_M_outer);
2861 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2862 && bidirectional_range<range_reference_t<_Base>>
2863 && common_range<range_reference_t<_Base>>
2870 friend constexpr bool
2871 operator==(const _Iterator& __x, const _Iterator& __y)
2872 requires _S_ref_is_glvalue
2873 && equality_comparable<_Outer_iter>
2874 && equality_comparable<_Inner_iter>
2876 return (__x._M_outer == __y._M_outer
2877 && __x._M_inner == __y._M_inner);
2880 friend constexpr decltype(auto)
2881 iter_move(const _Iterator& __i)
2882 noexcept(noexcept(ranges::iter_move(__i._M_inner)))
2883 { return ranges::iter_move(__i._M_inner); }
2885 friend constexpr void
2886 iter_swap(const _Iterator& __x, const _Iterator& __y)
2887 noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner)))
2888 requires indirectly_swappable<_Inner_iter>
2889 { return ranges::iter_swap(__x._M_inner, __y._M_inner); }
2891 friend _Iterator<!_Const>;
2892 template<bool> friend struct _Sentinel;
2895 template<bool _Const>
2899 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2900 using _Base = join_view::_Base<_Const>;
2902 template<bool _Const2>
2904 __equal(const _Iterator<_Const2>& __i) const
2905 { return __i._M_outer == _M_end; }
2907 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2910 _Sentinel() = default;
2913 _Sentinel(_Parent* __parent)
2914 : _M_end(ranges::end(__parent->_M_base))
2918 _Sentinel(_Sentinel<!_Const> __s)
2919 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2920 : _M_end(std::move(__s._M_end))
2923 template<bool _Const2>
2924 requires sentinel_for<sentinel_t<_Base>,
2925 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2926 friend constexpr bool
2927 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2928 { return __y.__equal(__x); }
2930 friend _Sentinel<!_Const>;
2933 _Vp _M_base = _Vp();
2934 [[no_unique_address]]
2935 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
2938 join_view() requires default_initializable<_Vp> = default;
2941 join_view(_Vp __base)
2942 : _M_base(std::move(__base))
2946 base() const& requires copy_constructible<_Vp>
2951 { return std::move(_M_base); }
2956 constexpr bool __use_const
2957 = (__detail::__simple_view<_Vp>
2958 && is_reference_v<range_reference_t<_Vp>>);
2959 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
2964 requires input_range<const _Vp>
2965 && is_reference_v<range_reference_t<const _Vp>>
2967 return _Iterator<true>{this, ranges::begin(_M_base)};
2973 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
2974 && forward_range<_InnerRange>
2975 && common_range<_Vp> && common_range<_InnerRange>)
2976 return _Iterator<__detail::__simple_view<_Vp>>{this,
2977 ranges::end(_M_base)};
2979 return _Sentinel<__detail::__simple_view<_Vp>>{this};
2984 requires input_range<const _Vp>
2985 && is_reference_v<range_reference_t<const _Vp>>
2987 if constexpr (forward_range<const _Vp>
2988 && is_reference_v<range_reference_t<const _Vp>>
2989 && forward_range<range_reference_t<const _Vp>>
2990 && common_range<const _Vp>
2991 && common_range<range_reference_t<const _Vp>>)
2992 return _Iterator<true>{this, ranges::end(_M_base)};
2994 return _Sentinel<true>{this};
2998 template<typename _Range>
2999 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3005 template<typename _Range>
3006 concept __can_join_view
3007 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3008 } // namespace __detail
3010 struct _Join : __adaptor::_RangeAdaptorClosure
3012 template<viewable_range _Range>
3013 requires __detail::__can_join_view<_Range>
3015 operator() [[nodiscard]] (_Range&& __r) const
3017 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3018 // 3474. Nesting join_views is broken because of CTAD
3019 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3022 static constexpr bool _S_has_simple_call_op = true;
3025 inline constexpr _Join join;
3026 } // namespace views
3031 struct __require_constant;
3033 template<typename _Range>
3034 concept __tiny_range = sized_range<_Range>
3036 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3037 && (remove_reference_t<_Range>::size() <= 1);
3039 template<typename _Base>
3040 struct __lazy_split_view_outer_iter_cat
3043 template<forward_range _Base>
3044 struct __lazy_split_view_outer_iter_cat<_Base>
3045 { using iterator_category = input_iterator_tag; };
3047 template<typename _Base>
3048 struct __lazy_split_view_inner_iter_cat
3051 template<forward_range _Base>
3052 struct __lazy_split_view_inner_iter_cat<_Base>
3055 static constexpr auto
3058 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3059 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3060 return forward_iterator_tag{};
3065 using iterator_category = decltype(_S_iter_cat());
3069 template<input_range _Vp, forward_range _Pattern>
3070 requires view<_Vp> && view<_Pattern>
3071 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3073 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3074 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3077 template<bool _Const>
3078 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3080 template<bool _Const>
3083 template<bool _Const>
3085 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3088 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3089 using _Base = lazy_split_view::_Base<_Const>;
3093 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3095 // [range.lazy.split.outer] p1
3096 // Many of the following specifications refer to the notional member
3097 // current of outer-iterator. current is equivalent to current_ if
3098 // V models forward_range, and parent_->current_ otherwise.
3100 __current() noexcept
3102 if constexpr (forward_range<_Vp>)
3105 return *_M_parent->_M_current;
3109 __current() const noexcept
3111 if constexpr (forward_range<_Vp>)
3114 return *_M_parent->_M_current;
3117 _Parent* _M_parent = nullptr;
3119 // XXX: _M_current is present only if "V models forward_range"
3120 [[no_unique_address]]
3121 __detail::__maybe_present_t<forward_range<_Vp>,
3122 iterator_t<_Base>> _M_current;
3123 bool _M_trailing_empty = false;
3126 using iterator_concept = __conditional_t<forward_range<_Base>,
3127 forward_iterator_tag,
3128 input_iterator_tag>;
3129 // iterator_category defined in __lazy_split_view_outer_iter_cat
3130 using difference_type = range_difference_t<_Base>;
3132 struct value_type : view_interface<value_type>
3135 _OuterIter _M_i = _OuterIter();
3138 value_type() = default;
3141 value_type(_OuterIter __i)
3142 : _M_i(std::move(__i))
3145 constexpr _InnerIter<_Const>
3147 { return _InnerIter<_Const>{_M_i}; }
3149 constexpr default_sentinel_t
3150 end() const noexcept
3151 { return default_sentinel; }
3154 _OuterIter() = default;
3157 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3158 : _M_parent(__parent)
3162 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3163 requires forward_range<_Base>
3164 : _M_parent(__parent),
3165 _M_current(std::move(__current))
3169 _OuterIter(_OuterIter<!_Const> __i)
3171 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3172 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current))
3175 constexpr value_type
3177 { return value_type{*this}; }
3179 constexpr _OuterIter&
3182 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3183 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3184 const auto __end = ranges::end(_M_parent->_M_base);
3185 if (__current() == __end)
3187 _M_trailing_empty = false;
3190 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3191 if (__pbegin == __pend)
3193 else if constexpr (__detail::__tiny_range<_Pattern>)
3195 __current() = ranges::find(std::move(__current()), __end,
3197 if (__current() != __end)
3200 if (__current() == __end)
3201 _M_trailing_empty = true;
3208 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3212 if (__current() == __end)
3213 _M_trailing_empty = true;
3216 } while (++__current() != __end);
3220 constexpr decltype(auto)
3223 if constexpr (forward_range<_Base>)
3233 friend constexpr bool
3234 operator==(const _OuterIter& __x, const _OuterIter& __y)
3235 requires forward_range<_Base>
3237 return __x._M_current == __y._M_current
3238 && __x._M_trailing_empty == __y._M_trailing_empty;
3241 friend constexpr bool
3242 operator==(const _OuterIter& __x, default_sentinel_t)
3243 { return __x.__at_end(); };
3245 friend _OuterIter<!_Const>;
3246 friend _InnerIter<_Const>;
3249 template<bool _Const>
3251 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3254 using _Base = lazy_split_view::_Base<_Const>;
3259 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3260 auto __end = ranges::end(_M_i._M_parent->_M_base);
3261 if constexpr (__detail::__tiny_range<_Pattern>)
3263 const auto& __cur = _M_i_current();
3266 if (__pcur == __pend)
3267 return _M_incremented;
3268 return *__cur == *__pcur;
3272 auto __cur = _M_i_current();
3275 if (__pcur == __pend)
3276 return _M_incremented;
3279 if (*__cur != *__pcur)
3281 if (++__pcur == __pend)
3283 } while (++__cur != __end);
3289 _M_i_current() noexcept
3290 { return _M_i.__current(); }
3293 _M_i_current() const noexcept
3294 { return _M_i.__current(); }
3296 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3297 bool _M_incremented = false;
3300 using iterator_concept
3301 = typename _OuterIter<_Const>::iterator_concept;
3302 // iterator_category defined in __lazy_split_view_inner_iter_cat
3303 using value_type = range_value_t<_Base>;
3304 using difference_type = range_difference_t<_Base>;
3306 _InnerIter() = default;
3309 _InnerIter(_OuterIter<_Const> __i)
3310 : _M_i(std::move(__i))
3313 constexpr const iterator_t<_Base>&
3314 base() const& noexcept
3315 { return _M_i_current(); }
3317 constexpr iterator_t<_Base>
3318 base() && requires forward_range<_Vp>
3319 { return std::move(_M_i_current()); }
3321 constexpr decltype(auto)
3323 { return *_M_i_current(); }
3325 constexpr _InnerIter&
3328 _M_incremented = true;
3329 if constexpr (!forward_range<_Base>)
3330 if constexpr (_Pattern::size() == 0)
3336 constexpr decltype(auto)
3339 if constexpr (forward_range<_Base>)
3349 friend constexpr bool
3350 operator==(const _InnerIter& __x, const _InnerIter& __y)
3351 requires forward_range<_Base>
3352 { return __x._M_i == __y._M_i; }
3354 friend constexpr bool
3355 operator==(const _InnerIter& __x, default_sentinel_t)
3356 { return __x.__at_end(); }
3358 friend constexpr decltype(auto)
3359 iter_move(const _InnerIter& __i)
3360 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3361 { return ranges::iter_move(__i._M_i_current()); }
3363 friend constexpr void
3364 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3365 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3366 __y._M_i_current())))
3367 requires indirectly_swappable<iterator_t<_Base>>
3368 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3371 _Vp _M_base = _Vp();
3372 _Pattern _M_pattern = _Pattern();
3373 // XXX: _M_current is "present only if !forward_range<V>"
3374 [[no_unique_address]]
3375 __detail::__maybe_present_t<!forward_range<_Vp>,
3376 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3380 lazy_split_view() requires (default_initializable<_Vp>
3381 && default_initializable<_Pattern>)
3385 lazy_split_view(_Vp __base, _Pattern __pattern)
3386 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3389 template<input_range _Range>
3390 requires constructible_from<_Vp, views::all_t<_Range>>
3391 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3393 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3394 : _M_base(views::all(std::forward<_Range>(__r))),
3395 _M_pattern(views::single(std::move(__e)))
3399 base() const& requires copy_constructible<_Vp>
3404 { return std::move(_M_base); }
3409 if constexpr (forward_range<_Vp>)
3411 constexpr bool __simple
3412 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3413 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3417 _M_current = ranges::begin(_M_base);
3418 return _OuterIter<false>{this};
3423 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3425 return _OuterIter<true>{this, ranges::begin(_M_base)};
3429 end() requires forward_range<_Vp> && common_range<_Vp>
3431 constexpr bool __simple
3432 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3433 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3439 if constexpr (forward_range<_Vp>
3440 && forward_range<const _Vp>
3441 && common_range<const _Vp>)
3442 return _OuterIter<true>{this, ranges::end(_M_base)};
3444 return default_sentinel;
3448 template<typename _Range, typename _Pattern>
3449 lazy_split_view(_Range&&, _Pattern&&)
3450 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3452 template<input_range _Range>
3453 lazy_split_view(_Range&&, range_value_t<_Range>)
3454 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3460 template<typename _Range, typename _Pattern>
3461 concept __can_lazy_split_view
3462 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3463 } // namespace __detail
3465 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3467 template<viewable_range _Range, typename _Pattern>
3468 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3470 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3472 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3475 using _RangeAdaptor<_LazySplit>::operator();
3476 static constexpr int _S_arity = 2;
3477 // The pattern argument of views::lazy_split is not always simple -- it can be
3478 // a non-view range, the value category of which affects whether the call
3479 // is well-formed. But a scalar or a view pattern argument is surely
3481 template<typename _Pattern>
3482 static constexpr bool _S_has_simple_extra_args
3483 = is_scalar_v<_Pattern> || (view<_Pattern>
3484 && copy_constructible<_Pattern>);
3487 inline constexpr _LazySplit lazy_split;
3488 } // namespace views
3490 template<forward_range _Vp, forward_range _Pattern>
3491 requires view<_Vp> && view<_Pattern>
3492 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3494 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3497 _Vp _M_base = _Vp();
3498 _Pattern _M_pattern = _Pattern();
3499 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3505 split_view() requires (default_initializable<_Vp>
3506 && default_initializable<_Pattern>)
3510 split_view(_Vp __base, _Pattern __pattern)
3511 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3514 template<forward_range _Range>
3515 requires constructible_from<_Vp, views::all_t<_Range>>
3516 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3518 split_view(_Range&& __r, range_value_t<_Range> __e)
3519 : _M_base(views::all(std::forward<_Range>(__r))),
3520 _M_pattern(views::single(std::move(__e)))
3524 base() const& requires copy_constructible<_Vp>
3529 { return std::move(_M_base); }
3534 if (!_M_cached_begin)
3535 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3536 return {this, ranges::begin(_M_base), *_M_cached_begin};
3542 if constexpr (common_range<_Vp>)
3543 return _Iterator{this, ranges::end(_M_base), {}};
3545 return _Sentinel{this};
3548 constexpr subrange<iterator_t<_Vp>>
3549 _M_find_next(iterator_t<_Vp> __it)
3551 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3552 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3564 split_view* _M_parent = nullptr;
3565 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3566 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3567 bool _M_trailing_empty = false;
3569 friend struct _Sentinel;
3572 using iterator_concept = forward_iterator_tag;
3573 using iterator_category = input_iterator_tag;
3574 using value_type = subrange<iterator_t<_Vp>>;
3575 using difference_type = range_difference_t<_Vp>;
3577 _Iterator() = default;
3580 _Iterator(split_view* __parent,
3581 iterator_t<_Vp> __current,
3582 subrange<iterator_t<_Vp>> __next)
3583 : _M_parent(__parent),
3584 _M_cur(std::move(__current)),
3585 _M_next(std::move(__next))
3588 constexpr iterator_t<_Vp>
3592 constexpr value_type
3594 { return {_M_cur, _M_next.begin()}; }
3596 constexpr _Iterator&
3599 _M_cur = _M_next.begin();
3600 if (_M_cur != ranges::end(_M_parent->_M_base))
3602 _M_cur = _M_next.end();
3603 if (_M_cur == ranges::end(_M_parent->_M_base))
3605 _M_trailing_empty = true;
3606 _M_next = {_M_cur, _M_cur};
3609 _M_next = _M_parent->_M_find_next(_M_cur);
3612 _M_trailing_empty = false;
3624 friend constexpr bool
3625 operator==(const _Iterator& __x, const _Iterator& __y)
3627 return __x._M_cur == __y._M_cur
3628 && __x._M_trailing_empty == __y._M_trailing_empty;
3635 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3638 _M_equal(const _Iterator& __x) const
3639 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3642 _Sentinel() = default;
3645 _Sentinel(split_view* __parent)
3646 : _M_end(ranges::end(__parent->_M_base))
3649 friend constexpr bool
3650 operator==(const _Iterator& __x, const _Sentinel& __y)
3651 { return __y._M_equal(__x); }
3655 template<typename _Range, typename _Pattern>
3656 split_view(_Range&&, _Pattern&&)
3657 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3659 template<forward_range _Range>
3660 split_view(_Range&&, range_value_t<_Range>)
3661 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3667 template<typename _Range, typename _Pattern>
3668 concept __can_split_view
3669 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3670 } // namespace __detail
3672 struct _Split : __adaptor::_RangeAdaptor<_Split>
3674 template<viewable_range _Range, typename _Pattern>
3675 requires __detail::__can_split_view<_Range, _Pattern>
3677 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3679 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3682 using _RangeAdaptor<_Split>::operator();
3683 static constexpr int _S_arity = 2;
3684 template<typename _Pattern>
3685 static constexpr bool _S_has_simple_extra_args
3686 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3689 inline constexpr _Split split;
3690 } // namespace views
3696 template<input_or_output_iterator _Iter>
3698 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3700 if constexpr (contiguous_iterator<_Iter>)
3701 return span(std::__to_address(__i), __n);
3702 else if constexpr (random_access_iterator<_Iter>)
3703 return subrange(__i, __i + __n);
3705 return subrange(counted_iterator(std::move(__i), __n),
3710 inline constexpr _Counted counted{};
3711 } // namespace views
3714 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3715 class common_view : public view_interface<common_view<_Vp>>
3718 _Vp _M_base = _Vp();
3721 common_view() requires default_initializable<_Vp> = default;
3724 common_view(_Vp __r)
3725 : _M_base(std::move(__r))
3728 /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
3729 template<viewable_range _Range>
3730 requires (!common_range<_Range>)
3731 && constructible_from<_Vp, views::all_t<_Range>>
3733 common_view(_Range&& __r)
3734 : _M_base(views::all(std::forward<_Range>(__r)))
3739 base() const& requires copy_constructible<_Vp>
3744 { return std::move(_M_base); }
3749 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3750 return ranges::begin(_M_base);
3752 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3753 (ranges::begin(_M_base));
3757 begin() const requires range<const _Vp>
3759 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3760 return ranges::begin(_M_base);
3762 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3763 (ranges::begin(_M_base));
3769 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3770 return ranges::begin(_M_base) + ranges::size(_M_base);
3772 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3773 (ranges::end(_M_base));
3777 end() const requires range<const _Vp>
3779 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3780 return ranges::begin(_M_base) + ranges::size(_M_base);
3782 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3783 (ranges::end(_M_base));
3787 size() requires sized_range<_Vp>
3788 { return ranges::size(_M_base); }
3791 size() const requires sized_range<const _Vp>
3792 { return ranges::size(_M_base); }
3795 template<typename _Range>
3796 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3798 template<typename _Tp>
3799 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3800 = enable_borrowed_range<_Tp>;
3806 template<typename _Range>
3807 concept __already_common = common_range<_Range>
3808 && requires { views::all(std::declval<_Range>()); };
3810 template<typename _Range>
3811 concept __can_common_view
3812 = requires { common_view{std::declval<_Range>()}; };
3813 } // namespace __detail
3815 struct _Common : __adaptor::_RangeAdaptorClosure
3817 template<viewable_range _Range>
3818 requires __detail::__already_common<_Range>
3819 || __detail::__can_common_view<_Range>
3821 operator() [[nodiscard]] (_Range&& __r) const
3823 if constexpr (__detail::__already_common<_Range>)
3824 return views::all(std::forward<_Range>(__r));
3826 return common_view{std::forward<_Range>(__r)};
3829 static constexpr bool _S_has_simple_call_op = true;
3832 inline constexpr _Common common;
3833 } // namespace views
3836 requires bidirectional_range<_Vp>
3837 class reverse_view : public view_interface<reverse_view<_Vp>>
3840 static constexpr bool _S_needs_cached_begin
3841 = !common_range<_Vp> && !(random_access_range<_Vp>
3842 && sized_sentinel_for<sentinel_t<_Vp>,
3845 _Vp _M_base = _Vp();
3846 [[no_unique_address]]
3847 __detail::__maybe_present_t<_S_needs_cached_begin,
3848 __detail::_CachedPosition<_Vp>>
3852 reverse_view() requires default_initializable<_Vp> = default;
3855 reverse_view(_Vp __r)
3856 : _M_base(std::move(__r))
3860 base() const& requires copy_constructible<_Vp>
3865 { return std::move(_M_base); }
3867 constexpr reverse_iterator<iterator_t<_Vp>>
3870 if constexpr (_S_needs_cached_begin)
3871 if (_M_cached_begin._M_has_value())
3872 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
3874 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3875 if constexpr (_S_needs_cached_begin)
3876 _M_cached_begin._M_set(_M_base, __it);
3877 return std::make_reverse_iterator(std::move(__it));
3881 begin() requires common_range<_Vp>
3882 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3885 begin() const requires common_range<const _Vp>
3886 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3888 constexpr reverse_iterator<iterator_t<_Vp>>
3890 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3893 end() const requires common_range<const _Vp>
3894 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3897 size() requires sized_range<_Vp>
3898 { return ranges::size(_M_base); }
3901 size() const requires sized_range<const _Vp>
3902 { return ranges::size(_M_base); }
3905 template<typename _Range>
3906 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3908 template<typename _Tp>
3909 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
3910 = enable_borrowed_range<_Tp>;
3917 inline constexpr bool __is_reversible_subrange = false;
3919 template<typename _Iter, subrange_kind _Kind>
3920 inline constexpr bool
3921 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3922 reverse_iterator<_Iter>,
3926 inline constexpr bool __is_reverse_view = false;
3928 template<typename _Vp>
3929 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
3931 template<typename _Range>
3932 concept __can_reverse_view
3933 = requires { reverse_view{std::declval<_Range>()}; };
3934 } // namespace __detail
3936 struct _Reverse : __adaptor::_RangeAdaptorClosure
3938 template<viewable_range _Range>
3939 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
3940 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
3941 || __detail::__can_reverse_view<_Range>
3943 operator() [[nodiscard]] (_Range&& __r) const
3945 using _Tp = remove_cvref_t<_Range>;
3946 if constexpr (__detail::__is_reverse_view<_Tp>)
3947 return std::forward<_Range>(__r).base();
3948 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3950 using _Iter = decltype(ranges::begin(__r).base());
3951 if constexpr (sized_range<_Tp>)
3952 return subrange<_Iter, _Iter, subrange_kind::sized>
3953 {__r.end().base(), __r.begin().base(), __r.size()};
3955 return subrange<_Iter, _Iter, subrange_kind::unsized>
3956 {__r.end().base(), __r.begin().base()};
3959 return reverse_view{std::forward<_Range>(__r)};
3962 static constexpr bool _S_has_simple_call_op = true;
3965 inline constexpr _Reverse reverse;
3966 } // namespace views
3970 template<typename _Tp, size_t _Nm>
3971 concept __has_tuple_element = requires(_Tp __t)
3973 typename tuple_size<_Tp>::type;
3974 requires _Nm < tuple_size_v<_Tp>;
3975 typename tuple_element_t<_Nm, _Tp>;
3976 { std::get<_Nm>(__t) }
3977 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
3980 template<typename _Tp, size_t _Nm>
3981 concept __returnable_element
3982 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
3985 template<input_range _Vp, size_t _Nm>
3987 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
3988 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
3990 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
3991 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
3994 elements_view() requires default_initializable<_Vp> = default;
3997 elements_view(_Vp base)
3998 : _M_base(std::move(base))
4002 base() const& requires copy_constructible<_Vp>
4007 { return std::move(_M_base); }
4010 begin() requires (!__detail::__simple_view<_Vp>)
4011 { return _Iterator<false>(ranges::begin(_M_base)); }
4014 begin() const requires range<const _Vp>
4015 { return _Iterator<true>(ranges::begin(_M_base)); }
4018 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4019 { return _Sentinel<false>{ranges::end(_M_base)}; }
4022 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4023 { return _Iterator<false>{ranges::end(_M_base)}; }
4026 end() const requires range<const _Vp>
4027 { return _Sentinel<true>{ranges::end(_M_base)}; }
4030 end() const requires common_range<const _Vp>
4031 { return _Iterator<true>{ranges::end(_M_base)}; }
4034 size() requires sized_range<_Vp>
4035 { return ranges::size(_M_base); }
4038 size() const requires sized_range<const _Vp>
4039 { return ranges::size(_M_base); }
4042 template<bool _Const>
4043 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4045 template<bool _Const>
4049 template<bool _Const>
4050 requires forward_range<_Base<_Const>>
4051 struct __iter_cat<_Const>
4054 static auto _S_iter_cat()
4056 using _Base = elements_view::_Base<_Const>;
4057 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4058 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4059 if constexpr (!is_lvalue_reference_v<_Res>)
4060 return input_iterator_tag{};
4061 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4062 return random_access_iterator_tag{};
4067 using iterator_category = decltype(_S_iter_cat());
4070 template<bool _Const>
4073 template<bool _Const>
4074 struct _Iterator : __iter_cat<_Const>
4077 using _Base = elements_view::_Base<_Const>;
4079 iterator_t<_Base> _M_current = iterator_t<_Base>();
4081 static constexpr decltype(auto)
4082 _S_get_element(const iterator_t<_Base>& __i)
4084 if constexpr (is_reference_v<range_reference_t<_Base>>)
4085 return std::get<_Nm>(*__i);
4088 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4089 return static_cast<_Et>(std::get<_Nm>(*__i));
4096 if constexpr (random_access_range<_Base>)
4097 return random_access_iterator_tag{};
4098 else if constexpr (bidirectional_range<_Base>)
4099 return bidirectional_iterator_tag{};
4100 else if constexpr (forward_range<_Base>)
4101 return forward_iterator_tag{};
4103 return input_iterator_tag{};
4106 friend _Iterator<!_Const>;
4109 using iterator_concept = decltype(_S_iter_concept());
4110 // iterator_category defined in elements_view::__iter_cat
4112 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4113 using difference_type = range_difference_t<_Base>;
4115 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4118 _Iterator(iterator_t<_Base> current)
4119 : _M_current(std::move(current))
4123 _Iterator(_Iterator<!_Const> i)
4124 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4125 : _M_current(std::move(i._M_current))
4128 constexpr const iterator_t<_Base>&
4129 base() const& noexcept
4130 { return _M_current; }
4132 constexpr iterator_t<_Base>
4134 { return std::move(_M_current); }
4136 constexpr decltype(auto)
4138 { return _S_get_element(_M_current); }
4140 constexpr _Iterator&
4152 operator++(int) requires forward_range<_Base>
4159 constexpr _Iterator&
4160 operator--() requires bidirectional_range<_Base>
4167 operator--(int) requires bidirectional_range<_Base>
4174 constexpr _Iterator&
4175 operator+=(difference_type __n)
4176 requires random_access_range<_Base>
4182 constexpr _Iterator&
4183 operator-=(difference_type __n)
4184 requires random_access_range<_Base>
4190 constexpr decltype(auto)
4191 operator[](difference_type __n) const
4192 requires random_access_range<_Base>
4193 { return _S_get_element(_M_current + __n); }
4195 friend constexpr bool
4196 operator==(const _Iterator& __x, const _Iterator& __y)
4197 requires equality_comparable<iterator_t<_Base>>
4198 { return __x._M_current == __y._M_current; }
4200 friend constexpr bool
4201 operator<(const _Iterator& __x, const _Iterator& __y)
4202 requires random_access_range<_Base>
4203 { return __x._M_current < __y._M_current; }
4205 friend constexpr bool
4206 operator>(const _Iterator& __x, const _Iterator& __y)
4207 requires random_access_range<_Base>
4208 { return __y._M_current < __x._M_current; }
4210 friend constexpr bool
4211 operator<=(const _Iterator& __x, const _Iterator& __y)
4212 requires random_access_range<_Base>
4213 { return !(__y._M_current > __x._M_current); }
4215 friend constexpr bool
4216 operator>=(const _Iterator& __x, const _Iterator& __y)
4217 requires random_access_range<_Base>
4218 { return !(__x._M_current > __y._M_current); }
4220 #ifdef __cpp_lib_three_way_comparison
4221 friend constexpr auto
4222 operator<=>(const _Iterator& __x, const _Iterator& __y)
4223 requires random_access_range<_Base>
4224 && three_way_comparable<iterator_t<_Base>>
4225 { return __x._M_current <=> __y._M_current; }
4228 friend constexpr _Iterator
4229 operator+(const _Iterator& __x, difference_type __y)
4230 requires random_access_range<_Base>
4231 { return _Iterator{__x} += __y; }
4233 friend constexpr _Iterator
4234 operator+(difference_type __x, const _Iterator& __y)
4235 requires random_access_range<_Base>
4236 { return __y + __x; }
4238 friend constexpr _Iterator
4239 operator-(const _Iterator& __x, difference_type __y)
4240 requires random_access_range<_Base>
4241 { return _Iterator{__x} -= __y; }
4243 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4244 // 3483. transform_view::iterator's difference is overconstrained
4245 friend constexpr difference_type
4246 operator-(const _Iterator& __x, const _Iterator& __y)
4247 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4248 { return __x._M_current - __y._M_current; }
4250 template <bool> friend struct _Sentinel;
4253 template<bool _Const>
4257 template<bool _Const2>
4259 _M_equal(const _Iterator<_Const2>& __x) const
4260 { return __x._M_current == _M_end; }
4262 template<bool _Const2>
4264 _M_distance_from(const _Iterator<_Const2>& __i) const
4265 { return _M_end - __i._M_current; }
4267 using _Base = elements_view::_Base<_Const>;
4268 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4271 _Sentinel() = default;
4274 _Sentinel(sentinel_t<_Base> __end)
4275 : _M_end(std::move(__end))
4279 _Sentinel(_Sentinel<!_Const> __other)
4281 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4282 : _M_end(std::move(__other._M_end))
4285 constexpr sentinel_t<_Base>
4289 template<bool _Const2>
4290 requires sentinel_for<sentinel_t<_Base>,
4291 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4292 friend constexpr bool
4293 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4294 { return __y._M_equal(__x); }
4296 template<bool _Const2,
4297 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4298 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4299 friend constexpr range_difference_t<_Base2>
4300 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4301 { return -__y._M_distance_from(__x); }
4303 template<bool _Const2,
4304 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4305 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4306 friend constexpr range_difference_t<_Base2>
4307 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4308 { return __x._M_distance_from(__y); }
4310 friend _Sentinel<!_Const>;
4313 _Vp _M_base = _Vp();
4316 template<typename _Tp, size_t _Nm>
4317 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4318 = enable_borrowed_range<_Tp>;
4320 template<typename _Range>
4321 using keys_view = elements_view<views::all_t<_Range>, 0>;
4323 template<typename _Range>
4324 using values_view = elements_view<views::all_t<_Range>, 1>;
4330 template<size_t _Nm, typename _Range>
4331 concept __can_elements_view
4332 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4333 } // namespace __detail
4335 template<size_t _Nm>
4336 struct _Elements : __adaptor::_RangeAdaptorClosure
4338 template<viewable_range _Range>
4339 requires __detail::__can_elements_view<_Nm, _Range>
4341 operator() [[nodiscard]] (_Range&& __r) const
4343 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4346 static constexpr bool _S_has_simple_call_op = true;
4349 template<size_t _Nm>
4350 inline constexpr _Elements<_Nm> elements;
4351 inline constexpr auto keys = elements<0>;
4352 inline constexpr auto values = elements<1>;
4353 } // namespace views
4355 } // namespace ranges
4357 namespace views = ranges::views;
4359 _GLIBCXX_END_NAMESPACE_VERSION
4361 #endif // library concepts
4363 #endif /* _GLIBCXX_RANGES */