1 // <ranges> -*- C++ -*-
3 // Copyright (C) 2019-2021 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>
46 #include <bits/ranges_util.h>
47 #include <bits/refwrap.h>
50 * @defgroup ranges Ranges
52 * Components for dealing with ranges of elements.
55 namespace std _GLIBCXX_VISIBILITY(default)
57 _GLIBCXX_BEGIN_NAMESPACE_VERSION
60 // [range.access] customization point objects
61 // [range.req] range and view concepts
62 // [range.dangling] dangling iterator handling
63 // Defined in <bits/ranges_base.h>
65 // [view.interface] View interface
66 // [range.subrange] Sub-ranges
67 // Defined in <bits/ranges_util.h>
69 // C++20 24.6 [range.factories] Range factories
71 /// A view that contains no elements.
72 template<typename _Tp> requires is_object_v<_Tp>
74 : public view_interface<empty_view<_Tp>>
77 static constexpr _Tp* begin() noexcept { return nullptr; }
78 static constexpr _Tp* end() noexcept { return nullptr; }
79 static constexpr _Tp* data() noexcept { return nullptr; }
80 static constexpr size_t size() noexcept { return 0; }
81 static constexpr bool empty() noexcept { return true; }
84 template<typename _Tp>
85 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
89 template<typename _Tp>
90 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
92 template<__boxable _Tp>
93 struct __box : std::optional<_Tp>
95 using std::optional<_Tp>::optional;
99 noexcept(is_nothrow_default_constructible_v<_Tp>)
100 requires default_initializable<_Tp>
101 : std::optional<_Tp>{std::in_place}
104 __box(const __box&) = default;
105 __box(__box&&) = default;
107 using std::optional<_Tp>::operator=;
109 // _GLIBCXX_RESOLVE_LIB_DEFECTS
110 // 3477. Simplify constraints for semiregular-box
112 operator=(const __box& __that)
113 noexcept(is_nothrow_copy_constructible_v<_Tp>)
114 requires (!copyable<_Tp>)
116 if (this != std::__addressof(__that))
119 this->emplace(*__that);
127 operator=(__box&& __that)
128 noexcept(is_nothrow_move_constructible_v<_Tp>)
129 requires (!movable<_Tp>)
131 if (this != std::__addressof(__that))
134 this->emplace(std::move(*__that));
142 // For types which are already copyable, this specialization of the
143 // copyable wrapper stores the object directly without going through
144 // std::optional. It provides just the subset of the primary template's
145 // API that we currently use.
146 template<__boxable _Tp>
147 requires copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
148 && is_nothrow_copy_constructible_v<_Tp>)
152 [[no_unique_address]] _Tp _M_value = _Tp();
155 __box() requires default_initializable<_Tp> = default;
158 __box(const _Tp& __t)
159 noexcept(is_nothrow_copy_constructible_v<_Tp>)
165 noexcept(is_nothrow_move_constructible_v<_Tp>)
166 : _M_value(std::move(__t))
169 template<typename... _Args>
170 requires constructible_from<_Tp, _Args...>
172 __box(in_place_t, _Args&&... __args)
173 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
174 : _M_value(std::forward<_Args>(__args)...)
177 __box(const __box&) = default;
178 __box(__box&&) = default;
179 __box& operator=(const __box&) requires copyable<_Tp> = default;
180 __box& operator=(__box&&) requires copyable<_Tp> = default;
182 // When _Tp is nothrow_copy_constructible but not copy_assignable,
183 // copy assignment is implemented via destroy-then-copy-construct.
185 operator=(const __box& __that) noexcept
187 static_assert(is_nothrow_copy_constructible_v<_Tp>);
188 if (this != std::__addressof(__that))
191 std::construct_at(std::__addressof(_M_value), *__that);
196 // Likewise for move assignment.
198 operator=(__box&& __that) noexcept
200 static_assert(is_nothrow_move_constructible_v<_Tp>);
201 if (this != std::__addressof(__that))
204 std::construct_at(std::__addressof(_M_value), std::move(*__that));
210 has_value() const noexcept
218 operator*() const noexcept
222 operator->() noexcept
223 { return std::__addressof(_M_value); }
226 operator->() const noexcept
227 { return std::__addressof(_M_value); }
229 } // namespace __detail
231 /// A view that contains exactly one element.
232 template<copy_constructible _Tp> requires is_object_v<_Tp>
233 class single_view : public view_interface<single_view<_Tp>>
236 single_view() requires default_initializable<_Tp> = default;
239 single_view(const _Tp& __t)
240 noexcept(is_nothrow_copy_constructible_v<_Tp>)
245 single_view(_Tp&& __t)
246 noexcept(is_nothrow_move_constructible_v<_Tp>)
247 : _M_value(std::move(__t))
250 // _GLIBCXX_RESOLVE_LIB_DEFECTS
251 // 3428. single_view's in place constructor should be explicit
252 template<typename... _Args>
253 requires constructible_from<_Tp, _Args...>
255 single_view(in_place_t, _Args&&... __args)
256 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
257 : _M_value{in_place, std::forward<_Args>(__args)...}
265 begin() const noexcept
270 { return data() + 1; }
274 { return data() + 1; }
276 static constexpr size_t
282 { return _M_value.operator->(); }
285 data() const noexcept
286 { return _M_value.operator->(); }
289 [[no_unique_address]] __detail::__box<_Tp> _M_value;
292 template<typename _Tp>
293 single_view(_Tp) -> single_view<_Tp>;
297 template<typename _Wp>
298 constexpr auto __to_signed_like(_Wp __w) noexcept
300 if constexpr (!integral<_Wp>)
301 return iter_difference_t<_Wp>();
302 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
303 return iter_difference_t<_Wp>(__w);
304 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
305 return ptrdiff_t(__w);
306 else if constexpr (sizeof(long long) > sizeof(_Wp))
307 return (long long)(__w);
308 #ifdef __SIZEOF_INT128__
309 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
310 return __int128(__w);
313 return __max_diff_type(__w);
316 template<typename _Wp>
317 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
319 template<typename _It>
320 concept __decrementable = incrementable<_It>
323 { --__i } -> same_as<_It&>;
324 { __i-- } -> same_as<_It>;
327 template<typename _It>
328 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
329 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
331 { __i += __n } -> same_as<_It&>;
332 { __i -= __n } -> same_as<_It&>;
336 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
339 template<typename _Winc>
340 struct __iota_view_iter_cat
343 template<incrementable _Winc>
344 struct __iota_view_iter_cat<_Winc>
345 { using iterator_category = input_iterator_tag; };
346 } // namespace __detail
348 template<weakly_incrementable _Winc,
349 semiregular _Bound = unreachable_sentinel_t>
350 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
352 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
357 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
363 using namespace __detail;
364 if constexpr (__advanceable<_Winc>)
365 return random_access_iterator_tag{};
366 else if constexpr (__decrementable<_Winc>)
367 return bidirectional_iterator_tag{};
368 else if constexpr (incrementable<_Winc>)
369 return forward_iterator_tag{};
371 return input_iterator_tag{};
375 using iterator_concept = decltype(_S_iter_concept());
376 // iterator_category defined in __iota_view_iter_cat
377 using value_type = _Winc;
378 using difference_type = __detail::__iota_diff_t<_Winc>;
380 _Iterator() requires default_initializable<_Winc> = default;
383 _Iterator(_Winc __value)
384 : _M_value(__value) { }
387 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
402 operator++(int) requires incrementable<_Winc>
410 operator--() requires __detail::__decrementable<_Winc>
417 operator--(int) requires __detail::__decrementable<_Winc>
425 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
427 using __detail::__is_integer_like;
428 using __detail::__is_signed_integer_like;
429 if constexpr (__is_integer_like<_Winc>
430 && !__is_signed_integer_like<_Winc>)
432 if (__n >= difference_type(0))
433 _M_value += static_cast<_Winc>(__n);
435 _M_value -= static_cast<_Winc>(-__n);
443 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
445 using __detail::__is_integer_like;
446 using __detail::__is_signed_integer_like;
447 if constexpr (__is_integer_like<_Winc>
448 && !__is_signed_integer_like<_Winc>)
450 if (__n >= difference_type(0))
451 _M_value -= static_cast<_Winc>(__n);
453 _M_value += static_cast<_Winc>(-__n);
461 operator[](difference_type __n) const
462 requires __detail::__advanceable<_Winc>
463 { return _Winc(_M_value + __n); }
465 friend constexpr bool
466 operator==(const _Iterator& __x, const _Iterator& __y)
467 requires equality_comparable<_Winc>
468 { return __x._M_value == __y._M_value; }
470 friend constexpr bool
471 operator<(const _Iterator& __x, const _Iterator& __y)
472 requires totally_ordered<_Winc>
473 { return __x._M_value < __y._M_value; }
475 friend constexpr bool
476 operator>(const _Iterator& __x, const _Iterator& __y)
477 requires totally_ordered<_Winc>
478 { return __y < __x; }
480 friend constexpr bool
481 operator<=(const _Iterator& __x, const _Iterator& __y)
482 requires totally_ordered<_Winc>
483 { return !(__y < __x); }
485 friend constexpr bool
486 operator>=(const _Iterator& __x, const _Iterator& __y)
487 requires totally_ordered<_Winc>
488 { return !(__x < __y); }
490 #ifdef __cpp_lib_three_way_comparison
491 friend constexpr auto
492 operator<=>(const _Iterator& __x, const _Iterator& __y)
493 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
494 { return __x._M_value <=> __y._M_value; }
497 friend constexpr _Iterator
498 operator+(_Iterator __i, difference_type __n)
499 requires __detail::__advanceable<_Winc>
500 { return __i += __n; }
502 friend constexpr _Iterator
503 operator+(difference_type __n, _Iterator __i)
504 requires __detail::__advanceable<_Winc>
505 { return __i += __n; }
507 friend constexpr _Iterator
508 operator-(_Iterator __i, difference_type __n)
509 requires __detail::__advanceable<_Winc>
510 { return __i -= __n; }
512 friend constexpr difference_type
513 operator-(const _Iterator& __x, const _Iterator& __y)
514 requires __detail::__advanceable<_Winc>
516 using __detail::__is_integer_like;
517 using __detail::__is_signed_integer_like;
518 using _Dt = difference_type;
519 if constexpr (__is_integer_like<_Winc>)
521 if constexpr (__is_signed_integer_like<_Winc>)
522 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
524 return (__y._M_value > __x._M_value)
525 ? _Dt(-_Dt(__y._M_value - __x._M_value))
526 : _Dt(__x._M_value - __y._M_value);
529 return __x._M_value - __y._M_value;
533 _Winc _M_value = _Winc();
543 _M_equal(const _Iterator& __x) const
544 { return __x._M_value == _M_bound; }
547 _M_distance_from(const _Iterator& __x) const
548 { return _M_bound - __x._M_value; }
550 _Bound _M_bound = _Bound();
553 _Sentinel() = default;
556 _Sentinel(_Bound __bound)
557 : _M_bound(__bound) { }
559 friend constexpr bool
560 operator==(const _Iterator& __x, const _Sentinel& __y)
561 { return __y._M_equal(__x); }
563 friend constexpr iter_difference_t<_Winc>
564 operator-(const _Iterator& __x, const _Sentinel& __y)
565 requires sized_sentinel_for<_Bound, _Winc>
566 { return -__y._M_distance_from(__x); }
568 friend constexpr iter_difference_t<_Winc>
569 operator-(const _Sentinel& __x, const _Iterator& __y)
570 requires sized_sentinel_for<_Bound, _Winc>
571 { return __x._M_distance_from(__y); }
576 _Winc _M_value = _Winc();
577 [[no_unique_address]] _Bound _M_bound = _Bound();
580 iota_view() requires default_initializable<_Winc> = default;
583 iota_view(_Winc __value)
588 iota_view(type_identity_t<_Winc> __value,
589 type_identity_t<_Bound> __bound)
590 : _M_value(__value), _M_bound(__bound)
592 if constexpr (totally_ordered_with<_Winc, _Bound>)
593 __glibcxx_assert( bool(__value <= __bound) );
597 iota_view(_Iterator __first, _Iterator __last)
598 requires same_as<_Winc, _Bound>
599 : iota_view(__first._M_value, __last._M_value)
603 iota_view(_Iterator __first, unreachable_sentinel_t __last)
604 requires same_as<_Bound, unreachable_sentinel_t>
605 : iota_view(__first._M_value, __last)
609 iota_view(_Iterator __first, _Sentinel __last)
610 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
611 : iota_view(__first._M_value, __last._M_bound)
615 begin() const { return _Iterator{_M_value}; }
620 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
621 return unreachable_sentinel;
623 return _Sentinel{_M_bound};
627 end() const requires same_as<_Winc, _Bound>
628 { return _Iterator{_M_bound}; }
632 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
633 || (integral<_Winc> && integral<_Bound>)
634 || sized_sentinel_for<_Bound, _Winc>
636 using __detail::__is_integer_like;
637 using __detail::__to_unsigned_like;
638 if constexpr (integral<_Winc> && integral<_Bound>)
640 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
641 return _Up(_M_bound) - _Up(_M_value);
643 else if constexpr (__is_integer_like<_Winc>)
644 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
646 return __to_unsigned_like(_M_bound - _M_value);
650 template<typename _Winc, typename _Bound>
651 requires (!__detail::__is_integer_like<_Winc>
652 || !__detail::__is_integer_like<_Bound>
653 || (__detail::__is_signed_integer_like<_Winc>
654 == __detail::__is_signed_integer_like<_Bound>))
655 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
657 template<typename _Winc, typename _Bound>
658 inline constexpr bool
659 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
663 template<typename _Tp>
664 inline constexpr empty_view<_Tp> empty{};
668 template<typename _Tp>
671 operator()(_Tp&& __e) const
672 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
673 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
676 inline constexpr _Single single{};
680 template<typename _Tp>
683 operator()(_Tp&& __e) const
684 { return iota_view(std::forward<_Tp>(__e)); }
686 template<typename _Tp, typename _Up>
689 operator()(_Tp&& __e, _Up&& __f) const
690 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
693 inline constexpr _Iota iota{};
698 template<typename _Val, typename _CharT, typename _Traits>
699 concept __stream_extractable
700 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
701 } // namespace __detail
703 template<movable _Val, typename _CharT,
704 typename _Traits = char_traits<_CharT>>
705 requires default_initializable<_Val>
706 && __detail::__stream_extractable<_Val, _CharT, _Traits>
707 class basic_istream_view
708 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
712 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
713 : _M_stream(std::__addressof(__stream))
719 *_M_stream >> _M_object;
720 return _Iterator{this};
723 constexpr default_sentinel_t
725 { return default_sentinel; }
728 basic_istream<_CharT, _Traits>* _M_stream;
734 using iterator_concept = input_iterator_tag;
735 using difference_type = ptrdiff_t;
736 using value_type = _Val;
739 _Iterator(basic_istream_view* __parent) noexcept
740 : _M_parent(__parent)
743 _Iterator(const _Iterator&) = delete;
744 _Iterator(_Iterator&&) = default;
745 _Iterator& operator=(const _Iterator&) = delete;
746 _Iterator& operator=(_Iterator&&) = default;
751 *_M_parent->_M_stream >> _M_parent->_M_object;
761 { return _M_parent->_M_object; }
764 operator==(const _Iterator& __x, default_sentinel_t)
765 { return __x._M_at_end(); }
768 basic_istream_view* _M_parent;
772 { return !*_M_parent->_M_stream; }
778 template<typename _Val, typename _CharT, typename _Traits>
779 basic_istream_view<_Val, _CharT, _Traits>
780 istream_view(basic_istream<_CharT, _Traits>& __s)
781 { return basic_istream_view<_Val, _CharT, _Traits>{__s}; }
783 // C++20 24.7 [range.adaptors] Range adaptors
789 // Alias for a type that is conditionally present
790 // (and is an empty type otherwise).
791 // Data members using this alias should use [[no_unique_address]] so that
792 // they take no space when not needed.
793 template<bool _Present, typename _Tp>
794 using __maybe_present_t = __conditional_t<_Present, _Tp, _Empty>;
796 // Alias for a type that is conditionally const.
797 template<bool _Const, typename _Tp>
798 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
800 } // namespace __detail
802 namespace views::__adaptor
804 // True if the range adaptor _Adaptor can be applied with _Args.
805 template<typename _Adaptor, typename... _Args>
806 concept __adaptor_invocable
807 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
809 // True if the range adaptor non-closure _Adaptor can be partially applied
811 template<typename _Adaptor, typename... _Args>
812 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
813 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
814 && (constructible_from<decay_t<_Args>, _Args> && ...);
816 template<typename _Adaptor, typename... _Args>
819 template<typename _Lhs, typename _Rhs>
822 // The base class of every range adaptor closure.
824 // The derived class should define the optional static data member
825 // _S_has_simple_call_op to true if the behavior of this adaptor is
826 // independent of the constness/value category of the adaptor object.
827 struct _RangeAdaptorClosure
829 // range | adaptor is equivalent to adaptor(range).
830 template<typename _Self, typename _Range>
831 requires derived_from<remove_cvref_t<_Self>, _RangeAdaptorClosure>
832 && __adaptor_invocable<_Self, _Range>
833 friend constexpr auto
834 operator|(_Range&& __r, _Self&& __self)
835 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
837 // Compose the adaptors __lhs and __rhs into a pipeline, returning
838 // another range adaptor closure object.
839 template<typename _Lhs, typename _Rhs>
840 requires derived_from<_Lhs, _RangeAdaptorClosure>
841 && derived_from<_Rhs, _RangeAdaptorClosure>
842 friend constexpr auto
843 operator|(_Lhs __lhs, _Rhs __rhs)
844 { return _Pipe<_Lhs, _Rhs>{std::move(__lhs), std::move(__rhs)}; }
847 // The base class of every range adaptor non-closure.
849 // The static data member _Derived::_S_arity must contain the total number of
850 // arguments that the adaptor takes, and the class _Derived must introduce
851 // _RangeAdaptor::operator() into the class scope via a using-declaration.
853 // The optional static data member _Derived::_S_has_simple_extra_args should
854 // be defined to true if the behavior of this adaptor is independent of the
855 // constness/value category of the extra arguments. This data member could
856 // also be defined as a variable template parameterized by the types of the
858 template<typename _Derived>
861 // Partially apply the arguments __args to the range adaptor _Derived,
862 // returning a range adaptor closure object.
863 template<typename... _Args>
864 requires __adaptor_partial_app_viable<_Derived, _Args...>
866 operator()(_Args&&... __args) const
868 return _Partial<_Derived, decay_t<_Args>...>{std::forward<_Args>(__args)...};
872 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
873 // one that's not overloaded according to constness or value category of the
875 template<typename _Adaptor>
876 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
878 // True if the behavior of the range adaptor non-closure _Adaptor is
879 // independent of the value category of its extra arguments _Args.
880 template<typename _Adaptor, typename... _Args>
881 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
882 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
884 // A range adaptor closure that represents partial application of
885 // the range adaptor _Adaptor with arguments _Args.
886 template<typename _Adaptor, typename... _Args>
887 struct _Partial : _RangeAdaptorClosure
889 tuple<_Args...> _M_args;
892 _Partial(_Args... __args)
893 : _M_args(std::move(__args)...)
896 // Invoke _Adaptor with arguments __r, _M_args... according to the
897 // value category of this _Partial object.
898 template<typename _Range>
899 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
901 operator()(_Range&& __r) const &
903 auto __forwarder = [&__r] (const auto&... __args) {
904 return _Adaptor{}(std::forward<_Range>(__r), __args...);
906 return std::apply(__forwarder, _M_args);
909 template<typename _Range>
910 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
912 operator()(_Range&& __r) &&
914 auto __forwarder = [&__r] (auto&... __args) {
915 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
917 return std::apply(__forwarder, _M_args);
920 template<typename _Range>
922 operator()(_Range&& __r) const && = delete;
925 // A lightweight specialization of the above primary template for
926 // the common case where _Adaptor accepts a single extra argument.
927 template<typename _Adaptor, typename _Arg>
928 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
934 : _M_arg(std::move(__arg))
937 template<typename _Range>
938 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
940 operator()(_Range&& __r) const &
941 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
943 template<typename _Range>
944 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
946 operator()(_Range&& __r) &&
947 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
949 template<typename _Range>
951 operator()(_Range&& __r) const && = delete;
954 // Partial specialization of the primary template for the case where the extra
955 // arguments of the adaptor can always be safely and efficiently forwarded by
956 // const reference. This lets us get away with a single operator() overload,
957 // which makes overload resolution failure diagnostics more concise.
958 template<typename _Adaptor, typename... _Args>
959 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
960 && (is_trivially_copyable_v<_Args> && ...)
961 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure
963 tuple<_Args...> _M_args;
966 _Partial(_Args... __args)
967 : _M_args(std::move(__args)...)
970 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
971 // of the value category of this _Partial object.
972 template<typename _Range>
973 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
975 operator()(_Range&& __r) const
977 auto __forwarder = [&__r] (const auto&... __args) {
978 return _Adaptor{}(std::forward<_Range>(__r), __args...);
980 return std::apply(__forwarder, _M_args);
983 static constexpr bool _S_has_simple_call_op = true;
986 // A lightweight specialization of the above template for the common case
987 // where _Adaptor accepts a single extra argument.
988 template<typename _Adaptor, typename _Arg>
989 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
990 && is_trivially_copyable_v<_Arg>
991 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
997 : _M_arg(std::move(__arg))
1000 template<typename _Range>
1001 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1003 operator()(_Range&& __r) const
1004 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1006 static constexpr bool _S_has_simple_call_op = true;
1009 template<typename _Lhs, typename _Rhs, typename _Range>
1010 concept __pipe_invocable
1011 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1013 // A range adaptor closure that represents composition of the range
1014 // adaptor closures _Lhs and _Rhs.
1015 template<typename _Lhs, typename _Rhs>
1016 struct _Pipe : _RangeAdaptorClosure
1018 [[no_unique_address]] _Lhs _M_lhs;
1019 [[no_unique_address]] _Rhs _M_rhs;
1022 _Pipe(_Lhs __lhs, _Rhs __rhs)
1023 : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
1026 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1027 // range adaptor closure object.
1028 template<typename _Range>
1029 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1031 operator()(_Range&& __r) const &
1032 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1034 template<typename _Range>
1035 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1037 operator()(_Range&& __r) &&
1038 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1040 template<typename _Range>
1042 operator()(_Range&& __r) const && = delete;
1045 // A partial specialization of the above primary template for the case where
1046 // both adaptor operands have a simple operator(). This in turn lets us
1047 // implement composition using a single simple operator(), which makes
1048 // overload resolution failure diagnostics more concise.
1049 template<typename _Lhs, typename _Rhs>
1050 requires __closure_has_simple_call_op<_Lhs>
1051 && __closure_has_simple_call_op<_Rhs>
1052 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure
1054 [[no_unique_address]] _Lhs _M_lhs;
1055 [[no_unique_address]] _Rhs _M_rhs;
1058 _Pipe(_Lhs __lhs, _Rhs __rhs)
1059 : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
1062 template<typename _Range>
1063 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1065 operator()(_Range&& __r) const
1066 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1068 static constexpr bool _S_has_simple_call_op = true;
1070 } // namespace views::__adaptor
1072 template<range _Range> requires is_object_v<_Range>
1073 class ref_view : public view_interface<ref_view<_Range>>
1078 static void _S_fun(_Range&); // not defined
1079 static void _S_fun(_Range&&) = delete;
1082 template<__detail::__different_from<ref_view> _Tp>
1083 requires convertible_to<_Tp, _Range&>
1084 && requires { _S_fun(declval<_Tp>()); }
1087 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1088 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1095 constexpr iterator_t<_Range>
1097 { return ranges::begin(*_M_r); }
1099 constexpr sentinel_t<_Range>
1101 { return ranges::end(*_M_r); }
1104 empty() const requires requires { ranges::empty(*_M_r); }
1105 { return ranges::empty(*_M_r); }
1108 size() const requires sized_range<_Range>
1109 { return ranges::size(*_M_r); }
1112 data() const requires contiguous_range<_Range>
1113 { return ranges::data(*_M_r); }
1116 template<typename _Range>
1117 ref_view(_Range&) -> ref_view<_Range>;
1119 template<typename _Tp>
1120 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1126 template<typename _Range>
1127 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1129 template<typename _Range>
1130 concept __can_subrange = requires { subrange{std::declval<_Range>()}; };
1131 } // namespace __detail
1133 struct _All : __adaptor::_RangeAdaptorClosure
1135 template<typename _Range>
1136 static constexpr bool
1139 if constexpr (view<decay_t<_Range>>)
1140 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1141 else if constexpr (__detail::__can_ref_view<_Range>)
1144 return noexcept(subrange{std::declval<_Range>()});
1147 template<viewable_range _Range>
1148 requires view<decay_t<_Range>>
1149 || __detail::__can_ref_view<_Range>
1150 || __detail::__can_subrange<_Range>
1152 operator() [[nodiscard]] (_Range&& __r) const
1153 noexcept(_S_noexcept<_Range>())
1155 if constexpr (view<decay_t<_Range>>)
1156 return std::forward<_Range>(__r);
1157 else if constexpr (__detail::__can_ref_view<_Range>)
1158 return ref_view{std::forward<_Range>(__r)};
1160 return subrange{std::forward<_Range>(__r)};
1163 static constexpr bool _S_has_simple_call_op = true;
1166 inline constexpr _All all;
1168 template<viewable_range _Range>
1169 using all_t = decltype(all(std::declval<_Range>()));
1170 } // namespace views
1174 template<typename _Tp>
1175 struct __non_propagating_cache
1177 // When _Tp is not an object type (e.g. is a reference type), we make
1178 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1179 // users can easily conditionally declare data members with this type
1180 // (such as join_view::_M_inner).
1183 template<typename _Tp>
1184 requires is_object_v<_Tp>
1185 struct __non_propagating_cache<_Tp>
1186 : protected _Optional_base<_Tp>
1188 __non_propagating_cache() = default;
1191 __non_propagating_cache(const __non_propagating_cache&) noexcept
1195 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1196 { __other._M_reset(); }
1198 constexpr __non_propagating_cache&
1199 operator=(const __non_propagating_cache& __other) noexcept
1201 if (std::__addressof(__other) != this)
1206 constexpr __non_propagating_cache&
1207 operator=(__non_propagating_cache&& __other) noexcept
1214 constexpr __non_propagating_cache&
1215 operator=(_Tp __val)
1218 this->_M_payload._M_construct(std::move(__val));
1223 operator bool() const noexcept
1224 { return this->_M_is_engaged(); }
1227 operator*() noexcept
1228 { return this->_M_get(); }
1230 constexpr const _Tp&
1231 operator*() const noexcept
1232 { return this->_M_get(); }
1234 template<typename _Iter>
1236 _M_emplace_deref(const _Iter& __i)
1239 auto __f = [] (auto& __x) { return *__x; };
1240 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1241 return this->_M_get();
1245 template<range _Range>
1246 struct _CachedPosition
1249 _M_has_value() const
1252 constexpr iterator_t<_Range>
1253 _M_get(const _Range&) const
1255 __glibcxx_assert(false);
1256 __builtin_unreachable();
1260 _M_set(const _Range&, const iterator_t<_Range>&) const
1264 template<forward_range _Range>
1265 struct _CachedPosition<_Range>
1266 : protected __non_propagating_cache<iterator_t<_Range>>
1269 _M_has_value() const
1270 { return this->_M_is_engaged(); }
1272 constexpr iterator_t<_Range>
1273 _M_get(const _Range&) const
1275 __glibcxx_assert(_M_has_value());
1280 _M_set(const _Range&, const iterator_t<_Range>& __it)
1282 __glibcxx_assert(!_M_has_value());
1283 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1285 this->_M_payload._M_engaged = true;
1289 template<random_access_range _Range>
1290 requires (sizeof(range_difference_t<_Range>)
1291 <= sizeof(iterator_t<_Range>))
1292 struct _CachedPosition<_Range>
1295 range_difference_t<_Range> _M_offset = -1;
1298 _CachedPosition() = default;
1301 _CachedPosition(const _CachedPosition&) = default;
1304 _CachedPosition(_CachedPosition&& __other) noexcept
1305 { *this = std::move(__other); }
1307 constexpr _CachedPosition&
1308 operator=(const _CachedPosition&) = default;
1310 constexpr _CachedPosition&
1311 operator=(_CachedPosition&& __other) noexcept
1313 // Propagate the cached offset, but invalidate the source.
1314 _M_offset = __other._M_offset;
1315 __other._M_offset = -1;
1320 _M_has_value() const
1321 { return _M_offset >= 0; }
1323 constexpr iterator_t<_Range>
1324 _M_get(_Range& __r) const
1326 __glibcxx_assert(_M_has_value());
1327 return ranges::begin(__r) + _M_offset;
1331 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1333 __glibcxx_assert(!_M_has_value());
1334 _M_offset = __it - ranges::begin(__r);
1337 } // namespace __detail
1341 template<typename _Base>
1342 struct __filter_view_iter_cat
1345 template<forward_range _Base>
1346 struct __filter_view_iter_cat<_Base>
1352 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1353 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1354 return bidirectional_iterator_tag{};
1355 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1356 return forward_iterator_tag{};
1361 using iterator_category = decltype(_S_iter_cat());
1363 } // namespace __detail
1365 template<input_range _Vp,
1366 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1367 requires view<_Vp> && is_object_v<_Pred>
1368 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1373 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1376 static constexpr auto
1379 if constexpr (bidirectional_range<_Vp>)
1380 return bidirectional_iterator_tag{};
1381 else if constexpr (forward_range<_Vp>)
1382 return forward_iterator_tag{};
1384 return input_iterator_tag{};
1389 using _Vp_iter = iterator_t<_Vp>;
1391 _Vp_iter _M_current = _Vp_iter();
1392 filter_view* _M_parent = nullptr;
1395 using iterator_concept = decltype(_S_iter_concept());
1396 // iterator_category defined in __filter_view_iter_cat
1397 using value_type = range_value_t<_Vp>;
1398 using difference_type = range_difference_t<_Vp>;
1400 _Iterator() requires default_initializable<_Vp_iter> = default;
1403 _Iterator(filter_view* __parent, _Vp_iter __current)
1404 : _M_current(std::move(__current)),
1408 constexpr const _Vp_iter&
1409 base() const & noexcept
1410 { return _M_current; }
1414 { return std::move(_M_current); }
1416 constexpr range_reference_t<_Vp>
1418 { return *_M_current; }
1422 requires __detail::__has_arrow<_Vp_iter>
1423 && copyable<_Vp_iter>
1424 { return _M_current; }
1426 constexpr _Iterator&
1429 _M_current = ranges::find_if(std::move(++_M_current),
1430 ranges::end(_M_parent->_M_base),
1431 std::ref(*_M_parent->_M_pred));
1440 operator++(int) requires forward_range<_Vp>
1447 constexpr _Iterator&
1448 operator--() requires bidirectional_range<_Vp>
1452 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1457 operator--(int) requires bidirectional_range<_Vp>
1464 friend constexpr bool
1465 operator==(const _Iterator& __x, const _Iterator& __y)
1466 requires equality_comparable<_Vp_iter>
1467 { return __x._M_current == __y._M_current; }
1469 friend constexpr range_rvalue_reference_t<_Vp>
1470 iter_move(const _Iterator& __i)
1471 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1472 { return ranges::iter_move(__i._M_current); }
1474 friend constexpr void
1475 iter_swap(const _Iterator& __x, const _Iterator& __y)
1476 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1477 requires indirectly_swappable<_Vp_iter>
1478 { ranges::iter_swap(__x._M_current, __y._M_current); }
1484 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1487 __equal(const _Iterator& __i) const
1488 { return __i._M_current == _M_end; }
1491 _Sentinel() = default;
1494 _Sentinel(filter_view* __parent)
1495 : _M_end(ranges::end(__parent->_M_base))
1498 constexpr sentinel_t<_Vp>
1502 friend constexpr bool
1503 operator==(const _Iterator& __x, const _Sentinel& __y)
1504 { return __y.__equal(__x); }
1507 _Vp _M_base = _Vp();
1508 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1509 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1512 filter_view() requires (default_initializable<_Vp>
1513 && default_initializable<_Pred>)
1517 filter_view(_Vp __base, _Pred __pred)
1518 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1522 base() const& requires copy_constructible<_Vp>
1527 { return std::move(_M_base); }
1529 constexpr const _Pred&
1531 { return *_M_pred; }
1536 if (_M_cached_begin._M_has_value())
1537 return {this, _M_cached_begin._M_get(_M_base)};
1539 __glibcxx_assert(_M_pred.has_value());
1540 auto __it = ranges::find_if(ranges::begin(_M_base),
1541 ranges::end(_M_base),
1542 std::ref(*_M_pred));
1543 _M_cached_begin._M_set(_M_base, __it);
1544 return {this, std::move(__it)};
1550 if constexpr (common_range<_Vp>)
1551 return _Iterator{this, ranges::end(_M_base)};
1553 return _Sentinel{this};
1557 template<typename _Range, typename _Pred>
1558 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1564 template<typename _Range, typename _Pred>
1565 concept __can_filter_view
1566 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1567 } // namespace __detail
1569 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1571 template<viewable_range _Range, typename _Pred>
1572 requires __detail::__can_filter_view<_Range, _Pred>
1574 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1576 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1579 using _RangeAdaptor<_Filter>::operator();
1580 static constexpr int _S_arity = 2;
1581 static constexpr bool _S_has_simple_extra_args = true;
1584 inline constexpr _Filter filter;
1585 } // namespace views
1587 template<input_range _Vp, copy_constructible _Fp>
1588 requires view<_Vp> && is_object_v<_Fp>
1589 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1590 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1591 range_reference_t<_Vp>>>
1592 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1595 template<bool _Const>
1596 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1598 template<bool _Const>
1602 template<bool _Const>
1603 requires forward_range<_Base<_Const>>
1604 struct __iter_cat<_Const>
1610 using _Base = transform_view::_Base<_Const>;
1611 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1612 if constexpr (is_lvalue_reference_v<_Res>)
1615 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1616 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1617 return random_access_iterator_tag{};
1622 return input_iterator_tag{};
1625 using iterator_category = decltype(_S_iter_cat());
1628 template<bool _Const>
1631 template<bool _Const>
1632 struct _Iterator : __iter_cat<_Const>
1635 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1636 using _Base = transform_view::_Base<_Const>;
1641 if constexpr (random_access_range<_Base>)
1642 return random_access_iterator_tag{};
1643 else if constexpr (bidirectional_range<_Base>)
1644 return bidirectional_iterator_tag{};
1645 else if constexpr (forward_range<_Base>)
1646 return forward_iterator_tag{};
1648 return input_iterator_tag{};
1651 using _Base_iter = iterator_t<_Base>;
1653 _Base_iter _M_current = _Base_iter();
1654 _Parent* _M_parent = nullptr;
1657 using iterator_concept = decltype(_S_iter_concept());
1658 // iterator_category defined in __transform_view_iter_cat
1660 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1661 using difference_type = range_difference_t<_Base>;
1663 _Iterator() requires default_initializable<_Base_iter> = default;
1666 _Iterator(_Parent* __parent, _Base_iter __current)
1667 : _M_current(std::move(__current)),
1672 _Iterator(_Iterator<!_Const> __i)
1674 && convertible_to<iterator_t<_Vp>, _Base_iter>
1675 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1678 constexpr const _Base_iter&
1679 base() const & noexcept
1680 { return _M_current; }
1682 constexpr _Base_iter
1684 { return std::move(_M_current); }
1686 constexpr decltype(auto)
1688 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1689 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1691 constexpr _Iterator&
1703 operator++(int) requires forward_range<_Base>
1710 constexpr _Iterator&
1711 operator--() requires bidirectional_range<_Base>
1718 operator--(int) requires bidirectional_range<_Base>
1725 constexpr _Iterator&
1726 operator+=(difference_type __n) requires random_access_range<_Base>
1732 constexpr _Iterator&
1733 operator-=(difference_type __n) requires random_access_range<_Base>
1739 constexpr decltype(auto)
1740 operator[](difference_type __n) const
1741 requires random_access_range<_Base>
1742 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1744 friend constexpr bool
1745 operator==(const _Iterator& __x, const _Iterator& __y)
1746 requires equality_comparable<_Base_iter>
1747 { return __x._M_current == __y._M_current; }
1749 friend constexpr bool
1750 operator<(const _Iterator& __x, const _Iterator& __y)
1751 requires random_access_range<_Base>
1752 { return __x._M_current < __y._M_current; }
1754 friend constexpr bool
1755 operator>(const _Iterator& __x, const _Iterator& __y)
1756 requires random_access_range<_Base>
1757 { return __y < __x; }
1759 friend constexpr bool
1760 operator<=(const _Iterator& __x, const _Iterator& __y)
1761 requires random_access_range<_Base>
1762 { return !(__y < __x); }
1764 friend constexpr bool
1765 operator>=(const _Iterator& __x, const _Iterator& __y)
1766 requires random_access_range<_Base>
1767 { return !(__x < __y); }
1769 #ifdef __cpp_lib_three_way_comparison
1770 friend constexpr auto
1771 operator<=>(const _Iterator& __x, const _Iterator& __y)
1772 requires random_access_range<_Base>
1773 && three_way_comparable<_Base_iter>
1774 { return __x._M_current <=> __y._M_current; }
1777 friend constexpr _Iterator
1778 operator+(_Iterator __i, difference_type __n)
1779 requires random_access_range<_Base>
1780 { return {__i._M_parent, __i._M_current + __n}; }
1782 friend constexpr _Iterator
1783 operator+(difference_type __n, _Iterator __i)
1784 requires random_access_range<_Base>
1785 { return {__i._M_parent, __i._M_current + __n}; }
1787 friend constexpr _Iterator
1788 operator-(_Iterator __i, difference_type __n)
1789 requires random_access_range<_Base>
1790 { return {__i._M_parent, __i._M_current - __n}; }
1792 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1793 // 3483. transform_view::iterator's difference is overconstrained
1794 friend constexpr difference_type
1795 operator-(const _Iterator& __x, const _Iterator& __y)
1796 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
1797 { return __x._M_current - __y._M_current; }
1799 friend constexpr decltype(auto)
1800 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
1802 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
1803 return std::move(*__i);
1808 friend _Iterator<!_Const>;
1809 template<bool> friend struct _Sentinel;
1812 template<bool _Const>
1816 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1817 using _Base = transform_view::_Base<_Const>;
1819 template<bool _Const2>
1821 __distance_from(const _Iterator<_Const2>& __i) const
1822 { return _M_end - __i._M_current; }
1824 template<bool _Const2>
1826 __equal(const _Iterator<_Const2>& __i) const
1827 { return __i._M_current == _M_end; }
1829 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1832 _Sentinel() = default;
1835 _Sentinel(sentinel_t<_Base> __end)
1840 _Sentinel(_Sentinel<!_Const> __i)
1842 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1843 : _M_end(std::move(__i._M_end))
1846 constexpr sentinel_t<_Base>
1850 template<bool _Const2>
1851 requires sentinel_for<sentinel_t<_Base>,
1852 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
1853 friend constexpr bool
1854 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1855 { return __y.__equal(__x); }
1857 template<bool _Const2,
1858 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1859 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1860 friend constexpr range_difference_t<_Base2>
1861 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1862 { return -__y.__distance_from(__x); }
1864 template<bool _Const2,
1865 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1866 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1867 friend constexpr range_difference_t<_Base2>
1868 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
1869 { return __y.__distance_from(__x); }
1871 friend _Sentinel<!_Const>;
1874 _Vp _M_base = _Vp();
1875 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
1878 transform_view() requires (default_initializable<_Vp>
1879 && default_initializable<_Fp>)
1883 transform_view(_Vp __base, _Fp __fun)
1884 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
1888 base() const& requires copy_constructible<_Vp>
1889 { return _M_base ; }
1893 { return std::move(_M_base); }
1895 constexpr _Iterator<false>
1897 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
1899 constexpr _Iterator<true>
1901 requires range<const _Vp>
1902 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1903 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
1905 constexpr _Sentinel<false>
1907 { return _Sentinel<false>{ranges::end(_M_base)}; }
1909 constexpr _Iterator<false>
1910 end() requires common_range<_Vp>
1911 { return _Iterator<false>{this, ranges::end(_M_base)}; }
1913 constexpr _Sentinel<true>
1915 requires range<const _Vp>
1916 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1917 { return _Sentinel<true>{ranges::end(_M_base)}; }
1919 constexpr _Iterator<true>
1921 requires common_range<const _Vp>
1922 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1923 { return _Iterator<true>{this, ranges::end(_M_base)}; }
1926 size() requires sized_range<_Vp>
1927 { return ranges::size(_M_base); }
1930 size() const requires sized_range<const _Vp>
1931 { return ranges::size(_M_base); }
1934 template<typename _Range, typename _Fp>
1935 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
1941 template<typename _Range, typename _Fp>
1942 concept __can_transform_view
1943 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
1944 } // namespace __detail
1946 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
1948 template<viewable_range _Range, typename _Fp>
1949 requires __detail::__can_transform_view<_Range, _Fp>
1951 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
1953 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
1956 using _RangeAdaptor<_Transform>::operator();
1957 static constexpr int _S_arity = 2;
1958 static constexpr bool _S_has_simple_extra_args = true;
1961 inline constexpr _Transform transform;
1962 } // namespace views
1965 class take_view : public view_interface<take_view<_Vp>>
1968 template<bool _Const>
1969 using _CI = counted_iterator<
1970 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
1972 template<bool _Const>
1976 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1977 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1980 _Sentinel() = default;
1983 _Sentinel(sentinel_t<_Base> __end)
1988 _Sentinel(_Sentinel<!_Const> __s)
1989 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1990 : _M_end(std::move(__s._M_end))
1993 constexpr sentinel_t<_Base>
1997 friend constexpr bool
1998 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
1999 { return __y.count() == 0 || __y.base() == __x._M_end; }
2001 template<bool _OtherConst = !_Const,
2002 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2003 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2004 friend constexpr bool
2005 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2006 { return __y.count() == 0 || __y.base() == __x._M_end; }
2008 friend _Sentinel<!_Const>;
2011 _Vp _M_base = _Vp();
2012 range_difference_t<_Vp> _M_count = 0;
2015 take_view() requires default_initializable<_Vp> = default;
2018 take_view(_Vp base, range_difference_t<_Vp> __count)
2019 : _M_base(std::move(base)), _M_count(std::move(__count))
2023 base() const& requires copy_constructible<_Vp>
2028 { return std::move(_M_base); }
2031 begin() requires (!__detail::__simple_view<_Vp>)
2033 if constexpr (sized_range<_Vp>)
2035 if constexpr (random_access_range<_Vp>)
2036 return ranges::begin(_M_base);
2040 return counted_iterator(ranges::begin(_M_base), __sz);
2044 return counted_iterator(ranges::begin(_M_base), _M_count);
2048 begin() const requires range<const _Vp>
2050 if constexpr (sized_range<const _Vp>)
2052 if constexpr (random_access_range<const _Vp>)
2053 return ranges::begin(_M_base);
2057 return counted_iterator(ranges::begin(_M_base), __sz);
2061 return counted_iterator(ranges::begin(_M_base), _M_count);
2065 end() requires (!__detail::__simple_view<_Vp>)
2067 if constexpr (sized_range<_Vp>)
2069 if constexpr (random_access_range<_Vp>)
2070 return ranges::begin(_M_base) + size();
2072 return default_sentinel;
2075 return _Sentinel<false>{ranges::end(_M_base)};
2079 end() const requires range<const _Vp>
2081 if constexpr (sized_range<const _Vp>)
2083 if constexpr (random_access_range<const _Vp>)
2084 return ranges::begin(_M_base) + size();
2086 return default_sentinel;
2089 return _Sentinel<true>{ranges::end(_M_base)};
2093 size() requires sized_range<_Vp>
2095 auto __n = ranges::size(_M_base);
2096 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2100 size() const requires sized_range<const _Vp>
2102 auto __n = ranges::size(_M_base);
2103 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2107 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2108 // 3447. Deduction guides for take_view and drop_view have different
2110 template<typename _Range>
2111 take_view(_Range&&, range_difference_t<_Range>)
2112 -> take_view<views::all_t<_Range>>;
2114 template<typename _Tp>
2115 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2116 = enable_borrowed_range<_Tp>;
2122 template<typename _Range, typename _Tp>
2123 concept __can_take_view
2124 = requires { take_view(std::declval<_Range>(), std::declval<_Tp>()); };
2125 } // namespace __detail
2127 struct _Take : __adaptor::_RangeAdaptor<_Take>
2129 template<viewable_range _Range, typename _Tp>
2130 requires __detail::__can_take_view<_Range, _Tp>
2132 operator() [[nodiscard]] (_Range&& __r, _Tp&& __n) const
2134 return take_view(std::forward<_Range>(__r), std::forward<_Tp>(__n));
2137 using _RangeAdaptor<_Take>::operator();
2138 static constexpr int _S_arity = 2;
2139 // The count argument of views::take is not always simple -- it can be
2140 // e.g. a move-only class that's implicitly convertible to the difference
2141 // type. But an integer-like count argument is surely simple.
2142 template<typename _Tp>
2143 static constexpr bool _S_has_simple_extra_args
2144 = ranges::__detail::__is_integer_like<_Tp>;
2147 inline constexpr _Take take;
2148 } // namespace views
2150 template<view _Vp, typename _Pred>
2151 requires input_range<_Vp> && is_object_v<_Pred>
2152 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2153 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2155 template<bool _Const>
2159 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2161 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2162 const _Pred* _M_pred = nullptr;
2165 _Sentinel() = default;
2168 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2169 : _M_end(__end), _M_pred(__pred)
2173 _Sentinel(_Sentinel<!_Const> __s)
2174 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2175 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2178 constexpr sentinel_t<_Base>
2179 base() const { return _M_end; }
2181 friend constexpr bool
2182 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2183 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2185 template<bool _OtherConst = !_Const,
2186 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2187 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2188 friend constexpr bool
2189 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2190 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2192 friend _Sentinel<!_Const>;
2195 _Vp _M_base = _Vp();
2196 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2199 take_while_view() requires (default_initializable<_Vp>
2200 && default_initializable<_Pred>)
2204 take_while_view(_Vp base, _Pred __pred)
2205 : _M_base(std::move(base)), _M_pred(std::move(__pred))
2209 base() const& requires copy_constructible<_Vp>
2214 { return std::move(_M_base); }
2216 constexpr const _Pred&
2218 { return *_M_pred; }
2221 begin() requires (!__detail::__simple_view<_Vp>)
2222 { return ranges::begin(_M_base); }
2225 begin() const requires range<const _Vp>
2226 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2227 { return ranges::begin(_M_base); }
2230 end() requires (!__detail::__simple_view<_Vp>)
2231 { return _Sentinel<false>(ranges::end(_M_base),
2232 std::__addressof(*_M_pred)); }
2235 end() const requires range<const _Vp>
2236 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2237 { return _Sentinel<true>(ranges::end(_M_base),
2238 std::__addressof(*_M_pred)); }
2241 template<typename _Range, typename _Pred>
2242 take_while_view(_Range&&, _Pred)
2243 -> take_while_view<views::all_t<_Range>, _Pred>;
2249 template<typename _Range, typename _Pred>
2250 concept __can_take_while_view
2251 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2252 } // namespace __detail
2254 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2256 template<viewable_range _Range, typename _Pred>
2257 requires __detail::__can_take_while_view<_Range, _Pred>
2259 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2261 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2264 using _RangeAdaptor<_TakeWhile>::operator();
2265 static constexpr int _S_arity = 2;
2266 static constexpr bool _S_has_simple_extra_args = true;
2269 inline constexpr _TakeWhile take_while;
2270 } // namespace views
2273 class drop_view : public view_interface<drop_view<_Vp>>
2276 _Vp _M_base = _Vp();
2277 range_difference_t<_Vp> _M_count = 0;
2279 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2280 // both random_access_range and sized_range. Otherwise, cache its result.
2281 static constexpr bool _S_needs_cached_begin
2282 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2283 [[no_unique_address]]
2284 __detail::__maybe_present_t<_S_needs_cached_begin,
2285 __detail::_CachedPosition<_Vp>>
2289 drop_view() requires default_initializable<_Vp> = default;
2292 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2293 : _M_base(std::move(__base)), _M_count(__count)
2294 { __glibcxx_assert(__count >= 0); }
2297 base() const& requires copy_constructible<_Vp>
2302 { return std::move(_M_base); }
2304 // This overload is disabled for simple views with constant-time begin().
2307 requires (!(__detail::__simple_view<_Vp>
2308 && random_access_range<const _Vp>
2309 && sized_range<const _Vp>))
2311 if constexpr (_S_needs_cached_begin)
2312 if (_M_cached_begin._M_has_value())
2313 return _M_cached_begin._M_get(_M_base);
2315 auto __it = ranges::next(ranges::begin(_M_base),
2316 _M_count, ranges::end(_M_base));
2317 if constexpr (_S_needs_cached_begin)
2318 _M_cached_begin._M_set(_M_base, __it);
2322 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2323 // 3482. drop_view's const begin should additionally require sized_range
2326 requires random_access_range<const _Vp> && sized_range<const _Vp>
2328 return ranges::next(ranges::begin(_M_base), _M_count,
2329 ranges::end(_M_base));
2333 end() requires (!__detail::__simple_view<_Vp>)
2334 { return ranges::end(_M_base); }
2337 end() const requires range<const _Vp>
2338 { return ranges::end(_M_base); }
2341 size() requires sized_range<_Vp>
2343 const auto __s = ranges::size(_M_base);
2344 const auto __c = static_cast<decltype(__s)>(_M_count);
2345 return __s < __c ? 0 : __s - __c;
2349 size() const requires sized_range<const _Vp>
2351 const auto __s = ranges::size(_M_base);
2352 const auto __c = static_cast<decltype(__s)>(_M_count);
2353 return __s < __c ? 0 : __s - __c;
2357 template<typename _Range>
2358 drop_view(_Range&&, range_difference_t<_Range>)
2359 -> drop_view<views::all_t<_Range>>;
2361 template<typename _Tp>
2362 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2363 = enable_borrowed_range<_Tp>;
2369 template<typename _Range, typename _Tp>
2370 concept __can_drop_view
2371 = requires { drop_view(std::declval<_Range>(), std::declval<_Tp>()); };
2372 } // namespace __detail
2374 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2376 template<viewable_range _Range, typename _Tp>
2377 requires __detail::__can_drop_view<_Range, _Tp>
2379 operator() [[nodiscard]] (_Range&& __r, _Tp&& __n) const
2381 return drop_view(std::forward<_Range>(__r), std::forward<_Tp>(__n));
2384 using _RangeAdaptor<_Drop>::operator();
2385 static constexpr int _S_arity = 2;
2386 template<typename _Tp>
2387 static constexpr bool _S_has_simple_extra_args
2388 = _Take::_S_has_simple_extra_args<_Tp>;
2391 inline constexpr _Drop drop;
2392 } // namespace views
2394 template<view _Vp, typename _Pred>
2395 requires input_range<_Vp> && is_object_v<_Pred>
2396 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2397 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2400 _Vp _M_base = _Vp();
2401 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2402 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2405 drop_while_view() requires (default_initializable<_Vp>
2406 && default_initializable<_Pred>)
2410 drop_while_view(_Vp __base, _Pred __pred)
2411 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2415 base() const& requires copy_constructible<_Vp>
2420 { return std::move(_M_base); }
2422 constexpr const _Pred&
2424 { return *_M_pred; }
2429 if (_M_cached_begin._M_has_value())
2430 return _M_cached_begin._M_get(_M_base);
2432 __glibcxx_assert(_M_pred.has_value());
2433 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2434 ranges::end(_M_base),
2435 std::cref(*_M_pred));
2436 _M_cached_begin._M_set(_M_base, __it);
2442 { return ranges::end(_M_base); }
2445 template<typename _Range, typename _Pred>
2446 drop_while_view(_Range&&, _Pred)
2447 -> drop_while_view<views::all_t<_Range>, _Pred>;
2449 template<typename _Tp, typename _Pred>
2450 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2451 = enable_borrowed_range<_Tp>;
2457 template<typename _Range, typename _Pred>
2458 concept __can_drop_while_view
2459 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2460 } // namespace __detail
2462 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2464 template<viewable_range _Range, typename _Pred>
2465 requires __detail::__can_drop_while_view<_Range, _Pred>
2467 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2469 return drop_while_view(std::forward<_Range>(__r),
2470 std::forward<_Pred>(__p));
2473 using _RangeAdaptor<_DropWhile>::operator();
2474 static constexpr int _S_arity = 2;
2475 static constexpr bool _S_has_simple_extra_args = true;
2478 inline constexpr _DropWhile drop_while;
2479 } // namespace views
2481 template<input_range _Vp>
2482 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2483 class join_view : public view_interface<join_view<_Vp>>
2486 using _InnerRange = range_reference_t<_Vp>;
2488 template<bool _Const>
2489 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2491 template<bool _Const>
2492 using _Outer_iter = iterator_t<_Base<_Const>>;
2494 template<bool _Const>
2495 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2497 template<bool _Const>
2498 static constexpr bool _S_ref_is_glvalue
2499 = is_reference_v<range_reference_t<_Base<_Const>>>;
2501 template<bool _Const>
2505 template<bool _Const>
2506 requires _S_ref_is_glvalue<_Const>
2507 && forward_range<_Base<_Const>>
2508 && forward_range<range_reference_t<_Base<_Const>>>
2509 struct __iter_cat<_Const>
2512 static constexpr auto
2515 using _Outer_iter = join_view::_Outer_iter<_Const>;
2516 using _Inner_iter = join_view::_Inner_iter<_Const>;
2517 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2518 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2519 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2520 && derived_from<_InnerCat, bidirectional_iterator_tag>)
2521 return bidirectional_iterator_tag{};
2522 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2523 && derived_from<_InnerCat, forward_iterator_tag>)
2524 return forward_iterator_tag{};
2526 return input_iterator_tag{};
2529 using iterator_category = decltype(_S_iter_cat());
2532 template<bool _Const>
2535 template<bool _Const>
2536 struct _Iterator : __iter_cat<_Const>
2539 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2540 using _Base = join_view::_Base<_Const>;
2542 static constexpr bool _S_ref_is_glvalue
2543 = join_view::_S_ref_is_glvalue<_Const>;
2548 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2549 if constexpr (_S_ref_is_glvalue)
2552 return _M_parent->_M_inner._M_emplace_deref(__x);
2555 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2557 auto&& __inner = __update_inner(_M_outer);
2558 _M_inner = ranges::begin(__inner);
2559 if (_M_inner != ranges::end(__inner))
2563 if constexpr (_S_ref_is_glvalue)
2564 _M_inner = _Inner_iter();
2567 static constexpr auto
2570 if constexpr (_S_ref_is_glvalue
2571 && bidirectional_range<_Base>
2572 && bidirectional_range<range_reference_t<_Base>>)
2573 return bidirectional_iterator_tag{};
2574 else if constexpr (_S_ref_is_glvalue
2575 && forward_range<_Base>
2576 && forward_range<range_reference_t<_Base>>)
2577 return forward_iterator_tag{};
2579 return input_iterator_tag{};
2582 using _Outer_iter = join_view::_Outer_iter<_Const>;
2583 using _Inner_iter = join_view::_Inner_iter<_Const>;
2585 _Outer_iter _M_outer = _Outer_iter();
2586 _Inner_iter _M_inner = _Inner_iter();
2587 _Parent* _M_parent = nullptr;
2590 using iterator_concept = decltype(_S_iter_concept());
2591 // iterator_category defined in __join_view_iter_cat
2592 using value_type = range_value_t<range_reference_t<_Base>>;
2593 using difference_type
2594 = common_type_t<range_difference_t<_Base>,
2595 range_difference_t<range_reference_t<_Base>>>;
2597 _Iterator() requires (default_initializable<_Outer_iter>
2598 && default_initializable<_Inner_iter>)
2602 _Iterator(_Parent* __parent, _Outer_iter __outer)
2603 : _M_outer(std::move(__outer)),
2608 _Iterator(_Iterator<!_Const> __i)
2610 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2611 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2612 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
2613 _M_parent(__i._M_parent)
2616 constexpr decltype(auto)
2618 { return *_M_inner; }
2620 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2621 // 3500. join_view::iterator::operator->() is bogus
2622 constexpr _Inner_iter
2624 requires __detail::__has_arrow<_Inner_iter>
2625 && copyable<_Inner_iter>
2626 { return _M_inner; }
2628 constexpr _Iterator&
2631 auto&& __inner_range = [this] () -> auto&& {
2632 if constexpr (_S_ref_is_glvalue)
2635 return *_M_parent->_M_inner;
2637 if (++_M_inner == ranges::end(__inner_range))
2651 requires _S_ref_is_glvalue && forward_range<_Base>
2652 && forward_range<range_reference_t<_Base>>
2659 constexpr _Iterator&
2661 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2662 && bidirectional_range<range_reference_t<_Base>>
2663 && common_range<range_reference_t<_Base>>
2665 if (_M_outer == ranges::end(_M_parent->_M_base))
2666 _M_inner = ranges::end(*--_M_outer);
2667 while (_M_inner == ranges::begin(*_M_outer))
2668 _M_inner = ranges::end(*--_M_outer);
2675 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2676 && bidirectional_range<range_reference_t<_Base>>
2677 && common_range<range_reference_t<_Base>>
2684 friend constexpr bool
2685 operator==(const _Iterator& __x, const _Iterator& __y)
2686 requires _S_ref_is_glvalue
2687 && equality_comparable<_Outer_iter>
2688 && equality_comparable<_Inner_iter>
2690 return (__x._M_outer == __y._M_outer
2691 && __x._M_inner == __y._M_inner);
2694 friend constexpr decltype(auto)
2695 iter_move(const _Iterator& __i)
2696 noexcept(noexcept(ranges::iter_move(__i._M_inner)))
2697 { return ranges::iter_move(__i._M_inner); }
2699 friend constexpr void
2700 iter_swap(const _Iterator& __x, const _Iterator& __y)
2701 noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner)))
2702 requires indirectly_swappable<_Inner_iter>
2703 { return ranges::iter_swap(__x._M_inner, __y._M_inner); }
2705 friend _Iterator<!_Const>;
2706 template<bool> friend struct _Sentinel;
2709 template<bool _Const>
2713 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2714 using _Base = join_view::_Base<_Const>;
2716 template<bool _Const2>
2718 __equal(const _Iterator<_Const2>& __i) const
2719 { return __i._M_outer == _M_end; }
2721 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2724 _Sentinel() = default;
2727 _Sentinel(_Parent* __parent)
2728 : _M_end(ranges::end(__parent->_M_base))
2732 _Sentinel(_Sentinel<!_Const> __s)
2733 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2734 : _M_end(std::move(__s._M_end))
2737 template<bool _Const2>
2738 requires sentinel_for<sentinel_t<_Base>,
2739 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2740 friend constexpr bool
2741 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2742 { return __y.__equal(__x); }
2744 friend _Sentinel<!_Const>;
2747 _Vp _M_base = _Vp();
2748 [[no_unique_address]]
2749 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
2752 join_view() requires default_initializable<_Vp> = default;
2755 join_view(_Vp __base)
2756 : _M_base(std::move(__base))
2760 base() const& requires copy_constructible<_Vp>
2765 { return std::move(_M_base); }
2770 constexpr bool __use_const
2771 = (__detail::__simple_view<_Vp>
2772 && is_reference_v<range_reference_t<_Vp>>);
2773 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
2778 requires input_range<const _Vp>
2779 && is_reference_v<range_reference_t<const _Vp>>
2781 return _Iterator<true>{this, ranges::begin(_M_base)};
2787 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
2788 && forward_range<_InnerRange>
2789 && common_range<_Vp> && common_range<_InnerRange>)
2790 return _Iterator<__detail::__simple_view<_Vp>>{this,
2791 ranges::end(_M_base)};
2793 return _Sentinel<__detail::__simple_view<_Vp>>{this};
2798 requires input_range<const _Vp>
2799 && is_reference_v<range_reference_t<const _Vp>>
2801 if constexpr (forward_range<const _Vp>
2802 && is_reference_v<range_reference_t<const _Vp>>
2803 && forward_range<range_reference_t<const _Vp>>
2804 && common_range<const _Vp>
2805 && common_range<range_reference_t<const _Vp>>)
2806 return _Iterator<true>{this, ranges::end(_M_base)};
2808 return _Sentinel<true>{this};
2812 template<typename _Range>
2813 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
2819 template<typename _Range>
2820 concept __can_join_view
2821 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
2822 } // namespace __detail
2824 struct _Join : __adaptor::_RangeAdaptorClosure
2826 template<viewable_range _Range>
2827 requires __detail::__can_join_view<_Range>
2829 operator() [[nodiscard]] (_Range&& __r) const
2831 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2832 // 3474. Nesting join_views is broken because of CTAD
2833 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
2836 static constexpr bool _S_has_simple_call_op = true;
2839 inline constexpr _Join join;
2840 } // namespace views
2845 struct __require_constant;
2847 template<typename _Range>
2848 concept __tiny_range = sized_range<_Range>
2850 { typename __require_constant<remove_reference_t<_Range>::size()>; }
2851 && (remove_reference_t<_Range>::size() <= 1);
2853 template<typename _Base>
2854 struct __lazy_split_view_outer_iter_cat
2857 template<forward_range _Base>
2858 struct __lazy_split_view_outer_iter_cat<_Base>
2859 { using iterator_category = input_iterator_tag; };
2861 template<typename _Base>
2862 struct __lazy_split_view_inner_iter_cat
2865 template<forward_range _Base>
2866 struct __lazy_split_view_inner_iter_cat<_Base>
2869 static constexpr auto
2872 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
2873 if constexpr (derived_from<_Cat, forward_iterator_tag>)
2874 return forward_iterator_tag{};
2879 using iterator_category = decltype(_S_iter_cat());
2883 template<input_range _Vp, forward_range _Pattern>
2884 requires view<_Vp> && view<_Pattern>
2885 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
2887 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
2888 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
2891 template<bool _Const>
2892 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2894 template<bool _Const>
2897 template<bool _Const>
2899 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
2902 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
2903 using _Base = lazy_split_view::_Base<_Const>;
2907 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
2909 // [range.lazy.split.outer] p1
2910 // Many of the following specifications refer to the notional member
2911 // current of outer-iterator. current is equivalent to current_ if
2912 // V models forward_range, and parent_->current_ otherwise.
2914 __current() noexcept
2916 if constexpr (forward_range<_Vp>)
2919 return *_M_parent->_M_current;
2923 __current() const noexcept
2925 if constexpr (forward_range<_Vp>)
2928 return *_M_parent->_M_current;
2931 _Parent* _M_parent = nullptr;
2933 // XXX: _M_current is present only if "V models forward_range"
2934 [[no_unique_address]]
2935 __detail::__maybe_present_t<forward_range<_Vp>,
2936 iterator_t<_Base>> _M_current;
2937 bool _M_trailing_empty = false;
2940 using iterator_concept = __conditional_t<forward_range<_Base>,
2941 forward_iterator_tag,
2942 input_iterator_tag>;
2943 // iterator_category defined in __lazy_split_view_outer_iter_cat
2944 using difference_type = range_difference_t<_Base>;
2946 struct value_type : view_interface<value_type>
2949 _OuterIter _M_i = _OuterIter();
2952 value_type() = default;
2955 value_type(_OuterIter __i)
2956 : _M_i(std::move(__i))
2959 constexpr _InnerIter<_Const>
2961 { return _InnerIter<_Const>{_M_i}; }
2963 constexpr default_sentinel_t
2965 { return default_sentinel; }
2968 _OuterIter() = default;
2971 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
2972 : _M_parent(__parent)
2976 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
2977 requires forward_range<_Base>
2978 : _M_parent(__parent),
2979 _M_current(std::move(__current))
2983 _OuterIter(_OuterIter<!_Const> __i)
2985 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
2986 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current))
2989 constexpr value_type
2991 { return value_type{*this}; }
2993 constexpr _OuterIter&
2996 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2997 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
2998 const auto __end = ranges::end(_M_parent->_M_base);
2999 if (__current() == __end)
3001 _M_trailing_empty = false;
3004 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3005 if (__pbegin == __pend)
3007 else if constexpr (__detail::__tiny_range<_Pattern>)
3009 __current() = ranges::find(std::move(__current()), __end,
3011 if (__current() != __end)
3014 if (__current() == __end)
3015 _M_trailing_empty = true;
3022 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3026 if (__current() == __end)
3027 _M_trailing_empty = true;
3030 } while (++__current() != __end);
3034 constexpr decltype(auto)
3037 if constexpr (forward_range<_Base>)
3047 friend constexpr bool
3048 operator==(const _OuterIter& __x, const _OuterIter& __y)
3049 requires forward_range<_Base>
3051 return __x._M_current == __y._M_current
3052 && __x._M_trailing_empty == __y._M_trailing_empty;
3055 friend constexpr bool
3056 operator==(const _OuterIter& __x, default_sentinel_t)
3057 { return __x.__at_end(); };
3059 friend _OuterIter<!_Const>;
3060 friend _InnerIter<_Const>;
3063 template<bool _Const>
3065 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3068 using _Base = lazy_split_view::_Base<_Const>;
3073 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3074 auto __end = ranges::end(_M_i._M_parent->_M_base);
3075 if constexpr (__detail::__tiny_range<_Pattern>)
3077 const auto& __cur = _M_i_current();
3080 if (__pcur == __pend)
3081 return _M_incremented;
3082 return *__cur == *__pcur;
3086 auto __cur = _M_i_current();
3089 if (__pcur == __pend)
3090 return _M_incremented;
3093 if (*__cur != *__pcur)
3095 if (++__pcur == __pend)
3097 } while (++__cur != __end);
3103 _M_i_current() noexcept
3104 { return _M_i.__current(); }
3107 _M_i_current() const noexcept
3108 { return _M_i.__current(); }
3110 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3111 bool _M_incremented = false;
3114 using iterator_concept
3115 = typename _OuterIter<_Const>::iterator_concept;
3116 // iterator_category defined in __lazy_split_view_inner_iter_cat
3117 using value_type = range_value_t<_Base>;
3118 using difference_type = range_difference_t<_Base>;
3120 _InnerIter() = default;
3123 _InnerIter(_OuterIter<_Const> __i)
3124 : _M_i(std::move(__i))
3127 constexpr const iterator_t<_Base>&
3128 base() const& noexcept
3129 { return _M_i_current(); }
3131 constexpr iterator_t<_Base>
3133 { return std::move(_M_i_current()); }
3135 constexpr decltype(auto)
3137 { return *_M_i_current(); }
3139 constexpr _InnerIter&
3142 _M_incremented = true;
3143 if constexpr (!forward_range<_Base>)
3144 if constexpr (_Pattern::size() == 0)
3150 constexpr decltype(auto)
3153 if constexpr (forward_range<_Base>)
3163 friend constexpr bool
3164 operator==(const _InnerIter& __x, const _InnerIter& __y)
3165 requires forward_range<_Base>
3166 { return __x._M_i == __y._M_i; }
3168 friend constexpr bool
3169 operator==(const _InnerIter& __x, default_sentinel_t)
3170 { return __x.__at_end(); }
3172 friend constexpr decltype(auto)
3173 iter_move(const _InnerIter& __i)
3174 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3175 { return ranges::iter_move(__i._M_i_current()); }
3177 friend constexpr void
3178 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3179 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3180 __y._M_i_current())))
3181 requires indirectly_swappable<iterator_t<_Base>>
3182 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3185 _Vp _M_base = _Vp();
3186 _Pattern _M_pattern = _Pattern();
3187 // XXX: _M_current is "present only if !forward_range<V>"
3188 [[no_unique_address]]
3189 __detail::__maybe_present_t<!forward_range<_Vp>,
3190 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3194 lazy_split_view() requires (default_initializable<_Vp>
3195 && default_initializable<_Pattern>)
3199 lazy_split_view(_Vp __base, _Pattern __pattern)
3200 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3203 template<input_range _Range>
3204 requires constructible_from<_Vp, views::all_t<_Range>>
3205 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3207 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3208 : _M_base(views::all(std::forward<_Range>(__r))),
3209 _M_pattern(views::single(std::move(__e)))
3213 base() const& requires copy_constructible<_Vp>
3218 { return std::move(_M_base); }
3223 if constexpr (forward_range<_Vp>)
3224 return _OuterIter<__detail::__simple_view<_Vp>>{
3225 this, ranges::begin(_M_base)};
3228 _M_current = ranges::begin(_M_base);
3229 return _OuterIter<false>{this};
3234 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3236 return _OuterIter<true>{this, ranges::begin(_M_base)};
3240 end() requires forward_range<_Vp> && common_range<_Vp>
3242 return _OuterIter<__detail::__simple_view<_Vp>>{
3243 this, ranges::end(_M_base)};
3249 if constexpr (forward_range<_Vp>
3250 && forward_range<const _Vp>
3251 && common_range<const _Vp>)
3252 return _OuterIter<true>{this, ranges::end(_M_base)};
3254 return default_sentinel;
3258 template<typename _Range, typename _Pattern>
3259 lazy_split_view(_Range&&, _Pattern&&)
3260 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3262 template<input_range _Range>
3263 lazy_split_view(_Range&&, range_value_t<_Range>)
3264 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3270 template<typename _Range, typename _Pattern>
3271 concept __can_lazy_split_view
3272 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3273 } // namespace __detail
3275 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3277 template<viewable_range _Range, typename _Pattern>
3278 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3280 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3282 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3285 using _RangeAdaptor<_LazySplit>::operator();
3286 static constexpr int _S_arity = 2;
3287 // The pattern argument of views::lazy_split is not always simple -- it can be
3288 // a non-view range, the value category of which affects whether the call
3289 // is well-formed. But a scalar or a view pattern argument is surely
3291 template<typename _Pattern>
3292 static constexpr bool _S_has_simple_extra_args
3293 = is_scalar_v<_Pattern> || (view<_Pattern>
3294 && copy_constructible<_Pattern>);
3297 inline constexpr _LazySplit lazy_split;
3298 } // namespace views
3300 template<forward_range _Vp, forward_range _Pattern>
3301 requires view<_Vp> && view<_Pattern>
3302 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3304 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3307 _Vp _M_base = _Vp();
3308 _Pattern _M_pattern = _Pattern();
3309 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3315 split_view() requires (default_initializable<_Vp>
3316 && default_initializable<_Pattern>)
3320 split_view(_Vp __base, _Pattern __pattern)
3321 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3324 template<forward_range _Range>
3325 requires constructible_from<_Vp, views::all_t<_Range>>
3326 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3328 split_view(_Range&& __r, range_value_t<_Range> __e)
3329 : _M_base(views::all(std::forward<_Range>(__r))),
3330 _M_pattern(views::single(std::move(__e)))
3334 base() const& requires copyable<_Vp>
3339 { return std::move(_M_base); }
3344 if (!_M_cached_begin)
3345 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3346 return {this, ranges::begin(_M_base), *_M_cached_begin};
3352 if constexpr (common_range<_Vp>)
3353 return _Iterator{this, ranges::end(_M_base), {}};
3355 return _Sentinel{this};
3358 constexpr subrange<iterator_t<_Vp>>
3359 _M_find_next(iterator_t<_Vp> __it)
3361 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3362 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3374 split_view* _M_parent = nullptr;
3375 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3376 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3377 bool _M_trailing_empty = false;
3379 friend struct _Sentinel;
3382 using iterator_concept = forward_iterator_tag;
3383 using iterator_category = input_iterator_tag;
3384 using value_type = subrange<iterator_t<_Vp>>;
3385 using difference_type = range_difference_t<_Vp>;
3387 _Iterator() = default;
3390 _Iterator(split_view* __parent,
3391 iterator_t<_Vp> __current,
3392 subrange<iterator_t<_Vp>> __next)
3393 : _M_parent(__parent),
3394 _M_cur(std::move(__current)),
3395 _M_next(std::move(__next))
3398 constexpr iterator_t<_Vp>
3402 constexpr value_type
3404 { return {_M_cur, _M_next.begin()}; }
3406 constexpr _Iterator&
3409 _M_cur = _M_next.begin();
3410 if (_M_cur != ranges::end(_M_parent->_M_base))
3412 _M_cur = _M_next.end();
3413 if (_M_cur == ranges::end(_M_parent->_M_base))
3415 _M_trailing_empty = true;
3416 _M_next = {_M_cur, _M_cur};
3419 _M_next = _M_parent->_M_find_next(_M_cur);
3422 _M_trailing_empty = false;
3434 friend constexpr bool
3435 operator==(const _Iterator& __x, const _Iterator& __y)
3437 return __x._M_cur == __y._M_cur
3438 && __x._M_trailing_empty == __y._M_trailing_empty;
3445 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3448 _M_equal(const _Iterator& __x) const
3449 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3452 _Sentinel() = default;
3455 _Sentinel(split_view* __parent)
3456 : _M_end(ranges::end(__parent->_M_base))
3459 friend constexpr bool
3460 operator==(const _Iterator& __x, const _Sentinel& __y)
3461 { return __y._M_equal(__x); }
3465 template<typename _Range, typename _Pattern>
3466 split_view(_Range&&, _Pattern&&)
3467 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3469 template<forward_range _Range>
3470 split_view(_Range&&, range_value_t<_Range>)
3471 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3477 template<typename _Range, typename _Pattern>
3478 concept __can_split_view
3479 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3480 } // namespace __detail
3482 struct _Split : __adaptor::_RangeAdaptor<_Split>
3484 template<viewable_range _Range, typename _Pattern>
3485 requires __detail::__can_split_view<_Range, _Pattern>
3487 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3489 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3492 using _RangeAdaptor<_Split>::operator();
3493 static constexpr int _S_arity = 2;
3494 template<typename _Pattern>
3495 static constexpr bool _S_has_simple_extra_args
3496 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3499 inline constexpr _Split split;
3500 } // namespace views
3506 template<input_or_output_iterator _Iter>
3508 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3510 if constexpr (random_access_iterator<_Iter>)
3511 return subrange(__i, __i + __n);
3513 return subrange(counted_iterator(std::move(__i), __n),
3518 inline constexpr _Counted counted{};
3519 } // namespace views
3522 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3523 class common_view : public view_interface<common_view<_Vp>>
3526 _Vp _M_base = _Vp();
3529 common_view() requires default_initializable<_Vp> = default;
3532 common_view(_Vp __r)
3533 : _M_base(std::move(__r))
3536 /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
3537 template<viewable_range _Range>
3538 requires (!common_range<_Range>)
3539 && constructible_from<_Vp, views::all_t<_Range>>
3541 common_view(_Range&& __r)
3542 : _M_base(views::all(std::forward<_Range>(__r)))
3547 base() const& requires copy_constructible<_Vp>
3552 { return std::move(_M_base); }
3557 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3558 return ranges::begin(_M_base);
3560 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3561 (ranges::begin(_M_base));
3565 begin() const requires range<const _Vp>
3567 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3568 return ranges::begin(_M_base);
3570 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3571 (ranges::begin(_M_base));
3577 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3578 return ranges::begin(_M_base) + ranges::size(_M_base);
3580 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3581 (ranges::end(_M_base));
3585 end() const requires range<const _Vp>
3587 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3588 return ranges::begin(_M_base) + ranges::size(_M_base);
3590 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3591 (ranges::end(_M_base));
3595 size() requires sized_range<_Vp>
3596 { return ranges::size(_M_base); }
3599 size() const requires sized_range<const _Vp>
3600 { return ranges::size(_M_base); }
3603 template<typename _Range>
3604 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3606 template<typename _Tp>
3607 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3608 = enable_borrowed_range<_Tp>;
3614 template<typename _Range>
3615 concept __already_common = common_range<_Range>
3616 && requires { views::all(std::declval<_Range>()); };
3618 template<typename _Range>
3619 concept __can_common_view
3620 = requires { common_view{std::declval<_Range>()}; };
3621 } // namespace __detail
3623 struct _Common : __adaptor::_RangeAdaptorClosure
3625 template<viewable_range _Range>
3626 requires __detail::__already_common<_Range>
3627 || __detail::__can_common_view<_Range>
3629 operator() [[nodiscard]] (_Range&& __r) const
3631 if constexpr (__detail::__already_common<_Range>)
3632 return views::all(std::forward<_Range>(__r));
3634 return common_view{std::forward<_Range>(__r)};
3637 static constexpr bool _S_has_simple_call_op = true;
3640 inline constexpr _Common common;
3641 } // namespace views
3644 requires bidirectional_range<_Vp>
3645 class reverse_view : public view_interface<reverse_view<_Vp>>
3648 static constexpr bool _S_needs_cached_begin
3649 = !common_range<_Vp> && !(random_access_range<_Vp>
3650 && sized_sentinel_for<sentinel_t<_Vp>,
3653 _Vp _M_base = _Vp();
3654 [[no_unique_address]]
3655 __detail::__maybe_present_t<_S_needs_cached_begin,
3656 __detail::_CachedPosition<_Vp>>
3660 reverse_view() requires default_initializable<_Vp> = default;
3663 reverse_view(_Vp __r)
3664 : _M_base(std::move(__r))
3668 base() const& requires copy_constructible<_Vp>
3673 { return std::move(_M_base); }
3675 constexpr reverse_iterator<iterator_t<_Vp>>
3678 if constexpr (_S_needs_cached_begin)
3679 if (_M_cached_begin._M_has_value())
3680 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
3682 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3683 if constexpr (_S_needs_cached_begin)
3684 _M_cached_begin._M_set(_M_base, __it);
3685 return std::make_reverse_iterator(std::move(__it));
3689 begin() requires common_range<_Vp>
3690 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3693 begin() const requires common_range<const _Vp>
3694 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3696 constexpr reverse_iterator<iterator_t<_Vp>>
3698 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3701 end() const requires common_range<const _Vp>
3702 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3705 size() requires sized_range<_Vp>
3706 { return ranges::size(_M_base); }
3709 size() const requires sized_range<const _Vp>
3710 { return ranges::size(_M_base); }
3713 template<typename _Range>
3714 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3716 template<typename _Tp>
3717 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
3718 = enable_borrowed_range<_Tp>;
3725 inline constexpr bool __is_reversible_subrange = false;
3727 template<typename _Iter, subrange_kind _Kind>
3728 inline constexpr bool
3729 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3730 reverse_iterator<_Iter>,
3734 inline constexpr bool __is_reverse_view = false;
3736 template<typename _Vp>
3737 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
3739 template<typename _Range>
3740 concept __can_reverse_view
3741 = requires { reverse_view{std::declval<_Range>()}; };
3742 } // namespace __detail
3744 struct _Reverse : __adaptor::_RangeAdaptorClosure
3746 template<viewable_range _Range>
3747 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
3748 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
3749 || __detail::__can_reverse_view<_Range>
3751 operator() [[nodiscard]] (_Range&& __r) const
3753 using _Tp = remove_cvref_t<_Range>;
3754 if constexpr (__detail::__is_reverse_view<_Tp>)
3755 return std::forward<_Range>(__r).base();
3756 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3758 using _Iter = decltype(ranges::begin(__r).base());
3759 if constexpr (sized_range<_Tp>)
3760 return subrange<_Iter, _Iter, subrange_kind::sized>
3761 {__r.end().base(), __r.begin().base(), __r.size()};
3763 return subrange<_Iter, _Iter, subrange_kind::unsized>
3764 {__r.end().base(), __r.begin().base()};
3767 return reverse_view{std::forward<_Range>(__r)};
3770 static constexpr bool _S_has_simple_call_op = true;
3773 inline constexpr _Reverse reverse;
3774 } // namespace views
3778 template<typename _Tp, size_t _Nm>
3779 concept __has_tuple_element = requires(_Tp __t)
3781 typename tuple_size<_Tp>::type;
3782 requires _Nm < tuple_size_v<_Tp>;
3783 typename tuple_element_t<_Nm, _Tp>;
3784 { std::get<_Nm>(__t) }
3785 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
3788 template<typename _Tp, size_t _Nm>
3789 concept __returnable_element
3790 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
3793 template<input_range _Vp, size_t _Nm>
3795 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
3796 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
3798 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
3799 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
3802 elements_view() requires default_initializable<_Vp> = default;
3805 elements_view(_Vp base)
3806 : _M_base(std::move(base))
3810 base() const& requires copy_constructible<_Vp>
3815 { return std::move(_M_base); }
3818 begin() requires (!__detail::__simple_view<_Vp>)
3819 { return _Iterator<false>(ranges::begin(_M_base)); }
3822 begin() const requires range<const _Vp>
3823 { return _Iterator<true>(ranges::begin(_M_base)); }
3826 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
3827 { return _Sentinel<false>{ranges::end(_M_base)}; }
3830 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
3831 { return _Iterator<false>{ranges::end(_M_base)}; }
3834 end() const requires range<const _Vp>
3835 { return _Sentinel<true>{ranges::end(_M_base)}; }
3838 end() const requires common_range<const _Vp>
3839 { return _Iterator<true>{ranges::end(_M_base)}; }
3842 size() requires sized_range<_Vp>
3843 { return ranges::size(_M_base); }
3846 size() const requires sized_range<const _Vp>
3847 { return ranges::size(_M_base); }
3850 template<bool _Const>
3851 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3853 template<bool _Const>
3857 template<bool _Const>
3858 requires forward_range<_Base<_Const>>
3859 struct __iter_cat<_Const>
3862 static auto _S_iter_cat()
3864 using _Base = elements_view::_Base<_Const>;
3865 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3866 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
3867 if constexpr (!is_lvalue_reference_v<_Res>)
3868 return input_iterator_tag{};
3869 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
3870 return random_access_iterator_tag{};
3875 using iterator_category = decltype(_S_iter_cat());
3878 template<bool _Const>
3881 template<bool _Const>
3882 struct _Iterator : __iter_cat<_Const>
3885 using _Base = elements_view::_Base<_Const>;
3887 iterator_t<_Base> _M_current = iterator_t<_Base>();
3889 static constexpr decltype(auto)
3890 _S_get_element(const iterator_t<_Base>& __i)
3892 if constexpr (is_reference_v<range_reference_t<_Base>>)
3893 return std::get<_Nm>(*__i);
3896 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
3897 return static_cast<_Et>(std::get<_Nm>(*__i));
3904 if constexpr (random_access_range<_Base>)
3905 return random_access_iterator_tag{};
3906 else if constexpr (bidirectional_range<_Base>)
3907 return bidirectional_iterator_tag{};
3908 else if constexpr (forward_range<_Base>)
3909 return forward_iterator_tag{};
3911 return input_iterator_tag{};
3914 friend _Iterator<!_Const>;
3917 using iterator_concept = decltype(_S_iter_concept());
3918 // iterator_category defined in elements_view::__iter_cat
3920 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
3921 using difference_type = range_difference_t<_Base>;
3923 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
3926 _Iterator(iterator_t<_Base> current)
3927 : _M_current(std::move(current))
3931 _Iterator(_Iterator<!_Const> i)
3932 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3933 : _M_current(std::move(i._M_current))
3936 constexpr const iterator_t<_Base>&
3937 base() const& noexcept
3938 { return _M_current; }
3940 constexpr iterator_t<_Base>
3942 { return std::move(_M_current); }
3944 constexpr decltype(auto)
3946 { return _S_get_element(_M_current); }
3948 constexpr _Iterator&
3960 operator++(int) requires forward_range<_Base>
3967 constexpr _Iterator&
3968 operator--() requires bidirectional_range<_Base>
3975 operator--(int) requires bidirectional_range<_Base>
3982 constexpr _Iterator&
3983 operator+=(difference_type __n)
3984 requires random_access_range<_Base>
3990 constexpr _Iterator&
3991 operator-=(difference_type __n)
3992 requires random_access_range<_Base>
3998 constexpr decltype(auto)
3999 operator[](difference_type __n) const
4000 requires random_access_range<_Base>
4001 { return _S_get_element(_M_current + __n); }
4003 friend constexpr bool
4004 operator==(const _Iterator& __x, const _Iterator& __y)
4005 requires equality_comparable<iterator_t<_Base>>
4006 { return __x._M_current == __y._M_current; }
4008 friend constexpr bool
4009 operator<(const _Iterator& __x, const _Iterator& __y)
4010 requires random_access_range<_Base>
4011 { return __x._M_current < __y._M_current; }
4013 friend constexpr bool
4014 operator>(const _Iterator& __x, const _Iterator& __y)
4015 requires random_access_range<_Base>
4016 { return __y._M_current < __x._M_current; }
4018 friend constexpr bool
4019 operator<=(const _Iterator& __x, const _Iterator& __y)
4020 requires random_access_range<_Base>
4021 { return !(__y._M_current > __x._M_current); }
4023 friend constexpr bool
4024 operator>=(const _Iterator& __x, const _Iterator& __y)
4025 requires random_access_range<_Base>
4026 { return !(__x._M_current > __y._M_current); }
4028 #ifdef __cpp_lib_three_way_comparison
4029 friend constexpr auto
4030 operator<=>(const _Iterator& __x, const _Iterator& __y)
4031 requires random_access_range<_Base>
4032 && three_way_comparable<iterator_t<_Base>>
4033 { return __x._M_current <=> __y._M_current; }
4036 friend constexpr _Iterator
4037 operator+(const _Iterator& __x, difference_type __y)
4038 requires random_access_range<_Base>
4039 { return _Iterator{__x} += __y; }
4041 friend constexpr _Iterator
4042 operator+(difference_type __x, const _Iterator& __y)
4043 requires random_access_range<_Base>
4044 { return __y + __x; }
4046 friend constexpr _Iterator
4047 operator-(const _Iterator& __x, difference_type __y)
4048 requires random_access_range<_Base>
4049 { return _Iterator{__x} -= __y; }
4051 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4052 // 3483. transform_view::iterator's difference is overconstrained
4053 friend constexpr difference_type
4054 operator-(const _Iterator& __x, const _Iterator& __y)
4055 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4056 { return __x._M_current - __y._M_current; }
4058 template <bool> friend struct _Sentinel;
4061 template<bool _Const>
4065 template<bool _Const2>
4067 _M_equal(const _Iterator<_Const2>& __x) const
4068 { return __x._M_current == _M_end; }
4070 template<bool _Const2>
4072 _M_distance_from(const _Iterator<_Const2>& __i) const
4073 { return _M_end - __i._M_current; }
4075 using _Base = elements_view::_Base<_Const>;
4076 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4079 _Sentinel() = default;
4082 _Sentinel(sentinel_t<_Base> __end)
4083 : _M_end(std::move(__end))
4087 _Sentinel(_Sentinel<!_Const> __other)
4089 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4090 : _M_end(std::move(__other._M_end))
4093 constexpr sentinel_t<_Base>
4097 template<bool _Const2>
4098 requires sentinel_for<sentinel_t<_Base>,
4099 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4100 friend constexpr bool
4101 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4102 { return __y._M_equal(__x); }
4104 template<bool _Const2,
4105 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4106 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4107 friend constexpr range_difference_t<_Base2>
4108 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4109 { return -__y._M_distance_from(__x); }
4111 template<bool _Const2,
4112 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4113 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4114 friend constexpr range_difference_t<_Base2>
4115 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4116 { return __x._M_distance_from(__y); }
4118 friend _Sentinel<!_Const>;
4121 _Vp _M_base = _Vp();
4124 template<typename _Tp, size_t _Nm>
4125 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4126 = enable_borrowed_range<_Tp>;
4128 template<typename _Range>
4129 using keys_view = elements_view<views::all_t<_Range>, 0>;
4131 template<typename _Range>
4132 using values_view = elements_view<views::all_t<_Range>, 1>;
4138 template<size_t _Nm, typename _Range>
4139 concept __can_elements_view
4140 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4141 } // namespace __detail
4143 template<size_t _Nm>
4144 struct _Elements : __adaptor::_RangeAdaptorClosure
4146 template<viewable_range _Range>
4147 requires __detail::__can_elements_view<_Nm, _Range>
4149 operator() [[nodiscard]] (_Range&& __r) const
4151 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4154 static constexpr bool _S_has_simple_call_op = true;
4157 template<size_t _Nm>
4158 inline constexpr _Elements<_Nm> elements;
4159 inline constexpr auto keys = elements<0>;
4160 inline constexpr auto values = elements<1>;
4161 } // namespace views
4163 } // namespace ranges
4165 namespace views = ranges::views;
4167 _GLIBCXX_END_NAMESPACE_VERSION
4169 #endif // library concepts
4171 #endif /* _GLIBCXX_RANGES */