3// Copyright (C) 2019-2020 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
41#include <bits/refwrap.h>
43#include <initializer_list>
49 * @defgroup ranges Ranges
51 * Components for dealing with ranges of elements.
54namespace std _GLIBCXX_VISIBILITY(default)
56_GLIBCXX_BEGIN_NAMESPACE_VERSION
59 // [range.range] The range concept.
60 // [range.sized] The sized_range concept.
61 // Defined in <bits/range_access.h>
63 // [range.refinements]
64 // Defined in <bits/range_access.h>
68 template<typename _Tp>
69 inline constexpr bool enable_view = derived_from<_Tp, view_base>;
71 template<typename _Tp>
73 = range<_Tp> && movable<_Tp> && enable_view<_Tp>;
75 /// A range which can be safely converted to a view.
76 template<typename _Tp>
77 concept viewable_range = range<_Tp>
78 && (borrowed_range<_Tp> || view<remove_cvref_t<_Tp>>);
82 template<typename _Range>
83 concept __simple_view = view<_Range> && range<const _Range>
84 && same_as<iterator_t<_Range>, iterator_t<const _Range>>
85 && same_as<sentinel_t<_Range>, sentinel_t<const _Range>>;
87 template<typename _It>
88 concept __has_arrow = input_iterator<_It>
89 && (is_pointer_v<_It> || requires(_It __it) { __it.operator->(); });
91 template<typename _Tp, typename _Up>
93 = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
94 } // namespace __detail
96 template<typename _Derived>
97 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
98 class view_interface : public view_base
101 constexpr _Derived& _M_derived() noexcept
103 static_assert(derived_from<_Derived, view_interface<_Derived>>);
104 static_assert(view<_Derived>);
105 return static_cast<_Derived&>(*this);
108 constexpr const _Derived& _M_derived() const noexcept
110 static_assert(derived_from<_Derived, view_interface<_Derived>>);
111 static_assert(view<_Derived>);
112 return static_cast<const _Derived&>(*this);
117 empty() requires forward_range<_Derived>
118 { return ranges::begin(_M_derived()) == ranges::end(_M_derived()); }
121 empty() const requires forward_range<const _Derived>
122 { return ranges::begin(_M_derived()) == ranges::end(_M_derived()); }
125 operator bool() requires requires { ranges::empty(_M_derived()); }
126 { return !ranges::empty(_M_derived()); }
129 operator bool() const requires requires { ranges::empty(_M_derived()); }
130 { return !ranges::empty(_M_derived()); }
133 data() requires contiguous_iterator<iterator_t<_Derived>>
134 { return to_address(ranges::begin(_M_derived())); }
138 requires range<const _Derived>
139 && contiguous_iterator<iterator_t<const _Derived>>
140 { return to_address(ranges::begin(_M_derived())); }
144 requires forward_range<_Derived>
145 && sized_sentinel_for<sentinel_t<_Derived>, iterator_t<_Derived>>
146 { return ranges::end(_M_derived()) - ranges::begin(_M_derived()); }
150 requires forward_range<const _Derived>
151 && sized_sentinel_for<sentinel_t<const _Derived>,
152 iterator_t<const _Derived>>
153 { return ranges::end(_M_derived()) - ranges::begin(_M_derived()); }
155 constexpr decltype(auto)
156 front() requires forward_range<_Derived>
158 __glibcxx_assert(!empty());
159 return *ranges::begin(_M_derived());
162 constexpr decltype(auto)
163 front() const requires forward_range<const _Derived>
165 __glibcxx_assert(!empty());
166 return *ranges::begin(_M_derived());
169 constexpr decltype(auto)
171 requires bidirectional_range<_Derived> && common_range<_Derived>
173 __glibcxx_assert(!empty());
174 return *ranges::prev(ranges::end(_M_derived()));
177 constexpr decltype(auto)
179 requires bidirectional_range<const _Derived>
180 && common_range<const _Derived>
182 __glibcxx_assert(!empty());
183 return *ranges::prev(ranges::end(_M_derived()));
186 template<random_access_range _Range = _Derived>
187 constexpr decltype(auto)
188 operator[](range_difference_t<_Range> __n)
189 { return ranges::begin(_M_derived())[__n]; }
191 template<random_access_range _Range = const _Derived>
192 constexpr decltype(auto)
193 operator[](range_difference_t<_Range> __n) const
194 { return ranges::begin(_M_derived())[__n]; }
199 template<class _From, class _To>
200 concept __convertible_to_non_slicing = convertible_to<_From, _To>
201 && !(is_pointer_v<decay_t<_From>> && is_pointer_v<decay_t<_To>>
202 && __not_same_as<remove_pointer_t<decay_t<_From>>,
203 remove_pointer_t<decay_t<_To>>>);
205 template<typename _Tp>
207 = !is_reference_v<_Tp> && requires(_Tp __t)
209 typename tuple_size<_Tp>::type;
210 requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
211 typename tuple_element_t<0, remove_const_t<_Tp>>;
212 typename tuple_element_t<1, remove_const_t<_Tp>>;
213 { get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
214 { get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
217 template<typename _Tp, typename _Up, typename _Vp>
218 concept __pair_like_convertible_from
219 = !range<_Tp> && __pair_like<_Tp>
220 && constructible_from<_Tp, _Up, _Vp>
221 && __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>>
222 && convertible_to<_Vp, tuple_element_t<1, _Tp>>;
224 } // namespace __detail
226 enum class subrange_kind : bool { unsized, sized };
228 template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It,
229 subrange_kind _Kind = sized_sentinel_for<_Sent, _It>
230 ? subrange_kind::sized : subrange_kind::unsized>
231 requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>)
232 class subrange : public view_interface<subrange<_It, _Sent, _Kind>>
235 // XXX: gcc complains when using constexpr here
236 static const bool _S_store_size
237 = _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _It>;
239 _It _M_begin = _It();
240 _Sent _M_end = _Sent();
242 template<typename, bool = _S_store_size>
246 template<typename _Tp>
247 struct _Size<_Tp, true>
248 { __detail::__make_unsigned_like_t<_Tp> _M_size; };
250 [[no_unique_address]] _Size<iter_difference_t<_It>> _M_size = {};
253 subrange() requires default_initializable<_It> = default;
256 subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s)
257 requires (!_S_store_size)
258 : _M_begin(std::move(__i)), _M_end(__s)
262 subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s,
263 __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
264 requires (_Kind == subrange_kind::sized)
265 : _M_begin(std::move(__i)), _M_end(__s)
267 if constexpr (_S_store_size)
268 _M_size._M_size = __n;
271 template<__detail::__not_same_as<subrange> _Rng>
272 requires borrowed_range<_Rng>
273 && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
274 && convertible_to<sentinel_t<_Rng>, _Sent>
276 subrange(_Rng&& __r) requires _S_store_size && sized_range<_Rng>
277 : subrange(__r, ranges::size(__r))
280 template<__detail::__not_same_as<subrange> _Rng>
281 requires borrowed_range<_Rng>
282 && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
283 && convertible_to<sentinel_t<_Rng>, _Sent>
285 subrange(_Rng&& __r) requires (!_S_store_size)
286 : subrange{ranges::begin(__r), ranges::end(__r)}
289 template<borrowed_range _Rng>
290 requires __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
291 && convertible_to<sentinel_t<_Rng>, _Sent>
294 __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
295 requires (_Kind == subrange_kind::sized)
296 : subrange{ranges::begin(__r), ranges::end(__r), __n}
299 template<__detail::__not_same_as<subrange> _PairLike>
300 requires __detail::__pair_like_convertible_from<_PairLike, const _It&,
303 operator _PairLike() const
304 { return _PairLike(_M_begin, _M_end); }
307 begin() const requires copyable<_It>
310 [[nodiscard]] constexpr _It
311 begin() requires (!copyable<_It>)
312 { return std::move(_M_begin); }
314 constexpr _Sent end() const { return _M_end; }
316 constexpr bool empty() const { return _M_begin == _M_end; }
318 constexpr __detail::__make_unsigned_like_t<iter_difference_t<_It>>
319 size() const requires (_Kind == subrange_kind::sized)
321 if constexpr (_S_store_size)
322 return _M_size._M_size;
324 return __detail::__to_unsigned_like(_M_end - _M_begin);
327 [[nodiscard]] constexpr subrange
328 next(iter_difference_t<_It> __n = 1) const &
329 requires forward_iterator<_It>
336 [[nodiscard]] constexpr subrange
337 next(iter_difference_t<_It> __n = 1) &&
340 return std::move(*this);
343 [[nodiscard]] constexpr subrange
344 prev(iter_difference_t<_It> __n = 1) const
345 requires bidirectional_iterator<_It>
353 advance(iter_difference_t<_It> __n)
355 // _GLIBCXX_RESOLVE_LIB_DEFECTS
356 // 3433. subrange::advance(n) has UB when n < 0
357 if constexpr (bidirectional_iterator<_It>)
360 ranges::advance(_M_begin, __n);
361 if constexpr (_S_store_size)
362 _M_size._M_size += __detail::__to_unsigned_like(-__n);
366 __glibcxx_assert(__n >= 0);
367 auto __d = __n - ranges::advance(_M_begin, __n, _M_end);
368 if constexpr (_S_store_size)
369 _M_size._M_size -= __detail::__to_unsigned_like(__d);
374 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
375 subrange(_It, _Sent) -> subrange<_It, _Sent>;
377 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
379 __detail::__make_unsigned_like_t<iter_difference_t<_It>>)
380 -> subrange<_It, _Sent, subrange_kind::sized>;
382 template<borrowed_range _Rng>
384 -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>,
386 || sized_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>)
387 ? subrange_kind::sized : subrange_kind::unsized>;
389 template<borrowed_range _Rng>
391 __detail::__make_unsigned_like_t<range_difference_t<_Rng>>)
392 -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, subrange_kind::sized>;
394 template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
397 get(const subrange<_It, _Sent, _Kind>& __r)
399 if constexpr (_Num == 0)
405 template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
408 get(subrange<_It, _Sent, _Kind>&& __r)
410 if constexpr (_Num == 0)
416 template<input_or_output_iterator _It, sentinel_for<_It> _Sent,
418 inline constexpr bool
419 enable_borrowed_range<subrange<_It, _Sent, _Kind>> = true;
427 /// Type returned by algorithms instead of a dangling iterator or subrange.
430 constexpr dangling() noexcept = default;
431 template<typename... _Args>
432 constexpr dangling(_Args&&...) noexcept { }
435 template<range _Range>
436 using borrowed_iterator_t = conditional_t<borrowed_range<_Range>,
440 template<range _Range>
441 using borrowed_subrange_t = conditional_t<borrowed_range<_Range>,
442 subrange<iterator_t<_Range>>,
445 template<typename _Tp> requires is_object_v<_Tp>
447 : public view_interface<empty_view<_Tp>>
450 static constexpr _Tp* begin() noexcept { return nullptr; }
451 static constexpr _Tp* end() noexcept { return nullptr; }
452 static constexpr _Tp* data() noexcept { return nullptr; }
453 static constexpr size_t size() noexcept { return 0; }
454 static constexpr bool empty() noexcept { return true; }
457 template<typename _Tp>
458 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
462 template<copy_constructible _Tp> requires is_object_v<_Tp>
463 struct __box : std::optional<_Tp>
465 using std::optional<_Tp>::optional;
469 noexcept(is_nothrow_default_constructible_v<_Tp>)
470 requires default_initializable<_Tp>
471 : std::optional<_Tp>{std::in_place}
474 __box(const __box&) = default;
475 __box(__box&&) = default;
477 using std::optional<_Tp>::operator=;
479 // _GLIBCXX_RESOLVE_LIB_DEFECTS
480 // 3477. Simplify constraints for semiregular-box
482 operator=(const __box& __that)
483 noexcept(is_nothrow_copy_constructible_v<_Tp>)
484 requires (!copyable<_Tp>)
486 if (this != std::__addressof(__that))
489 this->emplace(*__that);
497 operator=(__box&& __that)
498 noexcept(is_nothrow_move_constructible_v<_Tp>)
499 requires (!movable<_Tp>)
501 if (this != std::__addressof(__that))
504 this->emplace(std::move(*__that));
512 } // namespace __detail
514 /// A view that contains exactly one element.
515 template<copy_constructible _Tp> requires is_object_v<_Tp>
516 class single_view : public view_interface<single_view<_Tp>>
519 single_view() = default;
522 single_view(const _Tp& __t)
527 single_view(_Tp&& __t)
528 : _M_value(std::move(__t))
531 // _GLIBCXX_RESOLVE_LIB_DEFECTS
532 // 3428. single_view's in place constructor should be explicit
533 template<typename... _Args>
534 requires constructible_from<_Tp, _Args...>
536 single_view(in_place_t, _Args&&... __args)
537 : _M_value{in_place, std::forward<_Args>(__args)...}
545 begin() const noexcept
550 { return data() + 1; }
554 { return data() + 1; }
556 static constexpr size_t
562 { return _M_value.operator->(); }
565 data() const noexcept
566 { return _M_value.operator->(); }
569 __detail::__box<_Tp> _M_value;
574 template<typename _Wp>
575 constexpr auto __to_signed_like(_Wp __w) noexcept
577 if constexpr (!integral<_Wp>)
578 return iter_difference_t<_Wp>();
579 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
580 return iter_difference_t<_Wp>(__w);
581 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
582 return ptrdiff_t(__w);
583 else if constexpr (sizeof(long long) > sizeof(_Wp))
584 return (long long)(__w);
585#ifdef __SIZEOF_INT128__
586 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
587 return __int128(__w);
590 return __max_diff_type(__w);
593 template<typename _Wp>
594 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
596 template<typename _It>
597 concept __decrementable = incrementable<_It>
600 { --__i } -> same_as<_It&>;
601 { __i-- } -> same_as<_It>;
604 template<typename _It>
605 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
606 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
608 { __i += __n } -> same_as<_It&>;
609 { __i -= __n } -> same_as<_It&>;
613 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
616 template<typename _Winc>
617 struct __iota_view_iter_cat
620 template<incrementable _Winc>
621 struct __iota_view_iter_cat<_Winc>
622 { using iterator_category = input_iterator_tag; };
623 } // namespace __detail
625 template<weakly_incrementable _Winc,
626 semiregular _Bound = unreachable_sentinel_t>
627 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
629 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
634 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
640 using namespace __detail;
641 if constexpr (__advanceable<_Winc>)
642 return random_access_iterator_tag{};
643 else if constexpr (__decrementable<_Winc>)
644 return bidirectional_iterator_tag{};
645 else if constexpr (incrementable<_Winc>)
646 return forward_iterator_tag{};
648 return input_iterator_tag{};
652 using iterator_concept = decltype(_S_iter_concept());
653 // iterator_category defined in __iota_view_iter_cat
654 using value_type = _Winc;
655 using difference_type = __detail::__iota_diff_t<_Winc>;
657 _Iterator() requires default_initializable<_Winc> = default;
660 _Iterator(_Winc __value)
661 : _M_value(__value) { }
664 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
679 operator++(int) requires incrementable<_Winc>
687 operator--() requires __detail::__decrementable<_Winc>
694 operator--(int) requires __detail::__decrementable<_Winc>
702 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
704 using __detail::__is_integer_like;
705 using __detail::__is_signed_integer_like;
706 if constexpr (__is_integer_like<_Winc>
707 && !__is_signed_integer_like<_Winc>)
709 if (__n >= difference_type(0))
710 _M_value += static_cast<_Winc>(__n);
712 _M_value -= static_cast<_Winc>(-__n);
720 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
722 using __detail::__is_integer_like;
723 using __detail::__is_signed_integer_like;
724 if constexpr (__is_integer_like<_Winc>
725 && !__is_signed_integer_like<_Winc>)
727 if (__n >= difference_type(0))
728 _M_value -= static_cast<_Winc>(__n);
730 _M_value += static_cast<_Winc>(-__n);
738 operator[](difference_type __n) const
739 requires __detail::__advanceable<_Winc>
740 { return _Winc(_M_value + __n); }
742 friend constexpr bool
743 operator==(const _Iterator& __x, const _Iterator& __y)
744 requires equality_comparable<_Winc>
745 { return __x._M_value == __y._M_value; }
747 friend constexpr bool
748 operator<(const _Iterator& __x, const _Iterator& __y)
749 requires totally_ordered<_Winc>
750 { return __x._M_value < __y._M_value; }
752 friend constexpr bool
753 operator>(const _Iterator& __x, const _Iterator& __y)
754 requires totally_ordered<_Winc>
755 { return __y < __x; }
757 friend constexpr bool
758 operator<=(const _Iterator& __x, const _Iterator& __y)
759 requires totally_ordered<_Winc>
760 { return !(__y < __x); }
762 friend constexpr bool
763 operator>=(const _Iterator& __x, const _Iterator& __y)
764 requires totally_ordered<_Winc>
765 { return !(__x < __y); }
767#ifdef __cpp_lib_three_way_comparison
768 friend constexpr auto
769 operator<=>(const _Iterator& __x, const _Iterator& __y)
770 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
771 { return __x._M_value <=> __y._M_value; }
774 friend constexpr _Iterator
775 operator+(_Iterator __i, difference_type __n)
776 requires __detail::__advanceable<_Winc>
777 { return __i += __n; }
779 friend constexpr _Iterator
780 operator+(difference_type __n, _Iterator __i)
781 requires __detail::__advanceable<_Winc>
782 { return __i += __n; }
784 friend constexpr _Iterator
785 operator-(_Iterator __i, difference_type __n)
786 requires __detail::__advanceable<_Winc>
787 { return __i -= __n; }
789 friend constexpr difference_type
790 operator-(const _Iterator& __x, const _Iterator& __y)
791 requires __detail::__advanceable<_Winc>
793 using __detail::__is_integer_like;
794 using __detail::__is_signed_integer_like;
795 using _Dt = difference_type;
796 if constexpr (__is_integer_like<_Winc>)
798 if constexpr (__is_signed_integer_like<_Winc>)
799 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
801 return (__y._M_value > __x._M_value)
802 ? _Dt(-_Dt(__y._M_value - __x._M_value))
803 : _Dt(__x._M_value - __y._M_value);
806 return __x._M_value - __y._M_value;
810 _Winc _M_value = _Winc();
819 _M_equal(const _Iterator& __x) const
820 { return __x._M_value == _M_bound; }
823 _M_distance_from(const _Iterator& __x) const
824 { return _M_bound - __x._M_value; }
826 _Bound _M_bound = _Bound();
829 _Sentinel() = default;
832 _Sentinel(_Bound __bound)
833 : _M_bound(__bound) { }
835 friend constexpr bool
836 operator==(const _Iterator& __x, const _Sentinel& __y)
837 { return __y._M_equal(__x); }
839 friend constexpr iter_difference_t<_Winc>
840 operator-(const _Iterator& __x, const _Sentinel& __y)
841 requires sized_sentinel_for<_Bound, _Winc>
842 { return -__y._M_distance_from(__x); }
844 friend constexpr iter_difference_t<_Winc>
845 operator-(const _Sentinel& __x, const _Iterator& __y)
846 requires sized_sentinel_for<_Bound, _Winc>
847 { return __x._M_distance_from(__y); }
850 _Winc _M_value = _Winc();
851 _Bound _M_bound = _Bound();
854 iota_view() requires default_initializable<_Winc> = default;
857 iota_view(_Winc __value)
862 iota_view(type_identity_t<_Winc> __value,
863 type_identity_t<_Bound> __bound)
864 : _M_value(__value), _M_bound(__bound)
866 if constexpr (totally_ordered_with<_Winc, _Bound>)
868 __glibcxx_assert( bool(__value <= __bound) );
873 begin() const { return _Iterator{_M_value}; }
878 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
879 return unreachable_sentinel;
881 return _Sentinel{_M_bound};
885 end() const requires same_as<_Winc, _Bound>
886 { return _Iterator{_M_bound}; }
890 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
891 || (integral<_Winc> && integral<_Bound>)
892 || sized_sentinel_for<_Bound, _Winc>
894 using __detail::__is_integer_like;
895 using __detail::__to_unsigned_like;
896 if constexpr (integral<_Winc> && integral<_Bound>)
898 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
899 return _Up(_M_bound) - _Up(_M_value);
901 else if constexpr (__is_integer_like<_Winc>)
902 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
904 return __to_unsigned_like(_M_bound - _M_value);
908 template<typename _Winc, typename _Bound>
909 requires (!__detail::__is_integer_like<_Winc>
910 || !__detail::__is_integer_like<_Bound>
911 || (__detail::__is_signed_integer_like<_Winc>
912 == __detail::__is_signed_integer_like<_Bound>))
913 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
915 template<weakly_incrementable _Winc, semiregular _Bound>
916 inline constexpr bool
917 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
921 template<typename _Tp>
922 inline constexpr empty_view<_Tp> empty{};
926 template<typename _Tp>
928 operator()(_Tp&& __e) const
929 { return single_view{std::forward<_Tp>(__e)}; }
932 inline constexpr _Single single{};
936 template<typename _Tp>
938 operator()(_Tp&& __e) const
939 { return iota_view{std::forward<_Tp>(__e)}; }
941 template<typename _Tp, typename _Up>
943 operator()(_Tp&& __e, _Up&& __f) const
944 { return iota_view{std::forward<_Tp>(__e), std::forward<_Up>(__f)}; }
947 inline constexpr _Iota iota{};
952 template<typename _Val, typename _CharT, typename _Traits>
953 concept __stream_extractable
954 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
955 } // namespace __detail
957 template<movable _Val, typename _CharT,
958 typename _Traits = char_traits<_CharT>>
959 requires default_initializable<_Val>
960 && __detail::__stream_extractable<_Val, _CharT, _Traits>
961 class basic_istream_view
962 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
965 basic_istream_view() = default;
968 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
969 : _M_stream(std::__addressof(__stream))
975 if (_M_stream != nullptr)
976 *_M_stream >> _M_object;
977 return _Iterator{this};
980 constexpr default_sentinel_t
982 { return default_sentinel; }
985 basic_istream<_CharT, _Traits>* _M_stream = nullptr;
986 _Val _M_object = _Val();
991 using iterator_concept = input_iterator_tag;
992 using difference_type = ptrdiff_t;
993 using value_type = _Val;
995 _Iterator() = default;
998 _Iterator(basic_istream_view* __parent) noexcept
999 : _M_parent(__parent)
1002 _Iterator(const _Iterator&) = delete;
1003 _Iterator(_Iterator&&) = default;
1004 _Iterator& operator=(const _Iterator&) = delete;
1005 _Iterator& operator=(_Iterator&&) = default;
1010 __glibcxx_assert(_M_parent->_M_stream != nullptr);
1011 *_M_parent->_M_stream >> _M_parent->_M_object;
1022 __glibcxx_assert(_M_parent->_M_stream != nullptr);
1023 return _M_parent->_M_object;
1027 operator==(const _Iterator& __x, default_sentinel_t)
1028 { return __x._M_at_end(); }
1031 basic_istream_view* _M_parent = nullptr;
1035 { return _M_parent == nullptr || !*_M_parent->_M_stream; }
1041 template<typename _Val, typename _CharT, typename _Traits>
1042 basic_istream_view<_Val, _CharT, _Traits>
1043 istream_view(basic_istream<_CharT, _Traits>& __s)
1044 { return basic_istream_view<_Val, _CharT, _Traits>{__s}; }
1050 // Alias for a type that is conditionally present
1051 // (and is an empty type otherwise).
1052 // Data members using this alias should use [[no_unique_address]] so that
1053 // they take no space when not needed.
1054 template<bool _Present, typename _Tp>
1055 using __maybe_present_t = conditional_t<_Present, _Tp, _Empty>;
1057 // Alias for a type that is conditionally const.
1058 template<bool _Const, typename _Tp>
1059 using __maybe_const_t = conditional_t<_Const, const _Tp, _Tp>;
1061} // namespace __detail
1067 template<typename _Tp>
1068 inline constexpr auto
1069 __maybe_refwrap(_Tp& __arg)
1070 { return reference_wrapper<_Tp>{__arg}; }
1072 template<typename _Tp>
1073 inline constexpr auto
1074 __maybe_refwrap(const _Tp& __arg)
1075 { return reference_wrapper<const _Tp>{__arg}; }
1077 template<typename _Tp>
1078 inline constexpr decltype(auto)
1079 __maybe_refwrap(_Tp&& __arg)
1080 { return std::forward<_Tp>(__arg); }
1082 template<typename _Callable>
1083 struct _RangeAdaptorClosure;
1085 template<typename _Callable>
1086 struct _RangeAdaptor
1089 [[no_unique_address]]
1090 __detail::__maybe_present_t<!is_default_constructible_v<_Callable>,
1091 _Callable> _M_callable;
1095 _RangeAdaptor(const _Callable& = {})
1096 requires is_default_constructible_v<_Callable>
1100 _RangeAdaptor(_Callable __callable)
1101 requires (!is_default_constructible_v<_Callable>)
1102 : _M_callable(std::move(__callable))
1105 template<typename... _Args>
1106 requires (sizeof...(_Args) >= 1)
1108 operator()(_Args&&... __args) const
1110 // [range.adaptor.object]: If a range adaptor object accepts more
1111 // than one argument, then the following expressions are equivalent:
1113 // (1) adaptor(range, args...)
1114 // (2) adaptor(args...)(range)
1115 // (3) range | adaptor(args...)
1117 // In this case, adaptor(args...) is a range adaptor closure object.
1119 // We handle (1) and (2) here, and (3) is just a special case of a
1120 // more general case already handled by _RangeAdaptorClosure.
1121 if constexpr (is_invocable_v<_Callable, _Args...>)
1123 static_assert(sizeof...(_Args) != 1,
1124 "a _RangeAdaptor that accepts only one argument "
1125 "should be defined as a _RangeAdaptorClosure");
1126 // Here we handle adaptor(range, args...) -- just forward all
1127 // arguments to the underlying adaptor routine.
1128 return _Callable{}(std::forward<_Args>(__args)...);
1132 // Here we handle adaptor(args...)(range).
1133 // Given args..., we return a _RangeAdaptorClosure that takes a
1134 // range argument, such that (2) is equivalent to (1).
1136 // We need to be careful about how we capture args... in this
1137 // closure. By using __maybe_refwrap, we capture lvalue
1138 // references by reference (through a reference_wrapper) and
1139 // otherwise capture by value.
1141 = [...__args(__maybe_refwrap(std::forward<_Args>(__args)))]
1142 <typename _Range> (_Range&& __r) {
1143 // This static_cast has two purposes: it forwards a
1144 // reference_wrapper<T> capture as a T&, and otherwise
1145 // forwards the captured argument as an rvalue.
1146 return _Callable{}(std::forward<_Range>(__r),
1147 (static_cast<unwrap_reference_t
1148 <remove_const_t<decltype(__args)>>>
1151 using _ClosureType = decltype(__closure);
1152 return _RangeAdaptorClosure<_ClosureType>(std::move(__closure));
1157 template<typename _Callable>
1158 _RangeAdaptor(_Callable) -> _RangeAdaptor<_Callable>;
1160 template<typename _Callable>
1161 struct _RangeAdaptorClosure : public _RangeAdaptor<_Callable>
1163 using _RangeAdaptor<_Callable>::_RangeAdaptor;
1165 template<viewable_range _Range>
1166 requires requires { declval<_Callable>()(declval<_Range>()); }
1168 operator()(_Range&& __r) const
1170 if constexpr (is_default_constructible_v<_Callable>)
1171 return _Callable{}(std::forward<_Range>(__r));
1173 return this->_M_callable(std::forward<_Range>(__r));
1176 template<viewable_range _Range>
1177 requires requires { declval<_Callable>()(declval<_Range>()); }
1178 friend constexpr auto
1179 operator|(_Range&& __r, const _RangeAdaptorClosure& __o)
1180 { return __o(std::forward<_Range>(__r)); }
1182 template<typename _Tp>
1183 friend constexpr auto
1184 operator|(const _RangeAdaptorClosure<_Tp>& __x,
1185 const _RangeAdaptorClosure& __y)
1187 if constexpr (is_default_constructible_v<_Tp>
1188 && is_default_constructible_v<_Callable>)
1190 auto __closure = [] <typename _Up> (_Up&& __e) {
1191 return std::forward<_Up>(__e) | decltype(__x){} | decltype(__y){};
1193 return _RangeAdaptorClosure<decltype(__closure)>(__closure);
1195 else if constexpr (is_default_constructible_v<_Tp>
1196 && !is_default_constructible_v<_Callable>)
1198 auto __closure = [__y] <typename _Up> (_Up&& __e) {
1199 return std::forward<_Up>(__e) | decltype(__x){} | __y;
1201 return _RangeAdaptorClosure<decltype(__closure)>(__closure);
1203 else if constexpr (!is_default_constructible_v<_Tp>
1204 && is_default_constructible_v<_Callable>)
1206 auto __closure = [__x] <typename _Up> (_Up&& __e) {
1207 return std::forward<_Up>(__e) | __x | decltype(__y){};
1209 return _RangeAdaptorClosure<decltype(__closure)>(__closure);
1213 auto __closure = [__x, __y] <typename _Up> (_Up&& __e) {
1214 return std::forward<_Up>(__e) | __x | __y;
1216 return _RangeAdaptorClosure<decltype(__closure)>(__closure);
1221 template<typename _Callable>
1222 _RangeAdaptorClosure(_Callable) -> _RangeAdaptorClosure<_Callable>;
1223 } // namespace __adaptor
1226 template<range _Range> requires is_object_v<_Range>
1227 class ref_view : public view_interface<ref_view<_Range>>
1230 _Range* _M_r = nullptr;
1232 static void _S_fun(_Range&); // not defined
1233 static void _S_fun(_Range&&) = delete;
1237 ref_view() noexcept = default;
1239 template<__detail::__not_same_as<ref_view> _Tp>
1240 requires convertible_to<_Tp, _Range&>
1241 && requires { _S_fun(declval<_Tp>()); }
1244 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1251 constexpr iterator_t<_Range>
1253 { return ranges::begin(*_M_r); }
1255 constexpr sentinel_t<_Range>
1257 { return ranges::end(*_M_r); }
1260 empty() const requires requires { ranges::empty(*_M_r); }
1261 { return ranges::empty(*_M_r); }
1264 size() const requires sized_range<_Range>
1265 { return ranges::size(*_M_r); }
1268 data() const requires contiguous_range<_Range>
1269 { return ranges::data(*_M_r); }
1272 template<typename _Range>
1273 ref_view(_Range&) -> ref_view<_Range>;
1275 template<typename _Tp>
1276 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1280 inline constexpr __adaptor::_RangeAdaptorClosure all
1281 = [] <viewable_range _Range> (_Range&& __r)
1283 if constexpr (view<decay_t<_Range>>)
1284 return std::forward<_Range>(__r);
1285 else if constexpr (requires { ref_view{std::forward<_Range>(__r)}; })
1286 return ref_view{std::forward<_Range>(__r)};
1288 return subrange{std::forward<_Range>(__r)};
1291 template<viewable_range _Range>
1292 using all_t = decltype(all(std::declval<_Range>()));
1294 } // namespace views
1296 // The following simple algos are transcribed from ranges_algo.h to avoid
1297 // having to include that entire header.
1300 template<typename _Iter, typename _Sent, typename _Tp>
1302 find(_Iter __first, _Sent __last, const _Tp& __value)
1304 while (__first != __last
1305 && !(bool)(*__first == __value))
1310 template<typename _Iter, typename _Sent, typename _Pred>
1312 find_if(_Iter __first, _Sent __last, _Pred __pred)
1314 while (__first != __last
1315 && !(bool)std::__invoke(__pred, *__first))
1320 template<typename _Iter, typename _Sent, typename _Pred>
1322 find_if_not(_Iter __first, _Sent __last, _Pred __pred)
1324 while (__first != __last
1325 && (bool)std::__invoke(__pred, *__first))
1330 template<typename _Iter1, typename _Sent1, typename _Iter2, typename _Sent2>
1331 constexpr pair<_Iter1, _Iter2>
1332 mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2)
1334 while (__first1 != __last1 && __first2 != __last2
1335 && (bool)ranges::equal_to{}(*__first1, *__first2))
1340 return { std::move(__first1), std::move(__first2) };
1342 } // namespace __detail
1346 template<range _Range>
1347 struct _CachedPosition
1350 _M_has_value() const
1353 constexpr iterator_t<_Range>
1354 _M_get(const _Range&) const
1356 __glibcxx_assert(false);
1357 __builtin_unreachable();
1361 _M_set(const _Range&, const iterator_t<_Range>&) const
1365 template<forward_range _Range>
1366 struct _CachedPosition<_Range>
1369 iterator_t<_Range> _M_iter{};
1373 _M_has_value() const
1374 { return _M_iter != iterator_t<_Range>{}; }
1376 constexpr iterator_t<_Range>
1377 _M_get(const _Range&) const
1379 __glibcxx_assert(_M_has_value());
1384 _M_set(const _Range&, const iterator_t<_Range>& __it)
1386 __glibcxx_assert(!_M_has_value());
1391 template<random_access_range _Range>
1392 requires (sizeof(range_difference_t<_Range>)
1393 <= sizeof(iterator_t<_Range>))
1394 struct _CachedPosition<_Range>
1397 range_difference_t<_Range> _M_offset = -1;
1401 _M_has_value() const
1402 { return _M_offset >= 0; }
1404 constexpr iterator_t<_Range>
1405 _M_get(_Range& __r) const
1407 __glibcxx_assert(_M_has_value());
1408 return ranges::begin(__r) + _M_offset;
1412 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1414 __glibcxx_assert(!_M_has_value());
1415 _M_offset = __it - ranges::begin(__r);
1418 } // namespace __detail
1422 template<typename _Base>
1423 struct __filter_view_iter_cat
1426 template<forward_range _Base>
1427 struct __filter_view_iter_cat<_Base>
1433 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1434 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1435 return bidirectional_iterator_tag{};
1436 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1437 return forward_iterator_tag{};
1442 using iterator_category = decltype(_S_iter_cat());
1444 } // namespace __detail
1446 template<input_range _Vp,
1447 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1448 requires view<_Vp> && is_object_v<_Pred>
1449 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1454 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1457 static constexpr auto
1460 if constexpr (bidirectional_range<_Vp>)
1461 return bidirectional_iterator_tag{};
1462 else if constexpr (forward_range<_Vp>)
1463 return forward_iterator_tag{};
1465 return input_iterator_tag{};
1470 using _Vp_iter = iterator_t<_Vp>;
1472 _Vp_iter _M_current = _Vp_iter();
1473 filter_view* _M_parent = nullptr;
1476 using iterator_concept = decltype(_S_iter_concept());
1477 // iterator_category defined in __filter_view_iter_cat
1478 using value_type = range_value_t<_Vp>;
1479 using difference_type = range_difference_t<_Vp>;
1481 _Iterator() requires default_initializable<_Vp_iter> = default;
1484 _Iterator(filter_view* __parent, _Vp_iter __current)
1485 : _M_current(std::move(__current)),
1489 constexpr const _Vp_iter&
1490 base() const & noexcept
1491 { return _M_current; }
1495 { return std::move(_M_current); }
1497 constexpr range_reference_t<_Vp>
1499 { return *_M_current; }
1503 requires __detail::__has_arrow<_Vp_iter>
1504 && copyable<_Vp_iter>
1505 { return _M_current; }
1507 constexpr _Iterator&
1510 _M_current = __detail::find_if(std::move(++_M_current),
1511 ranges::end(_M_parent->_M_base),
1512 std::ref(*_M_parent->_M_pred));
1521 operator++(int) requires forward_range<_Vp>
1528 constexpr _Iterator&
1529 operator--() requires bidirectional_range<_Vp>
1533 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1538 operator--(int) requires bidirectional_range<_Vp>
1545 friend constexpr bool
1546 operator==(const _Iterator& __x, const _Iterator& __y)
1547 requires equality_comparable<_Vp_iter>
1548 { return __x._M_current == __y._M_current; }
1550 friend constexpr range_rvalue_reference_t<_Vp>
1551 iter_move(const _Iterator& __i)
1552 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1553 { return ranges::iter_move(__i._M_current); }
1555 friend constexpr void
1556 iter_swap(const _Iterator& __x, const _Iterator& __y)
1557 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1558 requires indirectly_swappable<_Vp_iter>
1559 { ranges::iter_swap(__x._M_current, __y._M_current); }
1565 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1568 __equal(const _Iterator& __i) const
1569 { return __i._M_current == _M_end; }
1572 _Sentinel() = default;
1575 _Sentinel(filter_view* __parent)
1576 : _M_end(ranges::end(__parent->_M_base))
1579 constexpr sentinel_t<_Vp>
1583 friend constexpr bool
1584 operator==(const _Iterator& __x, const _Sentinel& __y)
1585 { return __y.__equal(__x); }
1588 _Vp _M_base = _Vp();
1589 __detail::__box<_Pred> _M_pred;
1590 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1593 filter_view() requires default_initializable<_Vp> = default;
1596 filter_view(_Vp __base, _Pred __pred)
1597 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1601 base() const& requires copy_constructible<_Vp>
1606 { return std::move(_M_base); }
1608 constexpr const _Pred&
1610 { return *_M_pred; }
1615 if (_M_cached_begin._M_has_value())
1616 return {this, _M_cached_begin._M_get(_M_base)};
1618 __glibcxx_assert(_M_pred.has_value());
1619 auto __it = __detail::find_if(ranges::begin(_M_base),
1620 ranges::end(_M_base),
1621 std::ref(*_M_pred));
1622 _M_cached_begin._M_set(_M_base, __it);
1623 return {this, std::move(__it)};
1629 if constexpr (common_range<_Vp>)
1630 return _Iterator{this, ranges::end(_M_base)};
1632 return _Sentinel{this};
1636 template<typename _Range, typename _Pred>
1637 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1641 inline constexpr __adaptor::_RangeAdaptor filter
1642 = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p)
1644 return filter_view{std::forward<_Range>(__r), std::forward<_Pred>(__p)};
1646 } // namespace views
1648 template<input_range _Vp, copy_constructible _Fp>
1649 requires view<_Vp> && is_object_v<_Fp>
1650 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1651 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1652 range_reference_t<_Vp>>>
1653 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1656 template<bool _Const>
1657 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1659 template<bool _Const>
1663 template<bool _Const>
1664 requires forward_range<_Base<_Const>>
1665 struct __iter_cat<_Const>
1671 using _Base = transform_view::_Base<_Const>;
1672 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1673 if constexpr (is_lvalue_reference_v<_Res>)
1676 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1677 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1678 return random_access_iterator_tag{};
1683 return input_iterator_tag{};
1686 using iterator_category = decltype(_S_iter_cat());
1689 template<bool _Const>
1692 template<bool _Const>
1693 struct _Iterator : __iter_cat<_Const>
1696 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1697 using _Base = transform_view::_Base<_Const>;
1702 if constexpr (random_access_range<_Base>)
1703 return random_access_iterator_tag{};
1704 else if constexpr (bidirectional_range<_Base>)
1705 return bidirectional_iterator_tag{};
1706 else if constexpr (forward_range<_Base>)
1707 return forward_iterator_tag{};
1709 return input_iterator_tag{};
1712 using _Base_iter = iterator_t<_Base>;
1714 _Base_iter _M_current = _Base_iter();
1715 _Parent* _M_parent = nullptr;
1718 using iterator_concept = decltype(_S_iter_concept());
1719 // iterator_category defined in __transform_view_iter_cat
1721 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1722 using difference_type = range_difference_t<_Base>;
1724 _Iterator() requires default_initializable<_Base_iter> = default;
1727 _Iterator(_Parent* __parent, _Base_iter __current)
1728 : _M_current(std::move(__current)),
1733 _Iterator(_Iterator<!_Const> __i)
1735 && convertible_to<iterator_t<_Vp>, _Base_iter>
1736 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1739 constexpr const _Base_iter&
1740 base() const & noexcept
1741 { return _M_current; }
1743 constexpr _Base_iter
1745 { return std::move(_M_current); }
1747 constexpr decltype(auto)
1749 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1750 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1752 constexpr _Iterator&
1764 operator++(int) requires forward_range<_Base>
1771 constexpr _Iterator&
1772 operator--() requires bidirectional_range<_Base>
1779 operator--(int) requires bidirectional_range<_Base>
1786 constexpr _Iterator&
1787 operator+=(difference_type __n) requires random_access_range<_Base>
1793 constexpr _Iterator&
1794 operator-=(difference_type __n) requires random_access_range<_Base>
1800 constexpr decltype(auto)
1801 operator[](difference_type __n) const
1802 requires random_access_range<_Base>
1803 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1805 friend constexpr bool
1806 operator==(const _Iterator& __x, const _Iterator& __y)
1807 requires equality_comparable<_Base_iter>
1808 { return __x._M_current == __y._M_current; }
1810 friend constexpr bool
1811 operator<(const _Iterator& __x, const _Iterator& __y)
1812 requires random_access_range<_Base>
1813 { return __x._M_current < __y._M_current; }
1815 friend constexpr bool
1816 operator>(const _Iterator& __x, const _Iterator& __y)
1817 requires random_access_range<_Base>
1818 { return __y < __x; }
1820 friend constexpr bool
1821 operator<=(const _Iterator& __x, const _Iterator& __y)
1822 requires random_access_range<_Base>
1823 { return !(__y < __x); }
1825 friend constexpr bool
1826 operator>=(const _Iterator& __x, const _Iterator& __y)
1827 requires random_access_range<_Base>
1828 { return !(__x < __y); }
1830#ifdef __cpp_lib_three_way_comparison
1831 friend constexpr auto
1832 operator<=>(const _Iterator& __x, const _Iterator& __y)
1833 requires random_access_range<_Base>
1834 && three_way_comparable<_Base_iter>
1835 { return __x._M_current <=> __y._M_current; }
1838 friend constexpr _Iterator
1839 operator+(_Iterator __i, difference_type __n)
1840 requires random_access_range<_Base>
1841 { return {__i._M_parent, __i._M_current + __n}; }
1843 friend constexpr _Iterator
1844 operator+(difference_type __n, _Iterator __i)
1845 requires random_access_range<_Base>
1846 { return {__i._M_parent, __i._M_current + __n}; }
1848 friend constexpr _Iterator
1849 operator-(_Iterator __i, difference_type __n)
1850 requires random_access_range<_Base>
1851 { return {__i._M_parent, __i._M_current - __n}; }
1853 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1854 // 3483. transform_view::iterator's difference is overconstrained
1855 friend constexpr difference_type
1856 operator-(const _Iterator& __x, const _Iterator& __y)
1857 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
1858 { return __x._M_current - __y._M_current; }
1860 friend constexpr decltype(auto)
1861 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
1863 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
1864 return std::move(*__i);
1869 friend _Iterator<!_Const>;
1870 template<bool> friend struct _Sentinel;
1873 template<bool _Const>
1877 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1878 using _Base = transform_view::_Base<_Const>;
1880 template<bool _Const2>
1882 __distance_from(const _Iterator<_Const2>& __i) const
1883 { return _M_end - __i._M_current; }
1885 template<bool _Const2>
1887 __equal(const _Iterator<_Const2>& __i) const
1888 { return __i._M_current == _M_end; }
1890 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1893 _Sentinel() = default;
1896 _Sentinel(sentinel_t<_Base> __end)
1901 _Sentinel(_Sentinel<!_Const> __i)
1903 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1904 : _M_end(std::move(__i._M_end))
1907 constexpr sentinel_t<_Base>
1911 template<bool _Const2>
1912 requires sentinel_for<sentinel_t<_Base>,
1913 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
1914 friend constexpr bool
1915 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1916 { return __y.__equal(__x); }
1918 template<bool _Const2,
1919 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1920 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1921 friend constexpr range_difference_t<_Base2>
1922 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1923 { return -__y.__distance_from(__x); }
1925 template<bool _Const2,
1926 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1927 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1928 friend constexpr range_difference_t<_Base2>
1929 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
1930 { return __y.__distance_from(__x); }
1932 friend _Sentinel<!_Const>;
1935 _Vp _M_base = _Vp();
1936 __detail::__box<_Fp> _M_fun;
1939 transform_view() requires default_initializable<_Vp> = default;
1942 transform_view(_Vp __base, _Fp __fun)
1943 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
1947 base() const& requires copy_constructible<_Vp>
1948 { return _M_base ; }
1952 { return std::move(_M_base); }
1954 constexpr _Iterator<false>
1956 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
1958 constexpr _Iterator<true>
1960 requires range<const _Vp>
1961 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1962 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
1964 constexpr _Sentinel<false>
1966 { return _Sentinel<false>{ranges::end(_M_base)}; }
1968 constexpr _Iterator<false>
1969 end() requires common_range<_Vp>
1970 { return _Iterator<false>{this, ranges::end(_M_base)}; }
1972 constexpr _Sentinel<true>
1974 requires range<const _Vp>
1975 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1976 { return _Sentinel<true>{ranges::end(_M_base)}; }
1978 constexpr _Iterator<true>
1980 requires common_range<const _Vp>
1981 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1982 { return _Iterator<true>{this, ranges::end(_M_base)}; }
1985 size() requires sized_range<_Vp>
1986 { return ranges::size(_M_base); }
1989 size() const requires sized_range<const _Vp>
1990 { return ranges::size(_M_base); }
1993 template<typename _Range, typename _Fp>
1994 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
1998 inline constexpr __adaptor::_RangeAdaptor transform
1999 = [] <viewable_range _Range, typename _Fp> (_Range&& __r, _Fp&& __f)
2001 return transform_view{std::forward<_Range>(__r), std::forward<_Fp>(__f)};
2003 } // namespace views
2006 class take_view : public view_interface<take_view<_Vp>>
2009 template<bool _Const>
2010 using _CI = counted_iterator<
2011 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2013 template<bool _Const>
2017 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2018 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2021 _Sentinel() = default;
2024 _Sentinel(sentinel_t<_Base> __end)
2029 _Sentinel(_Sentinel<!_Const> __s)
2030 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2031 : _M_end(std::move(__s._M_end))
2034 constexpr sentinel_t<_Base>
2038 friend constexpr bool
2039 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2040 { return __y.count() == 0 || __y.base() == __x._M_end; }
2042 template<bool _OtherConst = !_Const,
2043 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2044 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2045 friend constexpr bool
2046 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2047 { return __y.count() == 0 || __y.base() == __x._M_end; }
2049 friend _Sentinel<!_Const>;
2052 _Vp _M_base = _Vp();
2053 range_difference_t<_Vp> _M_count = 0;
2056 take_view() requires default_initializable<_Vp> = default;
2059 take_view(_Vp base, range_difference_t<_Vp> __count)
2060 : _M_base(std::move(base)), _M_count(std::move(__count))
2064 base() const& requires copy_constructible<_Vp>
2069 { return std::move(_M_base); }
2072 begin() requires (!__detail::__simple_view<_Vp>)
2074 if constexpr (sized_range<_Vp>)
2076 if constexpr (random_access_range<_Vp>)
2077 return ranges::begin(_M_base);
2081 return counted_iterator{ranges::begin(_M_base), __sz};
2085 return counted_iterator{ranges::begin(_M_base), _M_count};
2089 begin() const requires range<const _Vp>
2091 if constexpr (sized_range<const _Vp>)
2093 if constexpr (random_access_range<const _Vp>)
2094 return ranges::begin(_M_base);
2098 return counted_iterator{ranges::begin(_M_base), __sz};
2102 return counted_iterator{ranges::begin(_M_base), _M_count};
2106 end() requires (!__detail::__simple_view<_Vp>)
2108 if constexpr (sized_range<_Vp>)
2110 if constexpr (random_access_range<_Vp>)
2111 return ranges::begin(_M_base) + size();
2113 return default_sentinel;
2116 return _Sentinel<false>{ranges::end(_M_base)};
2120 end() const requires range<const _Vp>
2122 if constexpr (sized_range<const _Vp>)
2124 if constexpr (random_access_range<const _Vp>)
2125 return ranges::begin(_M_base) + size();
2127 return default_sentinel;
2130 return _Sentinel<true>{ranges::end(_M_base)};
2134 size() requires sized_range<_Vp>
2136 auto __n = ranges::size(_M_base);
2137 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2141 size() const requires sized_range<const _Vp>
2143 auto __n = ranges::size(_M_base);
2144 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2148 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2149 // 3447. Deduction guides for take_view and drop_view have different
2151 template<typename _Range>
2152 take_view(_Range&&, range_difference_t<_Range>)
2153 -> take_view<views::all_t<_Range>>;
2155 template<typename _Tp>
2156 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2157 = enable_borrowed_range<_Tp>;
2161 inline constexpr __adaptor::_RangeAdaptor take
2162 = [] <viewable_range _Range, typename _Tp> (_Range&& __r, _Tp&& __n)
2164 return take_view{std::forward<_Range>(__r), std::forward<_Tp>(__n)};
2166 } // namespace views
2168 template<view _Vp, typename _Pred>
2169 requires input_range<_Vp> && is_object_v<_Pred>
2170 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2171 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2173 template<bool _Const>
2177 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2179 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2180 const _Pred* _M_pred = nullptr;
2183 _Sentinel() = default;
2186 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2187 : _M_end(__end), _M_pred(__pred)
2191 _Sentinel(_Sentinel<!_Const> __s)
2192 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2193 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2196 constexpr sentinel_t<_Base>
2197 base() const { return _M_end; }
2199 friend constexpr bool
2200 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2201 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2203 template<bool _OtherConst = !_Const,
2204 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2205 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2206 friend constexpr bool
2207 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2208 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2210 friend _Sentinel<!_Const>;
2213 _Vp _M_base = _Vp();
2214 __detail::__box<_Pred> _M_pred;
2217 take_while_view() requires default_initializable<_Vp> = default;
2220 take_while_view(_Vp base, _Pred __pred)
2221 : _M_base(std::move(base)), _M_pred(std::move(__pred))
2226 base() const& requires copy_constructible<_Vp>
2231 { return std::move(_M_base); }
2233 constexpr const _Pred&
2235 { return *_M_pred; }
2238 begin() requires (!__detail::__simple_view<_Vp>)
2239 { return ranges::begin(_M_base); }
2242 begin() const requires range<const _Vp>
2243 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2244 { return ranges::begin(_M_base); }
2247 end() requires (!__detail::__simple_view<_Vp>)
2248 { return _Sentinel<false>(ranges::end(_M_base),
2249 std::__addressof(*_M_pred)); }
2252 end() const requires range<const _Vp>
2253 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2254 { return _Sentinel<true>(ranges::end(_M_base),
2255 std::__addressof(*_M_pred)); }
2258 template<typename _Range, typename _Pred>
2259 take_while_view(_Range&&, _Pred)
2260 -> take_while_view<views::all_t<_Range>, _Pred>;
2264 inline constexpr __adaptor::_RangeAdaptor take_while
2265 = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p)
2267 return take_while_view{std::forward<_Range>(__r), std::forward<_Pred>(__p)};
2269 } // namespace views
2272 class drop_view : public view_interface<drop_view<_Vp>>
2275 _Vp _M_base = _Vp();
2276 range_difference_t<_Vp> _M_count = 0;
2278 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2279 // both random_access_range and sized_range. Otherwise, cache its result.
2280 static constexpr bool _S_needs_cached_begin
2281 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2282 [[no_unique_address]]
2283 __detail::__maybe_present_t<_S_needs_cached_begin,
2284 __detail::_CachedPosition<_Vp>>
2288 drop_view() requires default_initializable<_Vp> = default;
2291 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2292 : _M_base(std::move(__base)), _M_count(__count)
2293 { __glibcxx_assert(__count >= 0); }
2296 base() const& requires copy_constructible<_Vp>
2301 { return std::move(_M_base); }
2303 // This overload is disabled for simple views with constant-time begin().
2306 requires (!(__detail::__simple_view<_Vp>
2307 && random_access_range<const _Vp>
2308 && sized_range<const _Vp>))
2310 if constexpr (_S_needs_cached_begin)
2311 if (_M_cached_begin._M_has_value())
2312 return _M_cached_begin._M_get(_M_base);
2314 auto __it = ranges::next(ranges::begin(_M_base),
2315 _M_count, ranges::end(_M_base));
2316 if constexpr (_S_needs_cached_begin)
2317 _M_cached_begin._M_set(_M_base, __it);
2321 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2322 // 3482. drop_view's const begin should additionally require sized_range
2325 requires random_access_range<const _Vp> && sized_range<const _Vp>
2327 return ranges::next(ranges::begin(_M_base), _M_count,
2328 ranges::end(_M_base));
2332 end() requires (!__detail::__simple_view<_Vp>)
2333 { return ranges::end(_M_base); }
2336 end() const requires range<const _Vp>
2337 { return ranges::end(_M_base); }
2340 size() requires sized_range<_Vp>
2342 const auto __s = ranges::size(_M_base);
2343 const auto __c = static_cast<decltype(__s)>(_M_count);
2344 return __s < __c ? 0 : __s - __c;
2348 size() const requires sized_range<const _Vp>
2350 const auto __s = ranges::size(_M_base);
2351 const auto __c = static_cast<decltype(__s)>(_M_count);
2352 return __s < __c ? 0 : __s - __c;
2356 template<typename _Range>
2357 drop_view(_Range&&, range_difference_t<_Range>)
2358 -> drop_view<views::all_t<_Range>>;
2360 template<typename _Tp>
2361 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2362 = enable_borrowed_range<_Tp>;
2366 inline constexpr __adaptor::_RangeAdaptor drop
2367 = [] <viewable_range _Range, typename _Tp> (_Range&& __r, _Tp&& __n)
2369 return drop_view{std::forward<_Range>(__r), std::forward<_Tp>(__n)};
2371 } // namespace views
2373 template<view _Vp, typename _Pred>
2374 requires input_range<_Vp> && is_object_v<_Pred>
2375 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2376 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2379 _Vp _M_base = _Vp();
2380 __detail::__box<_Pred> _M_pred;
2381 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2384 drop_while_view() requires default_initializable<_Vp> = default;
2387 drop_while_view(_Vp __base, _Pred __pred)
2388 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2392 base() const& requires copy_constructible<_Vp>
2397 { return std::move(_M_base); }
2399 constexpr const _Pred&
2401 { return *_M_pred; }
2406 if (_M_cached_begin._M_has_value())
2407 return _M_cached_begin._M_get(_M_base);
2409 __glibcxx_assert(_M_pred.has_value());
2410 auto __it = __detail::find_if_not(ranges::begin(_M_base),
2411 ranges::end(_M_base),
2412 std::cref(*_M_pred));
2413 _M_cached_begin._M_set(_M_base, __it);
2419 { return ranges::end(_M_base); }
2422 template<typename _Range, typename _Pred>
2423 drop_while_view(_Range&&, _Pred)
2424 -> drop_while_view<views::all_t<_Range>, _Pred>;
2426 template<typename _Tp, typename _Pred>
2427 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2428 = enable_borrowed_range<_Tp>;
2432 inline constexpr __adaptor::_RangeAdaptor drop_while
2433 = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p)
2435 return drop_while_view{std::forward<_Range>(__r),
2436 std::forward<_Pred>(__p)};
2438 } // namespace views
2440 template<input_range _Vp>
2441 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2442 && (is_reference_v<range_reference_t<_Vp>>
2443 || view<range_value_t<_Vp>>)
2444 class join_view : public view_interface<join_view<_Vp>>
2447 using _InnerRange = range_reference_t<_Vp>;
2449 template<bool _Const>
2450 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2452 template<bool _Const>
2453 using _Outer_iter = iterator_t<_Base<_Const>>;
2455 template<bool _Const>
2456 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2458 template<bool _Const>
2459 static constexpr bool _S_ref_is_glvalue
2460 = is_reference_v<range_reference_t<_Base<_Const>>>;
2462 template<bool _Const>
2466 template<bool _Const>
2467 requires _S_ref_is_glvalue<_Const>
2468 && forward_range<_Base<_Const>>
2469 && forward_range<range_reference_t<_Base<_Const>>>
2470 struct __iter_cat<_Const>
2473 static constexpr auto
2476 using _Outer_iter = join_view::_Outer_iter<_Const>;
2477 using _Inner_iter = join_view::_Inner_iter<_Const>;
2478 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2479 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2480 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2481 && derived_from<_InnerCat, bidirectional_iterator_tag>)
2482 return bidirectional_iterator_tag{};
2483 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2484 && derived_from<_InnerCat, forward_iterator_tag>)
2485 return forward_iterator_tag{};
2487 return input_iterator_tag{};
2490 using iterator_category = decltype(_S_iter_cat());
2493 template<bool _Const>
2496 template<bool _Const>
2497 struct _Iterator : __iter_cat<_Const>
2500 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2501 using _Base = join_view::_Base<_Const>;
2503 static constexpr bool _S_ref_is_glvalue
2504 = join_view::_S_ref_is_glvalue<_Const>;
2509 auto __update_inner = [this] (range_reference_t<_Base> __x) -> auto&
2511 if constexpr (_S_ref_is_glvalue)
2514 return (_M_parent->_M_inner = views::all(std::move(__x)));
2517 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2519 auto& __inner = __update_inner(*_M_outer);
2520 _M_inner = ranges::begin(__inner);
2521 if (_M_inner != ranges::end(__inner))
2525 if constexpr (_S_ref_is_glvalue)
2526 _M_inner = _Inner_iter();
2529 static constexpr auto
2532 if constexpr (_S_ref_is_glvalue
2533 && bidirectional_range<_Base>
2534 && bidirectional_range<range_reference_t<_Base>>)
2535 return bidirectional_iterator_tag{};
2536 else if constexpr (_S_ref_is_glvalue
2537 && forward_range<_Base>
2538 && forward_range<range_reference_t<_Base>>)
2539 return forward_iterator_tag{};
2541 return input_iterator_tag{};
2544 using _Outer_iter = join_view::_Outer_iter<_Const>;
2545 using _Inner_iter = join_view::_Inner_iter<_Const>;
2547 _Outer_iter _M_outer = _Outer_iter();
2548 _Inner_iter _M_inner = _Inner_iter();
2549 _Parent* _M_parent = nullptr;
2552 using iterator_concept = decltype(_S_iter_concept());
2553 // iterator_category defined in __join_view_iter_cat
2554 using value_type = range_value_t<range_reference_t<_Base>>;
2555 using difference_type
2556 = common_type_t<range_difference_t<_Base>,
2557 range_difference_t<range_reference_t<_Base>>>;
2559 _Iterator() requires (default_initializable<_Outer_iter>
2560 && default_initializable<_Inner_iter>)
2564 _Iterator(_Parent* __parent, _Outer_iter __outer)
2565 : _M_outer(std::move(__outer)),
2570 _Iterator(_Iterator<!_Const> __i)
2572 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2573 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2574 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
2575 _M_parent(__i._M_parent)
2578 constexpr decltype(auto)
2580 { return *_M_inner; }
2582 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2583 // 3500. join_view::iterator::operator->() is bogus
2584 constexpr _Inner_iter
2586 requires __detail::__has_arrow<_Inner_iter>
2587 && copyable<_Inner_iter>
2588 { return _M_inner; }
2590 constexpr _Iterator&
2593 auto&& __inner_range = [this] () -> auto&& {
2594 if constexpr (_S_ref_is_glvalue)
2597 return _M_parent->_M_inner;
2599 if (++_M_inner == ranges::end(__inner_range))
2613 requires _S_ref_is_glvalue && forward_range<_Base>
2614 && forward_range<range_reference_t<_Base>>
2621 constexpr _Iterator&
2623 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2624 && bidirectional_range<range_reference_t<_Base>>
2625 && common_range<range_reference_t<_Base>>
2627 if (_M_outer == ranges::end(_M_parent->_M_base))
2628 _M_inner = ranges::end(*--_M_outer);
2629 while (_M_inner == ranges::begin(*_M_outer))
2630 _M_inner = ranges::end(*--_M_outer);
2637 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2638 && bidirectional_range<range_reference_t<_Base>>
2639 && common_range<range_reference_t<_Base>>
2646 friend constexpr bool
2647 operator==(const _Iterator& __x, const _Iterator& __y)
2648 requires _S_ref_is_glvalue
2649 && equality_comparable<_Outer_iter>
2650 && equality_comparable<_Inner_iter>
2652 return (__x._M_outer == __y._M_outer
2653 && __x._M_inner == __y._M_inner);
2656 friend constexpr decltype(auto)
2657 iter_move(const _Iterator& __i)
2658 noexcept(noexcept(ranges::iter_move(__i._M_inner)))
2659 { return ranges::iter_move(__i._M_inner); }
2661 friend constexpr void
2662 iter_swap(const _Iterator& __x, const _Iterator& __y)
2663 noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner)))
2664 requires indirectly_swappable<_Inner_iter>
2665 { return ranges::iter_swap(__x._M_inner, __y._M_inner); }
2667 friend _Iterator<!_Const>;
2668 template<bool> friend struct _Sentinel;
2671 template<bool _Const>
2675 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2676 using _Base = join_view::_Base<_Const>;
2678 template<bool _Const2>
2680 __equal(const _Iterator<_Const2>& __i) const
2681 { return __i._M_outer == _M_end; }
2683 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2686 _Sentinel() = default;
2689 _Sentinel(_Parent* __parent)
2690 : _M_end(ranges::end(__parent->_M_base))
2694 _Sentinel(_Sentinel<!_Const> __s)
2695 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2696 : _M_end(std::move(__s._M_end))
2699 template<bool _Const2>
2700 requires sentinel_for<sentinel_t<_Base>,
2701 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2702 friend constexpr bool
2703 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2704 { return __y.__equal(__x); }
2706 friend _Sentinel<!_Const>;
2709 _Vp _M_base = _Vp();
2711 // XXX: _M_inner is "present only when !is_reference_v<_InnerRange>"
2712 [[no_unique_address]]
2713 __detail::__maybe_present_t<!is_reference_v<_InnerRange>,
2714 views::all_t<_InnerRange>> _M_inner;
2717 join_view() requires default_initializable<_Vp> = default;
2720 join_view(_Vp __base)
2721 : _M_base(std::move(__base))
2725 base() const& requires copy_constructible<_Vp>
2730 { return std::move(_M_base); }
2735 constexpr bool __use_const
2736 = (__detail::__simple_view<_Vp>
2737 && is_reference_v<range_reference_t<_Vp>>);
2738 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
2743 requires input_range<const _Vp>
2744 && is_reference_v<range_reference_t<const _Vp>>
2746 return _Iterator<true>{this, ranges::begin(_M_base)};
2752 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
2753 && forward_range<_InnerRange>
2754 && common_range<_Vp> && common_range<_InnerRange>)
2755 return _Iterator<__detail::__simple_view<_Vp>>{this,
2756 ranges::end(_M_base)};
2758 return _Sentinel<__detail::__simple_view<_Vp>>{this};
2763 requires input_range<const _Vp>
2764 && is_reference_v<range_reference_t<const _Vp>>
2766 if constexpr (forward_range<const _Vp>
2767 && is_reference_v<range_reference_t<const _Vp>>
2768 && forward_range<range_reference_t<const _Vp>>
2769 && common_range<const _Vp>
2770 && common_range<range_reference_t<const _Vp>>)
2771 return _Iterator<true>{this, ranges::end(_M_base)};
2773 return _Sentinel<true>{this};
2777 template<typename _Range>
2778 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
2782 inline constexpr __adaptor::_RangeAdaptorClosure join
2783 = [] <viewable_range _Range> (_Range&& __r)
2785 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2786 // 3474. Nesting join_views is broken because of CTAD
2787 return join_view<views::all_t<_Range>>{std::forward<_Range>(__r)};
2789 } // namespace views
2794 struct __require_constant;
2796 template<typename _Range>
2797 concept __tiny_range = sized_range<_Range>
2799 { typename __require_constant<remove_reference_t<_Range>::size()>; }
2800 && (remove_reference_t<_Range>::size() <= 1);
2802 template<typename _Base>
2803 struct __split_view_outer_iter_cat
2806 template<forward_range _Base>
2807 struct __split_view_outer_iter_cat<_Base>
2808 { using iterator_category = input_iterator_tag; };
2810 template<typename _Base>
2811 struct __split_view_inner_iter_cat
2814 template<forward_range _Base>
2815 struct __split_view_inner_iter_cat<_Base>
2818 static constexpr auto
2821 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
2822 if constexpr (derived_from<_Cat, forward_iterator_tag>)
2823 return forward_iterator_tag{};
2828 using iterator_category = decltype(_S_iter_cat());
2832 template<input_range _Vp, forward_range _Pattern>
2833 requires view<_Vp> && view<_Pattern>
2834 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
2836 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
2837 class split_view : public view_interface<split_view<_Vp, _Pattern>>
2840 template<bool _Const>
2841 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2843 template<bool _Const>
2846 template<bool _Const>
2848 : __detail::__split_view_outer_iter_cat<_Base<_Const>>
2851 using _Parent = __detail::__maybe_const_t<_Const, split_view>;
2852 using _Base = split_view::_Base<_Const>;
2856 { return __current() == ranges::end(_M_parent->_M_base); }
2858 // [range.split.outer] p1
2859 // Many of the following specifications refer to the notional member
2860 // current of outer-iterator. current is equivalent to current_ if
2861 // V models forward_range, and parent_->current_ otherwise.
2863 __current() noexcept
2865 if constexpr (forward_range<_Vp>)
2868 return _M_parent->_M_current;
2872 __current() const noexcept
2874 if constexpr (forward_range<_Vp>)
2877 return _M_parent->_M_current;
2880 _Parent* _M_parent = nullptr;
2882 // XXX: _M_current is present only if "V models forward_range"
2883 [[no_unique_address]]
2884 __detail::__maybe_present_t<forward_range<_Vp>,
2885 iterator_t<_Base>> _M_current;
2888 using iterator_concept = conditional_t<forward_range<_Base>,
2889 forward_iterator_tag,
2890 input_iterator_tag>;
2891 // iterator_category defined in __split_view_outer_iter_cat
2892 using difference_type = range_difference_t<_Base>;
2894 struct value_type : view_interface<value_type>
2897 _OuterIter _M_i = _OuterIter();
2900 value_type() = default;
2903 value_type(_OuterIter __i)
2904 : _M_i(std::move(__i))
2907 constexpr _InnerIter<_Const>
2909 { return _InnerIter<_Const>{_M_i}; }
2911 constexpr default_sentinel_t
2913 { return default_sentinel; }
2916 _OuterIter() = default;
2919 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
2920 : _M_parent(__parent)
2924 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
2925 requires forward_range<_Base>
2926 : _M_parent(__parent),
2927 _M_current(std::move(__current))
2931 _OuterIter(_OuterIter<!_Const> __i)
2933 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
2934 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current))
2937 constexpr value_type
2939 { return value_type{*this}; }
2941 constexpr _OuterIter&
2944 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2945 // 3505. split_view::outer-iterator::operator++ misspecified
2946 const auto __end = ranges::end(_M_parent->_M_base);
2947 if (__current() == __end)
2949 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
2950 if (__pbegin == __pend)
2952 else if constexpr (__detail::__tiny_range<_Pattern>)
2954 __current() = __detail::find(std::move(__current()), __end,
2956 if (__current() != __end)
2963 = __detail::mismatch(__current(), __end, __pbegin, __pend);
2969 } while (++__current() != __end);
2973 constexpr decltype(auto)
2976 if constexpr (forward_range<_Base>)
2986 friend constexpr bool
2987 operator==(const _OuterIter& __x, const _OuterIter& __y)
2988 requires forward_range<_Base>
2989 { return __x._M_current == __y._M_current; }
2991 friend constexpr bool
2992 operator==(const _OuterIter& __x, default_sentinel_t)
2993 { return __x.__at_end(); };
2995 friend _OuterIter<!_Const>;
2996 friend _InnerIter<_Const>;
2999 template<bool _Const>
3001 : __detail::__split_view_inner_iter_cat<_Base<_Const>>
3004 using _Base = split_view::_Base<_Const>;
3009 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3010 auto __end = ranges::end(_M_i._M_parent->_M_base);
3011 if constexpr (__detail::__tiny_range<_Pattern>)
3013 const auto& __cur = _M_i_current();
3016 if (__pcur == __pend)
3017 return _M_incremented;
3018 return *__cur == *__pcur;
3022 auto __cur = _M_i_current();
3025 if (__pcur == __pend)
3026 return _M_incremented;
3029 if (*__cur != *__pcur)
3031 if (++__pcur == __pend)
3033 } while (++__cur != __end);
3039 _M_i_current() noexcept
3040 { return _M_i.__current(); }
3043 _M_i_current() const noexcept
3044 { return _M_i.__current(); }
3046 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3047 bool _M_incremented = false;
3050 using iterator_concept
3051 = typename _OuterIter<_Const>::iterator_concept;
3052 // iterator_category defined in __split_view_inner_iter_cat
3053 using value_type = range_value_t<_Base>;
3054 using difference_type = range_difference_t<_Base>;
3056 _InnerIter() = default;
3059 _InnerIter(_OuterIter<_Const> __i)
3060 : _M_i(std::move(__i))
3063 constexpr const iterator_t<_Base>&
3064 base() const& noexcept
3065 { return _M_i_current(); }
3067 constexpr iterator_t<_Base>
3069 { return std::move(_M_i_current()); }
3071 constexpr decltype(auto)
3073 { return *_M_i_current(); }
3075 constexpr _InnerIter&
3078 _M_incremented = true;
3079 if constexpr (!forward_range<_Base>)
3080 if constexpr (_Pattern::size() == 0)
3086 constexpr decltype(auto)
3089 if constexpr (forward_range<_Base>)
3099 friend constexpr bool
3100 operator==(const _InnerIter& __x, const _InnerIter& __y)
3101 requires forward_range<_Base>
3102 { return __x._M_i == __y._M_i; }
3104 friend constexpr bool
3105 operator==(const _InnerIter& __x, default_sentinel_t)
3106 { return __x.__at_end(); }
3108 friend constexpr decltype(auto)
3109 iter_move(const _InnerIter& __i)
3110 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3111 { return ranges::iter_move(__i._M_i_current()); }
3113 friend constexpr void
3114 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3115 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3116 __y._M_i_current())))
3117 requires indirectly_swappable<iterator_t<_Base>>
3118 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3121 _Vp _M_base = _Vp();
3122 _Pattern _M_pattern = _Pattern();
3124 // XXX: _M_current is "present only if !forward_range<V>"
3125 [[no_unique_address]]
3126 __detail::__maybe_present_t<!forward_range<_Vp>, iterator_t<_Vp>>
3131 split_view() requires (default_initializable<_Vp>
3132 && default_initializable<_Pattern>
3133 && default_initializable<iterator_t<_Vp>>)
3137 split_view(_Vp __base, _Pattern __pattern)
3138 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3141 template<input_range _Range>
3142 requires constructible_from<_Vp, views::all_t<_Range>>
3143 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3145 split_view(_Range&& __r, range_value_t<_Range> __e)
3146 : _M_base(views::all(std::forward<_Range>(__r))),
3147 _M_pattern(std::move(__e))
3151 base() const& requires copy_constructible<_Vp>
3156 { return std::move(_M_base); }
3161 if constexpr (forward_range<_Vp>)
3162 return _OuterIter<__detail::__simple_view<_Vp>>{
3163 this, ranges::begin(_M_base)};
3166 _M_current = ranges::begin(_M_base);
3167 return _OuterIter<false>{this};
3172 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3174 return _OuterIter<true>{this, ranges::begin(_M_base)};
3178 end() requires forward_range<_Vp> && common_range<_Vp>
3180 return _OuterIter<__detail::__simple_view<_Vp>>{
3181 this, ranges::end(_M_base)};
3187 if constexpr (forward_range<_Vp>
3188 && forward_range<const _Vp>
3189 && common_range<const _Vp>)
3190 return _OuterIter<true>{this, ranges::end(_M_base)};
3192 return default_sentinel;
3196 template<typename _Range, typename _Pred>
3197 split_view(_Range&&, _Pred&&)
3198 -> split_view<views::all_t<_Range>, views::all_t<_Pred>>;
3200 template<input_range _Range>
3201 split_view(_Range&&, range_value_t<_Range>)
3202 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3206 inline constexpr __adaptor::_RangeAdaptor split
3207 = [] <viewable_range _Range, typename _Fp> (_Range&& __r, _Fp&& __f)
3209 return split_view{std::forward<_Range>(__r), std::forward<_Fp>(__f)};
3211 } // namespace views
3217 template<input_or_output_iterator _Iter>
3219 operator()(_Iter __i, iter_difference_t<_Iter> __n) const
3221 if constexpr (random_access_iterator<_Iter>)
3222 return subrange{__i, __i + __n};
3224 return subrange{counted_iterator{std::move(__i), __n},
3229 inline constexpr _Counted counted{};
3230 } // namespace views
3233 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3234 class common_view : public view_interface<common_view<_Vp>>
3237 _Vp _M_base = _Vp();
3240 common_view() requires default_initializable<_Vp> = default;
3243 common_view(_Vp __r)
3244 : _M_base(std::move(__r))
3247 /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
3248 template<viewable_range _Range>
3249 requires (!common_range<_Range>)
3250 && constructible_from<_Vp, views::all_t<_Range>>
3252 common_view(_Range&& __r)
3253 : _M_base(views::all(std::forward<_Range>(__r)))
3258 base() const& requires copy_constructible<_Vp>
3263 { return std::move(_M_base); }
3268 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3269 return ranges::begin(_M_base);
3271 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3272 (ranges::begin(_M_base));
3276 begin() const requires range<const _Vp>
3278 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3279 return ranges::begin(_M_base);
3281 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3282 (ranges::begin(_M_base));
3288 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3289 return ranges::begin(_M_base) + ranges::size(_M_base);
3291 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3292 (ranges::end(_M_base));
3296 end() const requires range<const _Vp>
3298 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3299 return ranges::begin(_M_base) + ranges::size(_M_base);
3301 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3302 (ranges::end(_M_base));
3306 size() requires sized_range<_Vp>
3307 { return ranges::size(_M_base); }
3310 size() const requires sized_range<const _Vp>
3311 { return ranges::size(_M_base); }
3314 template<typename _Range>
3315 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3317 template<typename _Tp>
3318 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3319 = enable_borrowed_range<_Tp>;
3323 inline constexpr __adaptor::_RangeAdaptorClosure common
3324 = [] <viewable_range _Range> (_Range&& __r)
3326 if constexpr (common_range<_Range>
3327 && requires { views::all(std::forward<_Range>(__r)); })
3328 return views::all(std::forward<_Range>(__r));
3330 return common_view{std::forward<_Range>(__r)};
3333 } // namespace views
3336 requires bidirectional_range<_Vp>
3337 class reverse_view : public view_interface<reverse_view<_Vp>>
3340 _Vp _M_base = _Vp();
3342 static constexpr bool _S_needs_cached_begin
3343 = !common_range<_Vp> && !random_access_range<_Vp>;
3344 [[no_unique_address]]
3345 __detail::__maybe_present_t<_S_needs_cached_begin,
3346 __detail::_CachedPosition<_Vp>>
3350 reverse_view() requires default_initializable<_Vp> = default;
3353 reverse_view(_Vp __r)
3354 : _M_base(std::move(__r))
3358 base() const& requires copy_constructible<_Vp>
3363 { return std::move(_M_base); }
3365 constexpr reverse_iterator<iterator_t<_Vp>>
3368 if constexpr (_S_needs_cached_begin)
3369 if (_M_cached_begin._M_has_value())
3370 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
3372 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3373 if constexpr (_S_needs_cached_begin)
3374 _M_cached_begin._M_set(_M_base, __it);
3375 return std::make_reverse_iterator(std::move(__it));
3379 begin() requires common_range<_Vp>
3380 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3383 begin() const requires common_range<const _Vp>
3384 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3386 constexpr reverse_iterator<iterator_t<_Vp>>
3388 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3391 end() const requires common_range<const _Vp>
3392 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3395 size() requires sized_range<_Vp>
3396 { return ranges::size(_M_base); }
3399 size() const requires sized_range<const _Vp>
3400 { return ranges::size(_M_base); }
3403 template<typename _Range>
3404 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3406 template<typename _Tp>
3407 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
3408 = enable_borrowed_range<_Tp>;
3415 inline constexpr bool __is_reversible_subrange = false;
3417 template<typename _Iter, subrange_kind _Kind>
3418 inline constexpr bool
3419 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3420 reverse_iterator<_Iter>,
3424 inline constexpr bool __is_reverse_view = false;
3426 template<typename _Vp>
3427 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
3430 inline constexpr __adaptor::_RangeAdaptorClosure reverse
3431 = [] <viewable_range _Range> (_Range&& __r)
3433 using _Tp = remove_cvref_t<_Range>;
3434 if constexpr (__detail::__is_reverse_view<_Tp>)
3435 return std::forward<_Range>(__r).base();
3436 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3438 using _Iter = decltype(ranges::begin(__r).base());
3439 if constexpr (sized_range<_Tp>)
3440 return subrange<_Iter, _Iter, subrange_kind::sized>
3441 (__r.end().base(), __r.begin().base(), __r.size());
3443 return subrange<_Iter, _Iter, subrange_kind::unsized>
3444 (__r.end().base(), __r.begin().base());
3447 return reverse_view{std::forward<_Range>(__r)};
3449 } // namespace views
3453 template<typename _Tp, size_t _Nm>
3454 concept __has_tuple_element = requires(_Tp __t)
3456 typename tuple_size<_Tp>::type;
3457 requires _Nm < tuple_size_v<_Tp>;
3458 typename tuple_element_t<_Nm, _Tp>;
3459 { std::get<_Nm>(__t) }
3460 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
3463 template<typename _Tp, size_t _Nm>
3464 concept __returnable_element
3465 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
3468 template<input_range _Vp, size_t _Nm>
3470 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
3471 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
3473 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
3474 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
3477 elements_view() requires default_initializable<_Vp> = default;
3480 elements_view(_Vp base)
3481 : _M_base(std::move(base))
3485 base() const& requires copy_constructible<_Vp>
3490 { return std::move(_M_base); }
3493 begin() requires (!__detail::__simple_view<_Vp>)
3494 { return _Iterator<false>(ranges::begin(_M_base)); }
3497 begin() const requires range<const _Vp>
3498 { return _Iterator<true>(ranges::begin(_M_base)); }
3501 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
3502 { return _Sentinel<false>{ranges::end(_M_base)}; }
3505 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
3506 { return _Iterator<false>{ranges::end(_M_base)}; }
3509 end() const requires range<const _Vp>
3510 { return _Sentinel<true>{ranges::end(_M_base)}; }
3513 end() const requires common_range<const _Vp>
3514 { return _Iterator<true>{ranges::end(_M_base)}; }
3517 size() requires sized_range<_Vp>
3518 { return ranges::size(_M_base); }
3521 size() const requires sized_range<const _Vp>
3522 { return ranges::size(_M_base); }
3525 template<bool _Const>
3526 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3528 template<bool _Const>
3532 template<bool _Const>
3533 requires forward_range<_Base<_Const>>
3534 struct __iter_cat<_Const>
3537 static auto _S_iter_cat()
3539 using _Base = elements_view::_Base<_Const>;
3540 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3541 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
3542 if constexpr (!is_lvalue_reference_v<_Res>)
3543 return input_iterator_tag{};
3544 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
3545 return random_access_iterator_tag{};
3550 using iterator_category = decltype(_S_iter_cat());
3553 template<bool _Const>
3556 template<bool _Const>
3557 struct _Iterator : __iter_cat<_Const>
3560 using _Base = elements_view::_Base<_Const>;
3562 iterator_t<_Base> _M_current = iterator_t<_Base>();
3564 static constexpr decltype(auto)
3565 _S_get_element(const iterator_t<_Base>& __i)
3567 if constexpr (is_reference_v<range_reference_t<_Base>>)
3568 return std::get<_Nm>(*__i);
3571 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
3572 return static_cast<_Et>(std::get<_Nm>(*__i));
3579 if constexpr (random_access_range<_Base>)
3580 return random_access_iterator_tag{};
3581 else if constexpr (bidirectional_range<_Base>)
3582 return bidirectional_iterator_tag{};
3583 else if constexpr (forward_range<_Base>)
3584 return forward_iterator_tag{};
3586 return input_iterator_tag{};
3589 friend _Iterator<!_Const>;
3592 using iterator_concept = decltype(_S_iter_concept());
3593 // iterator_category defined in elements_view::__iter_cat
3595 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
3596 using difference_type = range_difference_t<_Base>;
3598 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
3601 _Iterator(iterator_t<_Base> current)
3602 : _M_current(std::move(current))
3606 _Iterator(_Iterator<!_Const> i)
3607 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3608 : _M_current(std::move(i._M_current))
3611 constexpr const iterator_t<_Base>&
3612 base() const& noexcept
3613 { return _M_current; }
3615 constexpr iterator_t<_Base>
3617 { return std::move(_M_current); }
3619 constexpr decltype(auto)
3621 { return _S_get_element(_M_current); }
3623 constexpr _Iterator&
3635 operator++(int) requires forward_range<_Base>
3642 constexpr _Iterator&
3643 operator--() requires bidirectional_range<_Base>
3650 operator--(int) requires bidirectional_range<_Base>
3657 constexpr _Iterator&
3658 operator+=(difference_type __n)
3659 requires random_access_range<_Base>
3665 constexpr _Iterator&
3666 operator-=(difference_type __n)
3667 requires random_access_range<_Base>
3673 constexpr decltype(auto)
3674 operator[](difference_type __n) const
3675 requires random_access_range<_Base>
3676 { return _S_get_element(_M_current + __n); }
3678 friend constexpr bool
3679 operator==(const _Iterator& __x, const _Iterator& __y)
3680 requires equality_comparable<iterator_t<_Base>>
3681 { return __x._M_current == __y._M_current; }
3683 friend constexpr bool
3684 operator<(const _Iterator& __x, const _Iterator& __y)
3685 requires random_access_range<_Base>
3686 { return __x._M_current < __y._M_current; }
3688 friend constexpr bool
3689 operator>(const _Iterator& __x, const _Iterator& __y)
3690 requires random_access_range<_Base>
3691 { return __y._M_current < __x._M_current; }
3693 friend constexpr bool
3694 operator<=(const _Iterator& __x, const _Iterator& __y)
3695 requires random_access_range<_Base>
3696 { return !(__y._M_current > __x._M_current); }
3698 friend constexpr bool
3699 operator>=(const _Iterator& __x, const _Iterator& __y)
3700 requires random_access_range<_Base>
3701 { return !(__x._M_current > __y._M_current); }
3703#ifdef __cpp_lib_three_way_comparison
3704 friend constexpr auto
3705 operator<=>(const _Iterator& __x, const _Iterator& __y)
3706 requires random_access_range<_Base>
3707 && three_way_comparable<iterator_t<_Base>>
3708 { return __x._M_current <=> __y._M_current; }
3711 friend constexpr _Iterator
3712 operator+(const _Iterator& __x, difference_type __y)
3713 requires random_access_range<_Base>
3714 { return _Iterator{__x} += __y; }
3716 friend constexpr _Iterator
3717 operator+(difference_type __x, const _Iterator& __y)
3718 requires random_access_range<_Base>
3719 { return __y + __x; }
3721 friend constexpr _Iterator
3722 operator-(const _Iterator& __x, difference_type __y)
3723 requires random_access_range<_Base>
3724 { return _Iterator{__x} -= __y; }
3726 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3727 // 3483. transform_view::iterator's difference is overconstrained
3728 friend constexpr difference_type
3729 operator-(const _Iterator& __x, const _Iterator& __y)
3730 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
3731 { return __x._M_current - __y._M_current; }
3733 template <bool> friend struct _Sentinel;
3736 template<bool _Const>
3740 template<bool _Const2>
3742 _M_equal(const _Iterator<_Const2>& __x) const
3743 { return __x._M_current == _M_end; }
3745 template<bool _Const2>
3747 _M_distance_from(const _Iterator<_Const2>& __i) const
3748 { return _M_end - __i._M_current; }
3750 using _Base = elements_view::_Base<_Const>;
3751 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3754 _Sentinel() = default;
3757 _Sentinel(sentinel_t<_Base> __end)
3758 : _M_end(std::move(__end))
3762 _Sentinel(_Sentinel<!_Const> __other)
3764 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3765 : _M_end(std::move(__other._M_end))
3768 constexpr sentinel_t<_Base>
3772 template<bool _Const2>
3773 requires sentinel_for<sentinel_t<_Base>,
3774 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3775 friend constexpr bool
3776 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3777 { return __y._M_equal(__x); }
3779 template<bool _Const2,
3780 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
3781 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
3782 friend constexpr range_difference_t<_Base2>
3783 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3784 { return -__y._M_distance_from(__x); }
3786 template<bool _Const2,
3787 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
3788 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
3789 friend constexpr range_difference_t<_Base2>
3790 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
3791 { return __x._M_distance_from(__y); }
3793 friend _Sentinel<!_Const>;
3796 _Vp _M_base = _Vp();
3799 template<typename _Tp, size_t _Nm>
3800 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
3801 = enable_borrowed_range<_Tp>;
3803 template<typename _Range>
3804 using keys_view = elements_view<views::all_t<_Range>, 0>;
3806 template<typename _Range>
3807 using values_view = elements_view<views::all_t<_Range>, 1>;
3811 template<size_t _Nm>
3812 inline constexpr __adaptor::_RangeAdaptorClosure elements
3813 = [] <viewable_range _Range> (_Range&& __r)
3815 using _El = elements_view<views::all_t<_Range>, _Nm>;
3816 return _El{std::forward<_Range>(__r)};
3819 inline constexpr __adaptor::_RangeAdaptorClosure keys = elements<0>;
3820 inline constexpr __adaptor::_RangeAdaptorClosure values = elements<1>;
3821 } // namespace views
3823} // namespace ranges
3825 namespace views = ranges::views;
3827 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3828 struct tuple_size<ranges::subrange<_Iter, _Sent, _Kind>>
3829 : integral_constant<size_t, 2>
3832 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3833 struct tuple_element<0, ranges::subrange<_Iter, _Sent, _Kind>>
3834 { using type = _Iter; };
3836 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3837 struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>>
3838 { using type = _Sent; };
3840 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3841 struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>>
3842 { using type = _Iter; };
3844 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3845 struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>>
3846 { using type = _Sent; };
3848_GLIBCXX_END_NAMESPACE_VERSION
3850#endif // library concepts
3852#endif /* _GLIBCXX_RANGES */