1 // <ranges> -*- C++ -*-
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
39 #if __cpp_lib_concepts
41 #include <bits/refwrap.h>
43 #include <initializer_list>
49 * @defgroup ranges Ranges
51 * Components for dealing with ranges of elements.
54 namespace 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> && default_initializable<_Tp>
76 /// A range which can be safely converted to a view.
77 template<typename _Tp>
78 concept viewable_range = range<_Tp>
79 && (borrowed_range<_Tp> || view<remove_cvref_t<_Tp>>);
83 template<typename _Range>
84 concept __simple_view = view<_Range> && range<const _Range>
85 && same_as<iterator_t<_Range>, iterator_t<const _Range>>
86 && same_as<sentinel_t<_Range>, sentinel_t<const _Range>>;
88 template<typename _It>
89 concept __has_arrow = input_iterator<_It>
90 && (is_pointer_v<_It> || requires(_It __it) { __it.operator->(); });
92 template<typename _Tp, typename _Up>
94 = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
95 } // namespace __detail
97 template<typename _Derived>
98 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
99 class view_interface : public view_base
102 constexpr _Derived& _M_derived() noexcept
104 static_assert(derived_from<_Derived, view_interface<_Derived>>);
105 static_assert(view<_Derived>);
106 return static_cast<_Derived&>(*this);
109 constexpr const _Derived& _M_derived() const noexcept
111 static_assert(derived_from<_Derived, view_interface<_Derived>>);
112 static_assert(view<_Derived>);
113 return static_cast<const _Derived&>(*this);
118 empty() requires forward_range<_Derived>
119 { return ranges::begin(_M_derived()) == ranges::end(_M_derived()); }
122 empty() const requires forward_range<const _Derived>
123 { return ranges::begin(_M_derived()) == ranges::end(_M_derived()); }
126 operator bool() requires requires { ranges::empty(_M_derived()); }
127 { return !ranges::empty(_M_derived()); }
130 operator bool() const requires requires { ranges::empty(_M_derived()); }
131 { return !ranges::empty(_M_derived()); }
134 data() requires contiguous_iterator<iterator_t<_Derived>>
135 { return to_address(ranges::begin(_M_derived())); }
139 requires range<const _Derived>
140 && contiguous_iterator<iterator_t<const _Derived>>
141 { return to_address(ranges::begin(_M_derived())); }
145 requires forward_range<_Derived>
146 && sized_sentinel_for<sentinel_t<_Derived>, iterator_t<_Derived>>
147 { return ranges::end(_M_derived()) - ranges::begin(_M_derived()); }
151 requires forward_range<const _Derived>
152 && sized_sentinel_for<sentinel_t<const _Derived>,
153 iterator_t<const _Derived>>
154 { return ranges::end(_M_derived()) - ranges::begin(_M_derived()); }
156 constexpr decltype(auto)
157 front() requires forward_range<_Derived>
159 __glibcxx_assert(!empty());
160 return *ranges::begin(_M_derived());
163 constexpr decltype(auto)
164 front() const requires forward_range<const _Derived>
166 __glibcxx_assert(!empty());
167 return *ranges::begin(_M_derived());
170 constexpr decltype(auto)
172 requires bidirectional_range<_Derived> && common_range<_Derived>
174 __glibcxx_assert(!empty());
175 return *ranges::prev(ranges::end(_M_derived()));
178 constexpr decltype(auto)
180 requires bidirectional_range<const _Derived>
181 && common_range<const _Derived>
183 __glibcxx_assert(!empty());
184 return *ranges::prev(ranges::end(_M_derived()));
187 template<random_access_range _Range = _Derived>
188 constexpr decltype(auto)
189 operator[](range_difference_t<_Range> __n)
190 { return ranges::begin(_M_derived())[__n]; }
192 template<random_access_range _Range = const _Derived>
193 constexpr decltype(auto)
194 operator[](range_difference_t<_Range> __n) const
195 { return ranges::begin(_M_derived())[__n]; }
200 template<class _From, class _To>
201 concept __convertible_to_non_slicing = convertible_to<_From, _To>
202 && !(is_pointer_v<decay_t<_From>> && is_pointer_v<decay_t<_To>>
203 && __not_same_as<remove_pointer_t<decay_t<_From>>,
204 remove_pointer_t<decay_t<_To>>>);
206 template<typename _Tp>
208 = !is_reference_v<_Tp> && requires(_Tp __t)
210 typename tuple_size<_Tp>::type;
211 requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
212 typename tuple_element_t<0, remove_const_t<_Tp>>;
213 typename tuple_element_t<1, remove_const_t<_Tp>>;
214 { get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
215 { get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
218 template<typename _Tp, typename _Up, typename _Vp>
219 concept __pair_like_convertible_from
220 = !range<_Tp> && __pair_like<_Tp>
221 && constructible_from<_Tp, _Up, _Vp>
222 && __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>>
223 && convertible_to<_Vp, tuple_element_t<1, _Tp>>;
225 } // namespace __detail
227 enum class subrange_kind : bool { unsized, sized };
229 template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It,
230 subrange_kind _Kind = sized_sentinel_for<_Sent, _It>
231 ? subrange_kind::sized : subrange_kind::unsized>
232 requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>)
233 class subrange : public view_interface<subrange<_It, _Sent, _Kind>>
236 // XXX: gcc complains when using constexpr here
237 static const bool _S_store_size
238 = _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _It>;
240 _It _M_begin = _It();
241 _Sent _M_end = _Sent();
243 template<typename, bool = _S_store_size>
247 template<typename _Tp>
248 struct _Size<_Tp, true>
249 { __detail::__make_unsigned_like_t<_Tp> _M_size; };
251 [[no_unique_address]] _Size<iter_difference_t<_It>> _M_size = {};
254 subrange() = default;
257 subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s)
258 requires (!_S_store_size)
259 : _M_begin(std::move(__i)), _M_end(__s)
263 subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s,
264 __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
265 requires (_Kind == subrange_kind::sized)
266 : _M_begin(std::move(__i)), _M_end(__s)
268 using __detail::__to_unsigned_like;
269 __glibcxx_assert(__n == __to_unsigned_like(ranges::distance(__i, __s)));
270 if constexpr (_S_store_size)
271 _M_size._M_size = __n;
274 template<__detail::__not_same_as<subrange> _Rng>
275 requires borrowed_range<_Rng>
276 && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
277 && convertible_to<sentinel_t<_Rng>, _Sent>
279 subrange(_Rng&& __r) requires _S_store_size && sized_range<_Rng>
280 : subrange(__r, ranges::size(__r))
283 template<__detail::__not_same_as<subrange> _Rng>
284 requires borrowed_range<_Rng>
285 && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
286 && convertible_to<sentinel_t<_Rng>, _Sent>
288 subrange(_Rng&& __r) requires (!_S_store_size)
289 : subrange{ranges::begin(__r), ranges::end(__r)}
292 template<borrowed_range _Rng>
293 requires __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
294 && convertible_to<sentinel_t<_Rng>, _Sent>
297 __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
298 requires (_Kind == subrange_kind::sized)
299 : subrange{ranges::begin(__r), ranges::end(__r), __n}
302 template<__detail::__not_same_as<subrange> _PairLike>
303 requires __detail::__pair_like_convertible_from<_PairLike, const _It&,
306 operator _PairLike() const
307 { return _PairLike(_M_begin, _M_end); }
310 begin() const requires copyable<_It>
313 [[nodiscard]] constexpr _It
314 begin() requires (!copyable<_It>)
315 { return std::move(_M_begin); }
317 constexpr _Sent end() const { return _M_end; }
319 constexpr bool empty() const { return _M_begin == _M_end; }
321 constexpr __detail::__make_unsigned_like_t<iter_difference_t<_It>>
322 size() const requires (_Kind == subrange_kind::sized)
324 if constexpr (_S_store_size)
325 return _M_size._M_size;
327 return __detail::__to_unsigned_like(_M_end - _M_begin);
330 [[nodiscard]] constexpr subrange
331 next(iter_difference_t<_It> __n = 1) const &
332 requires forward_iterator<_It>
339 [[nodiscard]] constexpr subrange
340 next(iter_difference_t<_It> __n = 1) &&
343 return std::move(*this);
346 [[nodiscard]] constexpr subrange
347 prev(iter_difference_t<_It> __n = 1) const
348 requires bidirectional_iterator<_It>
356 advance(iter_difference_t<_It> __n)
358 // _GLIBCXX_RESOLVE_LIB_DEFECTS
359 // 3433. subrange::advance(n) has UB when n < 0
360 if constexpr (bidirectional_iterator<_It>)
363 ranges::advance(_M_begin, __n);
364 if constexpr (_S_store_size)
365 _M_size._M_size += __detail::__to_unsigned_like(-__n);
369 __glibcxx_assert(__n >= 0);
370 auto __d = __n - ranges::advance(_M_begin, __n, _M_end);
371 if constexpr (_S_store_size)
372 _M_size._M_size -= __detail::__to_unsigned_like(__d);
377 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
378 subrange(_It, _Sent) -> subrange<_It, _Sent>;
380 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
382 __detail::__make_unsigned_like_t<iter_difference_t<_It>>)
383 -> subrange<_It, _Sent, subrange_kind::sized>;
385 template<borrowed_range _Rng>
387 -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>,
389 || sized_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>)
390 ? subrange_kind::sized : subrange_kind::unsized>;
392 template<borrowed_range _Rng>
394 __detail::__make_unsigned_like_t<range_difference_t<_Rng>>)
395 -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, subrange_kind::sized>;
397 template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
400 get(const subrange<_It, _Sent, _Kind>& __r)
402 if constexpr (_Num == 0)
408 template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
411 get(subrange<_It, _Sent, _Kind>&& __r)
413 if constexpr (_Num == 0)
419 template<input_or_output_iterator _It, sentinel_for<_It> _Sent,
421 inline constexpr bool
422 enable_borrowed_range<subrange<_It, _Sent, _Kind>> = true;
424 } // namespace ranges
430 /// Type returned by algorithms instead of a dangling iterator or subrange.
433 constexpr dangling() noexcept = default;
434 template<typename... _Args>
435 constexpr dangling(_Args&&...) noexcept { }
438 template<range _Range>
439 using borrowed_iterator_t = conditional_t<borrowed_range<_Range>,
443 template<range _Range>
444 using borrowed_subrange_t = conditional_t<borrowed_range<_Range>,
445 subrange<iterator_t<_Range>>,
448 template<typename _Tp> requires is_object_v<_Tp>
450 : public view_interface<empty_view<_Tp>>
453 static constexpr _Tp* begin() noexcept { return nullptr; }
454 static constexpr _Tp* end() noexcept { return nullptr; }
455 static constexpr _Tp* data() noexcept { return nullptr; }
456 static constexpr size_t size() noexcept { return 0; }
457 static constexpr bool empty() noexcept { return true; }
460 template<typename _Tp>
461 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
465 template<copy_constructible _Tp> requires is_object_v<_Tp>
466 struct __box : std::optional<_Tp>
468 using std::optional<_Tp>::optional;
472 noexcept(is_nothrow_default_constructible_v<_Tp>)
473 requires default_initializable<_Tp>
474 : std::optional<_Tp>{std::in_place}
477 __box(const __box&) = default;
478 __box(__box&&) = default;
480 using std::optional<_Tp>::operator=;
482 // _GLIBCXX_RESOLVE_LIB_DEFECTS
483 // 3477. Simplify constraints for semiregular-box
485 operator=(const __box& __that)
486 noexcept(is_nothrow_copy_constructible_v<_Tp>)
487 requires (!copyable<_Tp>)
490 this->emplace(*__that);
497 operator=(__box&& __that)
498 noexcept(is_nothrow_move_constructible_v<_Tp>)
499 requires (!movable<_Tp>)
502 this->emplace(std::move(*__that));
509 } // namespace __detail
511 /// A view that contains exactly one element.
512 template<copy_constructible _Tp> requires is_object_v<_Tp>
513 class single_view : public view_interface<single_view<_Tp>>
516 single_view() = default;
519 single_view(const _Tp& __t)
524 single_view(_Tp&& __t)
525 : _M_value(std::move(__t))
528 // _GLIBCXX_RESOLVE_LIB_DEFECTS
529 // 3428. single_view's in place constructor should be explicit
530 template<typename... _Args>
531 requires constructible_from<_Tp, _Args...>
533 single_view(in_place_t, _Args&&... __args)
534 : _M_value{in_place, std::forward<_Args>(__args)...}
542 begin() const noexcept
547 { return data() + 1; }
551 { return data() + 1; }
553 static constexpr size_t
559 { return _M_value.operator->(); }
562 data() const noexcept
563 { return _M_value.operator->(); }
566 __detail::__box<_Tp> _M_value;
571 template<typename _Wp>
572 constexpr auto __to_signed_like(_Wp __w) noexcept
574 if constexpr (!integral<_Wp>)
575 return iter_difference_t<_Wp>();
576 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
577 return iter_difference_t<_Wp>(__w);
578 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
579 return ptrdiff_t(__w);
580 else if constexpr (sizeof(long long) > sizeof(_Wp))
581 return (long long)(__w);
582 #ifdef __SIZEOF_INT128__
583 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
584 return __int128(__w);
587 return __max_diff_type(__w);
590 template<typename _Wp>
591 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
593 template<typename _It>
594 concept __decrementable = incrementable<_It>
597 { --__i } -> same_as<_It&>;
598 { __i-- } -> same_as<_It>;
601 template<typename _It>
602 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
603 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
605 { __i += __n } -> same_as<_It&>;
606 { __i -= __n } -> same_as<_It&>;
610 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
613 template<typename _Winc>
614 struct __iota_view_iter_cat
617 template<incrementable _Winc>
618 struct __iota_view_iter_cat<_Winc>
619 { using iterator_category = input_iterator_tag; };
620 } // namespace __detail
622 template<weakly_incrementable _Winc,
623 semiregular _Bound = unreachable_sentinel_t>
624 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
625 && semiregular<_Winc>
626 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
631 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
637 using namespace __detail;
638 if constexpr (__advanceable<_Winc>)
639 return random_access_iterator_tag{};
640 else if constexpr (__decrementable<_Winc>)
641 return bidirectional_iterator_tag{};
642 else if constexpr (incrementable<_Winc>)
643 return forward_iterator_tag{};
645 return input_iterator_tag{};
649 using iterator_concept = decltype(_S_iter_concept());
650 // iterator_category defined in __iota_view_iter_cat
651 using value_type = _Winc;
652 using difference_type = __detail::__iota_diff_t<_Winc>;
654 _Iterator() = default;
657 _Iterator(_Winc __value)
658 : _M_value(__value) { }
661 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
676 operator++(int) requires incrementable<_Winc>
684 operator--() requires __detail::__decrementable<_Winc>
691 operator--(int) requires __detail::__decrementable<_Winc>
699 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
701 using __detail::__is_integer_like;
702 using __detail::__is_signed_integer_like;
703 if constexpr (__is_integer_like<_Winc>
704 && !__is_signed_integer_like<_Winc>)
706 if (__n >= difference_type(0))
707 _M_value += static_cast<_Winc>(__n);
709 _M_value -= static_cast<_Winc>(-__n);
717 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
719 using __detail::__is_integer_like;
720 using __detail::__is_signed_integer_like;
721 if constexpr (__is_integer_like<_Winc>
722 && !__is_signed_integer_like<_Winc>)
724 if (__n >= difference_type(0))
725 _M_value -= static_cast<_Winc>(__n);
727 _M_value += static_cast<_Winc>(-__n);
735 operator[](difference_type __n) const
736 requires __detail::__advanceable<_Winc>
737 { return _Winc(_M_value + __n); }
739 friend constexpr bool
740 operator==(const _Iterator& __x, const _Iterator& __y)
741 requires equality_comparable<_Winc>
742 { return __x._M_value == __y._M_value; }
744 friend constexpr bool
745 operator<(const _Iterator& __x, const _Iterator& __y)
746 requires totally_ordered<_Winc>
747 { return __x._M_value < __y._M_value; }
749 friend constexpr bool
750 operator>(const _Iterator& __x, const _Iterator& __y)
751 requires totally_ordered<_Winc>
752 { return __y < __x; }
754 friend constexpr bool
755 operator<=(const _Iterator& __x, const _Iterator& __y)
756 requires totally_ordered<_Winc>
757 { return !(__y < __x); }
759 friend constexpr bool
760 operator>=(const _Iterator& __x, const _Iterator& __y)
761 requires totally_ordered<_Winc>
762 { return !(__x < __y); }
764 #ifdef __cpp_lib_three_way_comparison
765 friend constexpr auto
766 operator<=>(const _Iterator& __x, const _Iterator& __y)
767 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
768 { return __x._M_value <=> __y._M_value; }
771 friend constexpr _Iterator
772 operator+(_Iterator __i, difference_type __n)
773 requires __detail::__advanceable<_Winc>
774 { return __i += __n; }
776 friend constexpr _Iterator
777 operator+(difference_type __n, _Iterator __i)
778 requires __detail::__advanceable<_Winc>
779 { return __i += __n; }
781 friend constexpr _Iterator
782 operator-(_Iterator __i, difference_type __n)
783 requires __detail::__advanceable<_Winc>
784 { return __i -= __n; }
786 friend constexpr difference_type
787 operator-(const _Iterator& __x, const _Iterator& __y)
788 requires __detail::__advanceable<_Winc>
790 using __detail::__is_integer_like;
791 using __detail::__is_signed_integer_like;
792 using _Dt = difference_type;
793 if constexpr (__is_integer_like<_Winc>)
795 if constexpr (__is_signed_integer_like<_Winc>)
796 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
798 return (__y._M_value > __x._M_value)
799 ? _Dt(-_Dt(__y._M_value - __x._M_value))
800 : _Dt(__x._M_value - __y._M_value);
803 return __x._M_value - __y._M_value;
807 _Winc _M_value = _Winc();
816 _M_equal(const _Iterator& __x) const
817 { return __x._M_value == _M_bound; }
820 _M_distance_from(const _Iterator& __x) const
821 { return _M_bound - __x._M_value; }
823 _Bound _M_bound = _Bound();
826 _Sentinel() = default;
829 _Sentinel(_Bound __bound)
830 : _M_bound(__bound) { }
832 friend constexpr bool
833 operator==(const _Iterator& __x, const _Sentinel& __y)
834 { return __y._M_equal(__x); }
836 friend constexpr iter_difference_t<_Winc>
837 operator-(const _Iterator& __x, const _Sentinel& __y)
838 requires sized_sentinel_for<_Bound, _Winc>
839 { return -__y._M_distance_from(__x); }
841 friend constexpr iter_difference_t<_Winc>
842 operator-(const _Sentinel& __x, const _Iterator& __y)
843 requires sized_sentinel_for<_Bound, _Winc>
844 { return __x._M_distance_from(__y); }
847 _Winc _M_value = _Winc();
848 _Bound _M_bound = _Bound();
851 iota_view() = default;
854 iota_view(_Winc __value)
859 iota_view(type_identity_t<_Winc> __value,
860 type_identity_t<_Bound> __bound)
861 : _M_value(__value), _M_bound(__bound)
863 if constexpr (totally_ordered_with<_Winc, _Bound>)
865 __glibcxx_assert( bool(__value <= __bound) );
870 begin() const { return _Iterator{_M_value}; }
875 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
876 return unreachable_sentinel;
878 return _Sentinel{_M_bound};
882 end() const requires same_as<_Winc, _Bound>
883 { return _Iterator{_M_bound}; }
887 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
888 || (integral<_Winc> && integral<_Bound>)
889 || sized_sentinel_for<_Bound, _Winc>
891 using __detail::__is_integer_like;
892 using __detail::__to_unsigned_like;
893 if constexpr (integral<_Winc> && integral<_Bound>)
895 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
896 return _Up(_M_bound) - _Up(_M_value);
898 else if constexpr (__is_integer_like<_Winc>)
899 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
901 return __to_unsigned_like(_M_bound - _M_value);
905 template<typename _Winc, typename _Bound>
906 requires (!__detail::__is_integer_like<_Winc>
907 || !__detail::__is_integer_like<_Bound>
908 || (__detail::__is_signed_integer_like<_Winc>
909 == __detail::__is_signed_integer_like<_Bound>))
910 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
912 template<weakly_incrementable _Winc, semiregular _Bound>
913 inline constexpr bool
914 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
918 template<typename _Tp>
919 inline constexpr empty_view<_Tp> empty{};
923 template<typename _Tp>
925 operator()(_Tp&& __e) const
926 { return single_view{std::forward<_Tp>(__e)}; }
929 inline constexpr _Single single{};
933 template<typename _Tp>
935 operator()(_Tp&& __e) const
936 { return iota_view{std::forward<_Tp>(__e)}; }
938 template<typename _Tp, typename _Up>
940 operator()(_Tp&& __e, _Up&& __f) const
941 { return iota_view{std::forward<_Tp>(__e), std::forward<_Up>(__f)}; }
944 inline constexpr _Iota iota{};
949 template<typename _Val, typename _CharT, typename _Traits>
950 concept __stream_extractable
951 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
952 } // namespace __detail
954 template<movable _Val, typename _CharT, typename _Traits>
955 requires default_initializable<_Val>
956 && __detail::__stream_extractable<_Val, _CharT, _Traits>
957 class basic_istream_view
958 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
961 basic_istream_view() = default;
964 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
965 : _M_stream(std::__addressof(__stream))
971 if (_M_stream != nullptr)
972 *_M_stream >> _M_object;
973 return _Iterator{this};
976 constexpr default_sentinel_t
978 { return default_sentinel; }
981 basic_istream<_CharT, _Traits>* _M_stream = nullptr;
982 _Val _M_object = _Val();
987 using iterator_concept = input_iterator_tag;
988 using difference_type = ptrdiff_t;
989 using value_type = _Val;
991 _Iterator() = default;
994 _Iterator(basic_istream_view* __parent) noexcept
995 : _M_parent(__parent)
998 _Iterator(const _Iterator&) = delete;
999 _Iterator(_Iterator&&) = default;
1000 _Iterator& operator=(const _Iterator&) = delete;
1001 _Iterator& operator=(_Iterator&&) = default;
1006 __glibcxx_assert(_M_parent->_M_stream != nullptr);
1007 *_M_parent->_M_stream >> _M_parent->_M_object;
1018 __glibcxx_assert(_M_parent->_M_stream != nullptr);
1019 return _M_parent->_M_object;
1023 operator==(const _Iterator& __x, default_sentinel_t)
1024 { return __x._M_at_end(); }
1027 basic_istream_view* _M_parent = nullptr;
1031 { return _M_parent == nullptr || !*_M_parent->_M_stream; }
1037 template<typename _Val, typename _CharT, typename _Traits>
1038 basic_istream_view<_Val, _CharT, _Traits>
1039 istream_view(basic_istream<_CharT, _Traits>& __s)
1040 { return basic_istream_view<_Val, _CharT, _Traits>{__s}; }
1046 // Alias for a type that is conditionally present
1047 // (and is an empty type otherwise).
1048 // Data members using this alias should use [[no_unique_address]] so that
1049 // they take no space when not needed.
1050 template<bool _Present, typename _Tp>
1051 using __maybe_present_t = conditional_t<_Present, _Tp, _Empty>;
1053 // Alias for a type that is conditionally const.
1054 template<bool _Const, typename _Tp>
1055 using __maybe_const_t = conditional_t<_Const, const _Tp, _Tp>;
1057 } // namespace __detail
1063 template<typename _Tp>
1064 inline constexpr auto
1065 __maybe_refwrap(_Tp& __arg)
1066 { return reference_wrapper<_Tp>{__arg}; }
1068 template<typename _Tp>
1069 inline constexpr auto
1070 __maybe_refwrap(const _Tp& __arg)
1071 { return reference_wrapper<const _Tp>{__arg}; }
1073 template<typename _Tp>
1074 inline constexpr decltype(auto)
1075 __maybe_refwrap(_Tp&& __arg)
1076 { return std::forward<_Tp>(__arg); }
1078 template<typename _Callable>
1079 struct _RangeAdaptorClosure;
1081 template<typename _Callable>
1082 struct _RangeAdaptor
1085 [[no_unique_address]]
1086 __detail::__maybe_present_t<!is_default_constructible_v<_Callable>,
1087 _Callable> _M_callable;
1091 _RangeAdaptor(const _Callable& = {})
1092 requires is_default_constructible_v<_Callable>
1096 _RangeAdaptor(_Callable __callable)
1097 requires (!is_default_constructible_v<_Callable>)
1098 : _M_callable(std::move(__callable))
1101 template<typename... _Args>
1102 requires (sizeof...(_Args) >= 1)
1104 operator()(_Args&&... __args) const
1106 // [range.adaptor.object]: If a range adaptor object accepts more
1107 // than one argument, then the following expressions are equivalent:
1109 // (1) adaptor(range, args...)
1110 // (2) adaptor(args...)(range)
1111 // (3) range | adaptor(args...)
1113 // In this case, adaptor(args...) is a range adaptor closure object.
1115 // We handle (1) and (2) here, and (3) is just a special case of a
1116 // more general case already handled by _RangeAdaptorClosure.
1117 if constexpr (is_invocable_v<_Callable, _Args...>)
1119 static_assert(sizeof...(_Args) != 1,
1120 "a _RangeAdaptor that accepts only one argument "
1121 "should be defined as a _RangeAdaptorClosure");
1122 // Here we handle adaptor(range, args...) -- just forward all
1123 // arguments to the underlying adaptor routine.
1124 return _Callable{}(std::forward<_Args>(__args)...);
1128 // Here we handle adaptor(args...)(range).
1129 // Given args..., we return a _RangeAdaptorClosure that takes a
1130 // range argument, such that (2) is equivalent to (1).
1132 // We need to be careful about how we capture args... in this
1133 // closure. By using __maybe_refwrap, we capture lvalue
1134 // references by reference (through a reference_wrapper) and
1135 // otherwise capture by value.
1137 = [...__args(__maybe_refwrap(std::forward<_Args>(__args)))]
1138 <typename _Range> (_Range&& __r) {
1139 // This static_cast has two purposes: it forwards a
1140 // reference_wrapper<T> capture as a T&, and otherwise
1141 // forwards the captured argument as an rvalue.
1142 return _Callable{}(std::forward<_Range>(__r),
1143 (static_cast<unwrap_reference_t
1144 <remove_const_t<decltype(__args)>>>
1147 using _ClosureType = decltype(__closure);
1148 return _RangeAdaptorClosure<_ClosureType>(std::move(__closure));
1153 template<typename _Callable>
1154 _RangeAdaptor(_Callable) -> _RangeAdaptor<_Callable>;
1156 template<typename _Callable>
1157 struct _RangeAdaptorClosure : public _RangeAdaptor<_Callable>
1159 using _RangeAdaptor<_Callable>::_RangeAdaptor;
1161 template<viewable_range _Range>
1162 requires requires { declval<_Callable>()(declval<_Range>()); }
1164 operator()(_Range&& __r) const
1166 if constexpr (is_default_constructible_v<_Callable>)
1167 return _Callable{}(std::forward<_Range>(__r));
1169 return this->_M_callable(std::forward<_Range>(__r));
1172 template<viewable_range _Range>
1173 requires requires { declval<_Callable>()(declval<_Range>()); }
1174 friend constexpr auto
1175 operator|(_Range&& __r, const _RangeAdaptorClosure& __o)
1176 { return __o(std::forward<_Range>(__r)); }
1178 template<typename _Tp>
1179 friend constexpr auto
1180 operator|(const _RangeAdaptorClosure<_Tp>& __x,
1181 const _RangeAdaptorClosure& __y)
1183 if constexpr (is_default_constructible_v<_Tp>
1184 && is_default_constructible_v<_Callable>)
1186 auto __closure = [] <typename _Up> (_Up&& __e) {
1187 return std::forward<_Up>(__e) | decltype(__x){} | decltype(__y){};
1189 return _RangeAdaptorClosure<decltype(__closure)>(__closure);
1191 else if constexpr (is_default_constructible_v<_Tp>
1192 && !is_default_constructible_v<_Callable>)
1194 auto __closure = [__y] <typename _Up> (_Up&& __e) {
1195 return std::forward<_Up>(__e) | decltype(__x){} | __y;
1197 return _RangeAdaptorClosure<decltype(__closure)>(__closure);
1199 else if constexpr (!is_default_constructible_v<_Tp>
1200 && is_default_constructible_v<_Callable>)
1202 auto __closure = [__x] <typename _Up> (_Up&& __e) {
1203 return std::forward<_Up>(__e) | __x | decltype(__y){};
1205 return _RangeAdaptorClosure<decltype(__closure)>(__closure);
1209 auto __closure = [__x, __y] <typename _Up> (_Up&& __e) {
1210 return std::forward<_Up>(__e) | __x | __y;
1212 return _RangeAdaptorClosure<decltype(__closure)>(__closure);
1217 template<typename _Callable>
1218 _RangeAdaptorClosure(_Callable) -> _RangeAdaptorClosure<_Callable>;
1219 } // namespace __adaptor
1220 } // namespace views
1222 template<range _Range> requires is_object_v<_Range>
1223 class ref_view : public view_interface<ref_view<_Range>>
1226 _Range* _M_r = nullptr;
1228 static void _S_fun(_Range&); // not defined
1229 static void _S_fun(_Range&&) = delete;
1233 ref_view() noexcept = default;
1235 template<__detail::__not_same_as<ref_view> _Tp>
1236 requires convertible_to<_Tp, _Range&>
1237 && requires { _S_fun(declval<_Tp>()); }
1240 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1247 constexpr iterator_t<_Range>
1249 { return ranges::begin(*_M_r); }
1251 constexpr sentinel_t<_Range>
1253 { return ranges::end(*_M_r); }
1256 empty() const requires requires { ranges::empty(*_M_r); }
1257 { return ranges::empty(*_M_r); }
1260 size() const requires sized_range<_Range>
1261 { return ranges::size(*_M_r); }
1264 data() const requires contiguous_range<_Range>
1265 { return ranges::data(*_M_r); }
1268 template<typename _Range>
1269 ref_view(_Range&) -> ref_view<_Range>;
1271 template<typename _Tp>
1272 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1276 inline constexpr __adaptor::_RangeAdaptorClosure all
1277 = [] <viewable_range _Range> (_Range&& __r)
1279 if constexpr (view<decay_t<_Range>>)
1280 return std::forward<_Range>(__r);
1281 else if constexpr (requires { ref_view{std::forward<_Range>(__r)}; })
1282 return ref_view{std::forward<_Range>(__r)};
1284 return subrange{std::forward<_Range>(__r)};
1287 template<viewable_range _Range>
1288 using all_t = decltype(all(std::declval<_Range>()));
1290 } // namespace views
1292 // The following simple algos are transcribed from ranges_algo.h to avoid
1293 // having to include that entire header.
1296 template<typename _Iter, typename _Sent, typename _Tp>
1298 find(_Iter __first, _Sent __last, const _Tp& __value)
1300 while (__first != __last
1301 && !(bool)(*__first == __value))
1306 template<typename _Iter, typename _Sent, typename _Pred>
1308 find_if(_Iter __first, _Sent __last, _Pred __pred)
1310 while (__first != __last
1311 && !(bool)std::__invoke(__pred, *__first))
1316 template<typename _Iter, typename _Sent, typename _Pred>
1318 find_if_not(_Iter __first, _Sent __last, _Pred __pred)
1320 while (__first != __last
1321 && (bool)std::__invoke(__pred, *__first))
1326 template<typename _Iter1, typename _Sent1, typename _Iter2, typename _Sent2>
1327 constexpr pair<_Iter1, _Iter2>
1328 mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2)
1330 while (__first1 != __last1 && __first2 != __last2
1331 && (bool)ranges::equal_to{}(*__first1, *__first2))
1336 return { std::move(__first1), std::move(__first2) };
1338 } // namespace __detail
1342 template<range _Range>
1343 struct _CachedPosition
1346 _M_has_value() const
1349 constexpr iterator_t<_Range>
1350 _M_get(const _Range&) const
1352 __glibcxx_assert(false);
1357 _M_set(const _Range&, const iterator_t<_Range>&) const
1361 template<forward_range _Range>
1362 struct _CachedPosition<_Range>
1365 iterator_t<_Range> _M_iter{};
1369 _M_has_value() const
1370 { return _M_iter != iterator_t<_Range>{}; }
1372 constexpr iterator_t<_Range>
1373 _M_get(const _Range&) const
1375 __glibcxx_assert(_M_has_value());
1380 _M_set(const _Range&, const iterator_t<_Range>& __it)
1382 __glibcxx_assert(!_M_has_value());
1387 template<random_access_range _Range>
1388 requires (sizeof(range_difference_t<_Range>)
1389 <= sizeof(iterator_t<_Range>))
1390 struct _CachedPosition<_Range>
1393 range_difference_t<_Range> _M_offset = -1;
1397 _M_has_value() const
1398 { return _M_offset >= 0; }
1400 constexpr iterator_t<_Range>
1401 _M_get(_Range& __r) const
1403 __glibcxx_assert(_M_has_value());
1404 return ranges::begin(__r) + _M_offset;
1408 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1410 __glibcxx_assert(!_M_has_value());
1411 _M_offset = __it - ranges::begin(__r);
1414 } // namespace __detail
1418 template<typename _Base>
1419 struct __filter_view_iter_cat
1422 template<forward_range _Base>
1423 struct __filter_view_iter_cat<_Base>
1429 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1430 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1431 return bidirectional_iterator_tag{};
1432 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1433 return forward_iterator_tag{};
1438 using iterator_category = decltype(_S_iter_cat());
1440 } // namespace __detail
1442 template<input_range _Vp,
1443 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1444 requires view<_Vp> && is_object_v<_Pred>
1445 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1450 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1453 static constexpr auto
1456 if constexpr (bidirectional_range<_Vp>)
1457 return bidirectional_iterator_tag{};
1458 else if constexpr (forward_range<_Vp>)
1459 return forward_iterator_tag{};
1461 return input_iterator_tag{};
1466 using _Vp_iter = iterator_t<_Vp>;
1468 _Vp_iter _M_current = _Vp_iter();
1469 filter_view* _M_parent = nullptr;
1472 using iterator_concept = decltype(_S_iter_concept());
1473 // iterator_category defined in __filter_view_iter_cat
1474 using value_type = range_value_t<_Vp>;
1475 using difference_type = range_difference_t<_Vp>;
1477 _Iterator() = default;
1480 _Iterator(filter_view* __parent, _Vp_iter __current)
1481 : _M_current(std::move(__current)),
1485 constexpr const _Vp_iter&
1486 base() const & noexcept
1487 { return _M_current; }
1491 { return std::move(_M_current); }
1493 constexpr range_reference_t<_Vp>
1495 { return *_M_current; }
1499 requires __detail::__has_arrow<_Vp_iter>
1500 && copyable<_Vp_iter>
1501 { return _M_current; }
1503 constexpr _Iterator&
1506 _M_current = __detail::find_if(std::move(++_M_current),
1507 ranges::end(_M_parent->_M_base),
1508 std::ref(*_M_parent->_M_pred));
1517 operator++(int) requires forward_range<_Vp>
1524 constexpr _Iterator&
1525 operator--() requires bidirectional_range<_Vp>
1529 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1534 operator--(int) requires bidirectional_range<_Vp>
1541 friend constexpr bool
1542 operator==(const _Iterator& __x, const _Iterator& __y)
1543 requires equality_comparable<_Vp_iter>
1544 { return __x._M_current == __y._M_current; }
1546 friend constexpr range_rvalue_reference_t<_Vp>
1547 iter_move(const _Iterator& __i)
1548 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1549 { return ranges::iter_move(__i._M_current); }
1551 friend constexpr void
1552 iter_swap(const _Iterator& __x, const _Iterator& __y)
1553 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1554 requires indirectly_swappable<_Vp_iter>
1555 { ranges::iter_swap(__x._M_current, __y._M_current); }
1561 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1564 __equal(const _Iterator& __i) const
1565 { return __i._M_current == _M_end; }
1568 _Sentinel() = default;
1571 _Sentinel(filter_view* __parent)
1572 : _M_end(ranges::end(__parent->_M_base))
1575 constexpr sentinel_t<_Vp>
1579 friend constexpr bool
1580 operator==(const _Iterator& __x, const _Sentinel& __y)
1581 { return __y.__equal(__x); }
1584 _Vp _M_base = _Vp();
1585 __detail::__box<_Pred> _M_pred;
1586 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1589 filter_view() = default;
1592 filter_view(_Vp __base, _Pred __pred)
1593 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1597 base() const& requires copy_constructible<_Vp>
1602 { return std::move(_M_base); }
1604 constexpr const _Pred&
1606 { return *_M_pred; }
1611 if (_M_cached_begin._M_has_value())
1612 return {this, _M_cached_begin._M_get(_M_base)};
1614 __glibcxx_assert(_M_pred.has_value());
1615 auto __it = __detail::find_if(ranges::begin(_M_base),
1616 ranges::end(_M_base),
1617 std::ref(*_M_pred));
1618 _M_cached_begin._M_set(_M_base, __it);
1619 return {this, std::move(__it)};
1625 if constexpr (common_range<_Vp>)
1626 return _Iterator{this, ranges::end(_M_base)};
1628 return _Sentinel{this};
1632 template<typename _Range, typename _Pred>
1633 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1637 inline constexpr __adaptor::_RangeAdaptor filter
1638 = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p)
1640 return filter_view{std::forward<_Range>(__r), std::forward<_Pred>(__p)};
1642 } // namespace views
1644 template<input_range _Vp, copy_constructible _Fp>
1645 requires view<_Vp> && is_object_v<_Fp>
1646 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1647 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1648 range_reference_t<_Vp>>>
1649 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1652 template<bool _Const>
1653 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1655 template<bool _Const>
1659 template<bool _Const>
1660 requires forward_range<_Base<_Const>>
1661 struct __iter_cat<_Const>
1667 using _Base = transform_view::_Base<_Const>;
1668 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1669 if constexpr (is_lvalue_reference_v<_Res>)
1672 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1673 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1674 return random_access_iterator_tag{};
1679 return input_iterator_tag{};
1682 using iterator_category = decltype(_S_iter_cat());
1685 template<bool _Const>
1688 template<bool _Const>
1689 struct _Iterator : __iter_cat<_Const>
1692 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1693 using _Base = transform_view::_Base<_Const>;
1698 if constexpr (random_access_range<_Vp>)
1699 return random_access_iterator_tag{};
1700 else if constexpr (bidirectional_range<_Vp>)
1701 return bidirectional_iterator_tag{};
1702 else if constexpr (forward_range<_Vp>)
1703 return forward_iterator_tag{};
1705 return input_iterator_tag{};
1708 using _Base_iter = iterator_t<_Base>;
1710 _Base_iter _M_current = _Base_iter();
1711 _Parent* _M_parent = nullptr;
1714 using iterator_concept = decltype(_S_iter_concept());
1715 // iterator_category defined in __transform_view_iter_cat
1717 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1718 using difference_type = range_difference_t<_Base>;
1720 _Iterator() = default;
1723 _Iterator(_Parent* __parent, _Base_iter __current)
1724 : _M_current(std::move(__current)),
1729 _Iterator(_Iterator<!_Const> __i)
1731 && convertible_to<iterator_t<_Vp>, _Base_iter>
1732 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1735 constexpr const _Base_iter&
1736 base() const & noexcept
1737 { return _M_current; }
1739 constexpr _Base_iter
1741 { return std::move(_M_current); }
1743 constexpr decltype(auto)
1745 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1746 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1748 constexpr _Iterator&
1760 operator++(int) requires forward_range<_Base>
1767 constexpr _Iterator&
1768 operator--() requires bidirectional_range<_Base>
1775 operator--(int) requires bidirectional_range<_Base>
1782 constexpr _Iterator&
1783 operator+=(difference_type __n) requires random_access_range<_Base>
1789 constexpr _Iterator&
1790 operator-=(difference_type __n) requires random_access_range<_Base>
1796 constexpr decltype(auto)
1797 operator[](difference_type __n) const
1798 requires random_access_range<_Base>
1799 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1801 friend constexpr bool
1802 operator==(const _Iterator& __x, const _Iterator& __y)
1803 requires equality_comparable<_Base_iter>
1804 { return __x._M_current == __y._M_current; }
1806 friend constexpr bool
1807 operator<(const _Iterator& __x, const _Iterator& __y)
1808 requires random_access_range<_Base>
1809 { return __x._M_current < __y._M_current; }
1811 friend constexpr bool
1812 operator>(const _Iterator& __x, const _Iterator& __y)
1813 requires random_access_range<_Base>
1814 { return __y < __x; }
1816 friend constexpr bool
1817 operator<=(const _Iterator& __x, const _Iterator& __y)
1818 requires random_access_range<_Base>
1819 { return !(__y < __x); }
1821 friend constexpr bool
1822 operator>=(const _Iterator& __x, const _Iterator& __y)
1823 requires random_access_range<_Base>
1824 { return !(__x < __y); }
1826 #ifdef __cpp_lib_three_way_comparison
1827 friend constexpr auto
1828 operator<=>(const _Iterator& __x, const _Iterator& __y)
1829 requires random_access_range<_Base>
1830 && three_way_comparable<_Base_iter>
1831 { return __x._M_current <=> __y._M_current; }
1834 friend constexpr _Iterator
1835 operator+(_Iterator __i, difference_type __n)
1836 requires random_access_range<_Base>
1837 { return {__i._M_parent, __i._M_current + __n}; }
1839 friend constexpr _Iterator
1840 operator+(difference_type __n, _Iterator __i)
1841 requires random_access_range<_Base>
1842 { return {__i._M_parent, __i._M_current + __n}; }
1844 friend constexpr _Iterator
1845 operator-(_Iterator __i, difference_type __n)
1846 requires random_access_range<_Base>
1847 { return {__i._M_parent, __i._M_current - __n}; }
1849 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1850 // 3483. transform_view::iterator's difference is overconstrained
1851 friend constexpr difference_type
1852 operator-(const _Iterator& __x, const _Iterator& __y)
1853 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
1854 { return __x._M_current - __y._M_current; }
1856 friend constexpr decltype(auto)
1857 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
1859 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
1860 return std::move(*__i);
1865 friend _Iterator<!_Const>;
1866 template<bool> friend struct _Sentinel;
1869 template<bool _Const>
1873 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1874 using _Base = transform_view::_Base<_Const>;
1876 template<bool _Const2>
1878 __distance_from(const _Iterator<_Const2>& __i) const
1879 { return _M_end - __i._M_current; }
1881 template<bool _Const2>
1883 __equal(const _Iterator<_Const2>& __i) const
1884 { return __i._M_current == _M_end; }
1886 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1889 _Sentinel() = default;
1892 _Sentinel(sentinel_t<_Base> __end)
1897 _Sentinel(_Sentinel<!_Const> __i)
1899 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1900 : _M_end(std::move(__i._M_end))
1903 constexpr sentinel_t<_Base>
1907 template<bool _Const2>
1908 requires sentinel_for<sentinel_t<_Base>,
1909 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
1910 friend constexpr bool
1911 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1912 { return __y.__equal(__x); }
1914 template<bool _Const2,
1915 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1916 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1917 friend constexpr range_difference_t<_Base2>
1918 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1919 { return -__y.__distance_from(__x); }
1921 template<bool _Const2,
1922 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1923 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1924 friend constexpr range_difference_t<_Base2>
1925 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
1926 { return __y.__distance_from(__x); }
1928 friend _Sentinel<!_Const>;
1931 _Vp _M_base = _Vp();
1932 __detail::__box<_Fp> _M_fun;
1935 transform_view() = default;
1938 transform_view(_Vp __base, _Fp __fun)
1939 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
1943 base() const& requires copy_constructible<_Vp>
1944 { return _M_base ; }
1948 { return std::move(_M_base); }
1950 constexpr _Iterator<false>
1952 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
1954 constexpr _Iterator<true>
1956 requires range<const _Vp>
1957 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1958 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
1960 constexpr _Sentinel<false>
1962 { return _Sentinel<false>{ranges::end(_M_base)}; }
1964 constexpr _Iterator<false>
1965 end() requires common_range<_Vp>
1966 { return _Iterator<false>{this, ranges::end(_M_base)}; }
1968 constexpr _Sentinel<true>
1970 requires range<const _Vp>
1971 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1972 { return _Sentinel<true>{ranges::end(_M_base)}; }
1974 constexpr _Iterator<true>
1976 requires common_range<const _Vp>
1977 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1978 { return _Iterator<true>{this, ranges::end(_M_base)}; }
1981 size() requires sized_range<_Vp>
1982 { return ranges::size(_M_base); }
1985 size() const requires sized_range<const _Vp>
1986 { return ranges::size(_M_base); }
1989 template<typename _Range, typename _Fp>
1990 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
1994 inline constexpr __adaptor::_RangeAdaptor transform
1995 = [] <viewable_range _Range, typename _Fp> (_Range&& __r, _Fp&& __f)
1997 return transform_view{std::forward<_Range>(__r), std::forward<_Fp>(__f)};
1999 } // namespace views
2002 class take_view : public view_interface<take_view<_Vp>>
2005 template<bool _Const>
2006 using _CI = counted_iterator<
2007 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2009 template<bool _Const>
2013 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2014 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2017 _Sentinel() = default;
2020 _Sentinel(sentinel_t<_Base> __end)
2025 _Sentinel(_Sentinel<!_Const> __s)
2026 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2027 : _M_end(std::move(__s._M_end))
2030 constexpr sentinel_t<_Base>
2034 friend constexpr bool
2035 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2036 { return __y.count() == 0 || __y.base() == __x._M_end; }
2038 template<bool _OtherConst = !_Const,
2039 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2040 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2041 friend constexpr bool
2042 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2043 { return __y.count() == 0 || __y.base() == __x._M_end; }
2045 friend _Sentinel<!_Const>;
2048 _Vp _M_base = _Vp();
2049 range_difference_t<_Vp> _M_count = 0;
2052 take_view() = default;
2055 take_view(_Vp base, range_difference_t<_Vp> __count)
2056 : _M_base(std::move(base)), _M_count(std::move(__count))
2060 base() const& requires copy_constructible<_Vp>
2065 { return std::move(_M_base); }
2068 begin() requires (!__detail::__simple_view<_Vp>)
2070 if constexpr (sized_range<_Vp>)
2072 if constexpr (random_access_range<_Vp>)
2073 return ranges::begin(_M_base);
2077 return counted_iterator{ranges::begin(_M_base), __sz};
2081 return counted_iterator{ranges::begin(_M_base), _M_count};
2085 begin() const requires range<const _Vp>
2087 if constexpr (sized_range<const _Vp>)
2089 if constexpr (random_access_range<const _Vp>)
2090 return ranges::begin(_M_base);
2094 return counted_iterator{ranges::begin(_M_base), __sz};
2098 return counted_iterator{ranges::begin(_M_base), _M_count};
2102 end() requires (!__detail::__simple_view<_Vp>)
2104 if constexpr (sized_range<_Vp>)
2106 if constexpr (random_access_range<_Vp>)
2107 return ranges::begin(_M_base) + size();
2109 return default_sentinel;
2112 return _Sentinel<false>{ranges::end(_M_base)};
2116 end() const requires range<const _Vp>
2118 if constexpr (sized_range<const _Vp>)
2120 if constexpr (random_access_range<const _Vp>)
2121 return ranges::begin(_M_base) + size();
2123 return default_sentinel;
2126 return _Sentinel<true>{ranges::end(_M_base)};
2130 size() requires sized_range<_Vp>
2132 auto __n = ranges::size(_M_base);
2133 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2137 size() const requires sized_range<const _Vp>
2139 auto __n = ranges::size(_M_base);
2140 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2144 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2145 // 3447. Deduction guides for take_view and drop_view have different
2147 template<typename _Range>
2148 take_view(_Range&&, range_difference_t<_Range>)
2149 -> take_view<views::all_t<_Range>>;
2151 template<typename _Tp>
2152 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2153 = enable_borrowed_range<_Tp>;
2157 inline constexpr __adaptor::_RangeAdaptor take
2158 = [] <viewable_range _Range, typename _Tp> (_Range&& __r, _Tp&& __n)
2160 return take_view{std::forward<_Range>(__r), std::forward<_Tp>(__n)};
2162 } // namespace views
2164 template<view _Vp, typename _Pred>
2165 requires input_range<_Vp> && is_object_v<_Pred>
2166 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2167 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2169 template<bool _Const>
2173 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2175 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2176 const _Pred* _M_pred = nullptr;
2179 _Sentinel() = default;
2182 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2183 : _M_end(__end), _M_pred(__pred)
2187 _Sentinel(_Sentinel<!_Const> __s)
2188 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2189 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2192 constexpr sentinel_t<_Base>
2193 base() const { return _M_end; }
2195 friend constexpr bool
2196 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2197 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2199 template<bool _OtherConst = !_Const,
2200 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2201 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2202 friend constexpr bool
2203 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2204 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2206 friend _Sentinel<!_Const>;
2209 _Vp _M_base = _Vp();
2210 __detail::__box<_Pred> _M_pred;
2213 take_while_view() = default;
2216 take_while_view(_Vp base, _Pred __pred)
2217 : _M_base(std::move(base)), _M_pred(std::move(__pred))
2222 base() const& requires copy_constructible<_Vp>
2227 { return std::move(_M_base); }
2229 constexpr const _Pred&
2231 { return *_M_pred; }
2234 begin() requires (!__detail::__simple_view<_Vp>)
2235 { return ranges::begin(_M_base); }
2238 begin() const requires range<const _Vp>
2239 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2240 { return ranges::begin(_M_base); }
2243 end() requires (!__detail::__simple_view<_Vp>)
2244 { return _Sentinel<false>(ranges::end(_M_base),
2245 std::__addressof(*_M_pred)); }
2248 end() const requires range<const _Vp>
2249 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2250 { return _Sentinel<true>(ranges::end(_M_base),
2251 std::__addressof(*_M_pred)); }
2254 template<typename _Range, typename _Pred>
2255 take_while_view(_Range&&, _Pred)
2256 -> take_while_view<views::all_t<_Range>, _Pred>;
2260 inline constexpr __adaptor::_RangeAdaptor take_while
2261 = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p)
2263 return take_while_view{std::forward<_Range>(__r), std::forward<_Pred>(__p)};
2265 } // namespace views
2268 class drop_view : public view_interface<drop_view<_Vp>>
2271 _Vp _M_base = _Vp();
2272 range_difference_t<_Vp> _M_count = 0;
2274 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2275 // both random_access_range and sized_range. Otherwise, cache its result.
2276 static constexpr bool _S_needs_cached_begin
2277 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2278 [[no_unique_address]]
2279 __detail::__maybe_present_t<_S_needs_cached_begin,
2280 __detail::_CachedPosition<_Vp>>
2284 drop_view() = default;
2287 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2288 : _M_base(std::move(__base)), _M_count(__count)
2289 { __glibcxx_assert(__count >= 0); }
2292 base() const& requires copy_constructible<_Vp>
2297 { return std::move(_M_base); }
2299 // This overload is disabled for simple views with constant-time begin().
2302 requires (!(__detail::__simple_view<_Vp>
2303 && random_access_range<const _Vp>
2304 && sized_range<const _Vp>))
2306 if constexpr (_S_needs_cached_begin)
2307 if (_M_cached_begin._M_has_value())
2308 return _M_cached_begin._M_get(_M_base);
2310 auto __it = ranges::next(ranges::begin(_M_base),
2311 _M_count, ranges::end(_M_base));
2312 if constexpr (_S_needs_cached_begin)
2313 _M_cached_begin._M_set(_M_base, __it);
2317 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2318 // 3482. drop_view's const begin should additionally require sized_range
2321 requires random_access_range<const _Vp> && sized_range<const _Vp>
2323 return ranges::next(ranges::begin(_M_base), _M_count,
2324 ranges::end(_M_base));
2328 end() requires (!__detail::__simple_view<_Vp>)
2329 { return ranges::end(_M_base); }
2332 end() const requires range<const _Vp>
2333 { return ranges::end(_M_base); }
2336 size() requires sized_range<_Vp>
2338 const auto __s = ranges::size(_M_base);
2339 const auto __c = static_cast<decltype(__s)>(_M_count);
2340 return __s < __c ? 0 : __s - __c;
2344 size() const requires sized_range<const _Vp>
2346 const auto __s = ranges::size(_M_base);
2347 const auto __c = static_cast<decltype(__s)>(_M_count);
2348 return __s < __c ? 0 : __s - __c;
2352 template<typename _Range>
2353 drop_view(_Range&&, range_difference_t<_Range>)
2354 -> drop_view<views::all_t<_Range>>;
2356 template<typename _Tp>
2357 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2358 = enable_borrowed_range<_Tp>;
2362 inline constexpr __adaptor::_RangeAdaptor drop
2363 = [] <viewable_range _Range, typename _Tp> (_Range&& __r, _Tp&& __n)
2365 return drop_view{std::forward<_Range>(__r), std::forward<_Tp>(__n)};
2367 } // namespace views
2369 template<view _Vp, typename _Pred>
2370 requires input_range<_Vp> && is_object_v<_Pred>
2371 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2372 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2375 _Vp _M_base = _Vp();
2376 __detail::__box<_Pred> _M_pred;
2377 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2380 drop_while_view() = default;
2383 drop_while_view(_Vp __base, _Pred __pred)
2384 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2388 base() const& requires copy_constructible<_Vp>
2393 { return std::move(_M_base); }
2395 constexpr const _Pred&
2397 { return *_M_pred; }
2402 if (_M_cached_begin._M_has_value())
2403 return _M_cached_begin._M_get(_M_base);
2405 auto __it = __detail::find_if_not(ranges::begin(_M_base),
2406 ranges::end(_M_base),
2407 std::cref(*_M_pred));
2408 _M_cached_begin._M_set(_M_base, __it);
2414 { return ranges::end(_M_base); }
2417 template<typename _Range, typename _Pred>
2418 drop_while_view(_Range&&, _Pred)
2419 -> drop_while_view<views::all_t<_Range>, _Pred>;
2421 template<typename _Tp, typename _Pred>
2422 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2423 = enable_borrowed_range<_Tp>;
2427 inline constexpr __adaptor::_RangeAdaptor drop_while
2428 = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p)
2430 return drop_while_view{std::forward<_Range>(__r),
2431 std::forward<_Pred>(__p)};
2433 } // namespace views
2435 template<input_range _Vp>
2436 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2437 && (is_reference_v<range_reference_t<_Vp>>
2438 || view<range_value_t<_Vp>>)
2439 class join_view : public view_interface<join_view<_Vp>>
2442 using _InnerRange = range_reference_t<_Vp>;
2444 template<bool _Const>
2445 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2447 template<bool _Const>
2448 using _Outer_iter = iterator_t<_Base<_Const>>;
2450 template<bool _Const>
2451 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2453 template<bool _Const>
2454 static constexpr bool _S_ref_is_glvalue
2455 = is_reference_v<range_reference_t<_Base<_Const>>>;
2457 template<bool _Const>
2461 template<bool _Const>
2462 requires _S_ref_is_glvalue<_Const>
2463 && forward_range<_Base<_Const>>
2464 && forward_range<range_reference_t<_Base<_Const>>>
2465 struct __iter_cat<_Const>
2468 static constexpr auto
2471 using _Outer_iter = join_view::_Outer_iter<_Const>;
2472 using _Inner_iter = join_view::_Inner_iter<_Const>;
2473 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2474 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2475 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2476 && derived_from<_InnerCat, bidirectional_iterator_tag>)
2477 return bidirectional_iterator_tag{};
2478 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2479 && derived_from<_InnerCat, forward_iterator_tag>)
2480 return forward_iterator_tag{};
2482 return input_iterator_tag{};
2485 using iterator_category = decltype(_S_iter_cat());
2488 template<bool _Const>
2491 template<bool _Const>
2492 struct _Iterator : __iter_cat<_Const>
2495 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2496 using _Base = join_view::_Base<_Const>;
2498 static constexpr bool _S_ref_is_glvalue
2499 = join_view::_S_ref_is_glvalue<_Const>;
2504 auto __update_inner = [this] (range_reference_t<_Base> __x) -> auto&
2506 if constexpr (_S_ref_is_glvalue)
2509 return (_M_parent->_M_inner = views::all(std::move(__x)));
2512 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2514 auto& __inner = __update_inner(*_M_outer);
2515 _M_inner = ranges::begin(__inner);
2516 if (_M_inner != ranges::end(__inner))
2520 if constexpr (_S_ref_is_glvalue)
2521 _M_inner = _Inner_iter();
2524 static constexpr auto
2527 if constexpr (_S_ref_is_glvalue
2528 && bidirectional_range<_Base>
2529 && bidirectional_range<range_reference_t<_Base>>)
2530 return bidirectional_iterator_tag{};
2531 else if constexpr (_S_ref_is_glvalue
2532 && forward_range<_Base>
2533 && forward_range<range_reference_t<_Base>>)
2534 return forward_iterator_tag{};
2536 return input_iterator_tag{};
2539 using _Outer_iter = join_view::_Outer_iter<_Const>;
2540 using _Inner_iter = join_view::_Inner_iter<_Const>;
2542 _Outer_iter _M_outer = _Outer_iter();
2543 _Inner_iter _M_inner = _Inner_iter();
2544 _Parent* _M_parent = nullptr;
2547 using iterator_concept = decltype(_S_iter_concept());
2548 // iterator_category defined in __join_view_iter_cat
2549 using value_type = range_value_t<range_reference_t<_Base>>;
2550 using difference_type
2551 = common_type_t<range_difference_t<_Base>,
2552 range_difference_t<range_reference_t<_Base>>>;
2554 _Iterator() = default;
2557 _Iterator(_Parent* __parent, _Outer_iter __outer)
2558 : _M_outer(std::move(__outer)),
2563 _Iterator(_Iterator<!_Const> __i)
2565 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2566 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2567 : _M_outer(std::move(__i._M_outer)), _M_inner(__i._M_inner),
2568 _M_parent(__i._M_parent)
2571 constexpr decltype(auto)
2573 { return *_M_inner; }
2575 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2576 // 3500. join_view::iterator::operator->() is bogus
2577 constexpr _Inner_iter
2579 requires __detail::__has_arrow<_Inner_iter>
2580 && copyable<_Inner_iter>
2581 { return _M_inner; }
2583 constexpr _Iterator&
2586 auto&& __inner_range = [this] () -> auto&& {
2587 if constexpr (_S_ref_is_glvalue)
2590 return _M_parent->_M_inner;
2592 if (++_M_inner == ranges::end(__inner_range))
2606 requires _S_ref_is_glvalue && forward_range<_Base>
2607 && forward_range<range_reference_t<_Base>>
2614 constexpr _Iterator&
2616 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2617 && bidirectional_range<range_reference_t<_Base>>
2618 && common_range<range_reference_t<_Base>>
2620 if (_M_outer == ranges::end(_M_parent->_M_base))
2621 _M_inner = ranges::end(*--_M_outer);
2622 while (_M_inner == ranges::begin(*_M_outer))
2623 _M_inner = ranges::end(*--_M_outer);
2630 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2631 && bidirectional_range<range_reference_t<_Base>>
2632 && common_range<range_reference_t<_Base>>
2639 friend constexpr bool
2640 operator==(const _Iterator& __x, const _Iterator& __y)
2641 requires _S_ref_is_glvalue
2642 && equality_comparable<_Outer_iter>
2643 && equality_comparable<_Inner_iter>
2645 return (__x._M_outer == __y._M_outer
2646 && __x._M_inner == __y._M_inner);
2649 friend constexpr decltype(auto)
2650 iter_move(const _Iterator& __i)
2651 noexcept(noexcept(ranges::iter_move(__i._M_inner)))
2652 { return ranges::iter_move(__i._M_inner); }
2654 friend constexpr void
2655 iter_swap(const _Iterator& __x, const _Iterator& __y)
2656 noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner)))
2657 requires indirectly_swappable<_Inner_iter>
2658 { return ranges::iter_swap(__x._M_inner, __y._M_inner); }
2660 friend _Iterator<!_Const>;
2661 template<bool> friend struct _Sentinel;
2664 template<bool _Const>
2668 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2669 using _Base = join_view::_Base<_Const>;
2671 template<bool _Const2>
2673 __equal(const _Iterator<_Const2>& __i) const
2674 { return __i._M_outer == _M_end; }
2676 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2679 _Sentinel() = default;
2682 _Sentinel(_Parent* __parent)
2683 : _M_end(ranges::end(__parent->_M_base))
2687 _Sentinel(_Sentinel<!_Const> __s)
2688 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2689 : _M_end(std::move(__s._M_end))
2692 template<bool _Const2>
2693 requires sentinel_for<sentinel_t<_Base>,
2694 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2695 friend constexpr bool
2696 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2697 { return __y.__equal(__x); }
2699 friend _Sentinel<!_Const>;
2702 _Vp _M_base = _Vp();
2704 // XXX: _M_inner is "present only when !is_reference_v<_InnerRange>"
2705 [[no_unique_address]]
2706 __detail::__maybe_present_t<!is_reference_v<_InnerRange>,
2707 views::all_t<_InnerRange>> _M_inner;
2710 join_view() = default;
2713 join_view(_Vp __base)
2714 : _M_base(std::move(__base))
2718 base() const& requires copy_constructible<_Vp>
2723 { return std::move(_M_base); }
2728 constexpr bool __use_const
2729 = (__detail::__simple_view<_Vp>
2730 && is_reference_v<range_reference_t<_Vp>>);
2731 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
2736 requires input_range<const _Vp>
2737 && is_reference_v<range_reference_t<const _Vp>>
2739 return _Iterator<true>{this, ranges::begin(_M_base)};
2745 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
2746 && forward_range<_InnerRange>
2747 && common_range<_Vp> && common_range<_InnerRange>)
2748 return _Iterator<__detail::__simple_view<_Vp>>{this,
2749 ranges::end(_M_base)};
2751 return _Sentinel<__detail::__simple_view<_Vp>>{this};
2756 requires input_range<const _Vp>
2757 && is_reference_v<range_reference_t<const _Vp>>
2759 if constexpr (forward_range<const _Vp>
2760 && is_reference_v<range_reference_t<const _Vp>>
2761 && forward_range<range_reference_t<const _Vp>>
2762 && common_range<const _Vp>
2763 && common_range<range_reference_t<const _Vp>>)
2764 return _Iterator<true>{this, ranges::end(_M_base)};
2766 return _Sentinel<true>{this};
2770 template<typename _Range>
2771 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
2775 inline constexpr __adaptor::_RangeAdaptorClosure join
2776 = [] <viewable_range _Range> (_Range&& __r)
2778 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2779 // 3474. Nesting join_views is broken because of CTAD
2780 return join_view<views::all_t<_Range>>{std::forward<_Range>(__r)};
2782 } // namespace views
2787 struct __require_constant;
2789 template<typename _Range>
2790 concept __tiny_range = sized_range<_Range>
2792 { typename __require_constant<remove_reference_t<_Range>::size()>; }
2793 && (remove_reference_t<_Range>::size() <= 1);
2795 template<typename _Base>
2796 struct __split_view_outer_iter_cat
2799 template<forward_range _Base>
2800 struct __split_view_outer_iter_cat<_Base>
2801 { using iterator_category = input_iterator_tag; };
2803 template<typename _Base>
2804 struct __split_view_inner_iter_cat
2807 template<forward_range _Base>
2808 struct __split_view_inner_iter_cat<_Base>
2811 static constexpr auto
2814 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
2815 if constexpr (derived_from<_Cat, forward_iterator_tag>)
2816 return forward_iterator_tag{};
2821 using iterator_category = decltype(_S_iter_cat());
2825 template<input_range _Vp, forward_range _Pattern>
2826 requires view<_Vp> && view<_Pattern>
2827 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
2829 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
2830 class split_view : public view_interface<split_view<_Vp, _Pattern>>
2833 template<bool _Const>
2834 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2836 template<bool _Const>
2839 template<bool _Const>
2841 : __detail::__split_view_outer_iter_cat<_Base<_Const>>
2844 using _Parent = __detail::__maybe_const_t<_Const, split_view>;
2845 using _Base = split_view::_Base<_Const>;
2849 { return __current() == ranges::end(_M_parent->_M_base); }
2851 // [range.split.outer] p1
2852 // Many of the following specifications refer to the notional member
2853 // current of outer-iterator. current is equivalent to current_ if
2854 // V models forward_range, and parent_->current_ otherwise.
2856 __current() noexcept
2858 if constexpr (forward_range<_Vp>)
2861 return _M_parent->_M_current;
2865 __current() const noexcept
2867 if constexpr (forward_range<_Vp>)
2870 return _M_parent->_M_current;
2873 _Parent* _M_parent = nullptr;
2875 // XXX: _M_current is present only if "V models forward_range"
2876 [[no_unique_address]]
2877 __detail::__maybe_present_t<forward_range<_Vp>,
2878 iterator_t<_Base>> _M_current;
2881 using iterator_concept = conditional_t<forward_range<_Base>,
2882 forward_iterator_tag,
2883 input_iterator_tag>;
2884 // iterator_category defined in __split_view_outer_iter_cat
2885 using difference_type = range_difference_t<_Base>;
2887 struct value_type : view_interface<value_type>
2890 _OuterIter _M_i = _OuterIter();
2893 value_type() = default;
2896 value_type(_OuterIter __i)
2897 : _M_i(std::move(__i))
2900 constexpr _InnerIter<_Const>
2902 requires copyable<_OuterIter>
2903 { return _InnerIter<_Const>{_M_i}; }
2905 constexpr _InnerIter<_Const>
2907 requires (!copyable<_OuterIter>)
2908 { return _InnerIter<_Const>{std::move(_M_i)}; }
2910 constexpr default_sentinel_t
2912 { return default_sentinel; }
2915 _OuterIter() = default;
2918 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
2919 : _M_parent(__parent)
2923 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
2924 requires forward_range<_Base>
2925 : _M_parent(__parent),
2926 _M_current(std::move(__current))
2930 _OuterIter(_OuterIter<!_Const> __i)
2932 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
2933 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current))
2936 constexpr value_type
2938 { return value_type{*this}; }
2940 constexpr _OuterIter&
2943 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2944 // 3505. split_view::outer-iterator::operator++ misspecified
2945 const auto __end = ranges::end(_M_parent->_M_base);
2946 if (__current() == __end)
2948 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
2949 if (__pbegin == __pend)
2951 else if constexpr (__detail::__tiny_range<_Pattern>)
2953 __current() = __detail::find(std::move(__current()), __end,
2955 if (__current() != __end)
2962 = __detail::mismatch(__current(), __end, __pbegin, __pend);
2968 } while (++__current() != __end);
2972 constexpr decltype(auto)
2975 if constexpr (forward_range<_Base>)
2985 friend constexpr bool
2986 operator==(const _OuterIter& __x, const _OuterIter& __y)
2987 requires forward_range<_Base>
2988 { return __x._M_current == __y._M_current; }
2990 friend constexpr bool
2991 operator==(const _OuterIter& __x, default_sentinel_t)
2992 { return __x.__at_end(); };
2994 friend _OuterIter<!_Const>;
2995 friend _InnerIter<_Const>;
2998 template<bool _Const>
3000 : __detail::__split_view_inner_iter_cat<_Base<_Const>>
3003 using _Base = split_view::_Base<_Const>;
3008 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3009 auto __end = ranges::end(_M_i._M_parent->_M_base);
3010 if constexpr (__detail::__tiny_range<_Pattern>)
3012 const auto& __cur = _M_i_current();
3015 if (__pcur == __pend)
3016 return _M_incremented;
3017 return *__cur == *__pcur;
3021 auto __cur = _M_i_current();
3024 if (__pcur == __pend)
3025 return _M_incremented;
3028 if (*__cur != *__pcur)
3030 if (++__pcur == __pend)
3032 } while (++__cur != __end);
3038 _M_i_current() noexcept
3039 { return _M_i.__current(); }
3042 _M_i_current() const noexcept
3043 { return _M_i.__current(); }
3045 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3046 bool _M_incremented = false;
3049 using iterator_concept
3050 = typename _OuterIter<_Const>::iterator_concept;
3051 // iterator_category defined in __split_view_inner_iter_cat
3052 using value_type = range_value_t<_Base>;
3053 using difference_type = range_difference_t<_Base>;
3055 _InnerIter() = default;
3058 _InnerIter(_OuterIter<_Const> __i)
3059 : _M_i(std::move(__i))
3062 constexpr decltype(auto)
3064 { return *_M_i_current(); }
3066 constexpr _InnerIter&
3069 _M_incremented = true;
3070 if constexpr (!forward_range<_Base>)
3071 if constexpr (_Pattern::size() == 0)
3077 constexpr decltype(auto)
3080 if constexpr (forward_range<_Base>)
3090 friend constexpr bool
3091 operator==(const _InnerIter& __x, const _InnerIter& __y)
3092 requires forward_range<_Base>
3093 { return __x._M_i == __y._M_i; }
3095 friend constexpr bool
3096 operator==(const _InnerIter& __x, default_sentinel_t)
3097 { return __x.__at_end(); }
3099 friend constexpr decltype(auto)
3100 iter_move(const _InnerIter& __i)
3101 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3102 { return ranges::iter_move(__i._M_i_current()); }
3104 friend constexpr void
3105 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3106 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3107 __y._M_i_current())))
3108 requires indirectly_swappable<iterator_t<_Base>>
3109 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3112 _Vp _M_base = _Vp();
3113 _Pattern _M_pattern = _Pattern();
3115 // XXX: _M_current is "present only if !forward_range<V>"
3116 [[no_unique_address]]
3117 __detail::__maybe_present_t<!forward_range<_Vp>, iterator_t<_Vp>>
3122 split_view() = default;
3125 split_view(_Vp __base, _Pattern __pattern)
3126 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3129 template<input_range _Range>
3130 requires constructible_from<_Vp, views::all_t<_Range>>
3131 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3133 split_view(_Range&& __r, range_value_t<_Range> __e)
3134 : _M_base(views::all(std::forward<_Range>(__r))),
3135 _M_pattern(std::move(__e))
3139 base() const& requires copy_constructible<_Vp>
3144 { return std::move(_M_base); }
3149 if constexpr (forward_range<_Vp>)
3150 return _OuterIter<__detail::__simple_view<_Vp>>{
3151 this, ranges::begin(_M_base)};
3154 _M_current = ranges::begin(_M_base);
3155 return _OuterIter<false>{this};
3160 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3162 return _OuterIter<true>{this, ranges::begin(_M_base)};
3166 end() requires forward_range<_Vp> && common_range<_Vp>
3168 return _OuterIter<__detail::__simple_view<_Vp>>{
3169 this, ranges::end(_M_base)};
3175 if constexpr (forward_range<_Vp>
3176 && forward_range<const _Vp>
3177 && common_range<const _Vp>)
3178 return _OuterIter<true>{this, ranges::end(_M_base)};
3180 return default_sentinel;
3184 template<typename _Range, typename _Pred>
3185 split_view(_Range&&, _Pred&&)
3186 -> split_view<views::all_t<_Range>, views::all_t<_Pred>>;
3188 template<input_range _Range>
3189 split_view(_Range&&, range_value_t<_Range>)
3190 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3194 inline constexpr __adaptor::_RangeAdaptor split
3195 = [] <viewable_range _Range, typename _Fp> (_Range&& __r, _Fp&& __f)
3197 return split_view{std::forward<_Range>(__r), std::forward<_Fp>(__f)};
3199 } // namespace views
3205 template<input_or_output_iterator _Iter>
3207 operator()(_Iter __i, iter_difference_t<_Iter> __n) const
3209 if constexpr (random_access_iterator<_Iter>)
3210 return subrange{__i, __i + __n};
3212 return subrange{counted_iterator{std::move(__i), __n},
3217 inline constexpr _Counted counted{};
3218 } // namespace views
3221 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3222 class common_view : public view_interface<common_view<_Vp>>
3225 _Vp _M_base = _Vp();
3228 common_view() = default;
3231 common_view(_Vp __r)
3232 : _M_base(std::move(__r))
3235 /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
3236 template<viewable_range _Range>
3237 requires (!common_range<_Range>)
3238 && constructible_from<_Vp, views::all_t<_Range>>
3240 common_view(_Range&& __r)
3241 : _M_base(views::all(std::forward<_Range>(__r)))
3246 base() const& requires copy_constructible<_Vp>
3251 { return std::move(_M_base); }
3256 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3257 return ranges::begin(_M_base);
3259 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3260 (ranges::begin(_M_base));
3264 begin() const requires range<const _Vp>
3266 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3267 return ranges::begin(_M_base);
3269 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3270 (ranges::begin(_M_base));
3276 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3277 return ranges::begin(_M_base) + ranges::size(_M_base);
3279 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3280 (ranges::end(_M_base));
3284 end() const requires range<const _Vp>
3286 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3287 return ranges::begin(_M_base) + ranges::size(_M_base);
3289 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3290 (ranges::end(_M_base));
3294 size() requires sized_range<_Vp>
3295 { return ranges::size(_M_base); }
3298 size() const requires sized_range<const _Vp>
3299 { return ranges::size(_M_base); }
3302 template<typename _Range>
3303 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3305 template<typename _Tp>
3306 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3307 = enable_borrowed_range<_Tp>;
3311 inline constexpr __adaptor::_RangeAdaptorClosure common
3312 = [] <viewable_range _Range> (_Range&& __r)
3314 if constexpr (common_range<_Range>
3315 && requires { views::all(std::forward<_Range>(__r)); })
3316 return views::all(std::forward<_Range>(__r));
3318 return common_view{std::forward<_Range>(__r)};
3321 } // namespace views
3324 requires bidirectional_range<_Vp>
3325 class reverse_view : public view_interface<reverse_view<_Vp>>
3328 _Vp _M_base = _Vp();
3330 static constexpr bool _S_needs_cached_begin
3331 = !common_range<_Vp> && !random_access_range<_Vp>;
3332 [[no_unique_address]]
3333 __detail::__maybe_present_t<_S_needs_cached_begin,
3334 __detail::_CachedPosition<_Vp>>
3338 reverse_view() = default;
3341 reverse_view(_Vp __r)
3342 : _M_base(std::move(__r))
3346 base() const& requires copy_constructible<_Vp>
3351 { return std::move(_M_base); }
3353 constexpr reverse_iterator<iterator_t<_Vp>>
3356 if constexpr (_S_needs_cached_begin)
3357 if (_M_cached_begin._M_has_value())
3358 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
3360 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3361 if constexpr (_S_needs_cached_begin)
3362 _M_cached_begin._M_set(_M_base, __it);
3363 return std::make_reverse_iterator(std::move(__it));
3367 begin() requires common_range<_Vp>
3368 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3371 begin() const requires common_range<const _Vp>
3372 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3374 constexpr reverse_iterator<iterator_t<_Vp>>
3376 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3379 end() const requires common_range<const _Vp>
3380 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3383 size() requires sized_range<_Vp>
3384 { return ranges::size(_M_base); }
3387 size() const requires sized_range<const _Vp>
3388 { return ranges::size(_M_base); }
3391 template<typename _Range>
3392 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3394 template<typename _Tp>
3395 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
3396 = enable_borrowed_range<_Tp>;
3403 inline constexpr bool __is_reversible_subrange = false;
3405 template<typename _Iter, subrange_kind _Kind>
3406 inline constexpr bool
3407 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3408 reverse_iterator<_Iter>,
3412 inline constexpr bool __is_reverse_view = false;
3414 template<typename _Vp>
3415 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
3418 inline constexpr __adaptor::_RangeAdaptorClosure reverse
3419 = [] <viewable_range _Range> (_Range&& __r)
3421 using _Tp = remove_cvref_t<_Range>;
3422 if constexpr (__detail::__is_reverse_view<_Tp>)
3423 return std::forward<_Range>(__r).base();
3424 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3426 using _Iter = decltype(ranges::begin(__r).base());
3427 if constexpr (sized_range<_Tp>)
3428 return subrange<_Iter, _Iter, subrange_kind::sized>
3429 (__r.end().base(), __r.begin().base(), __r.size());
3431 return subrange<_Iter, _Iter, subrange_kind::unsized>
3432 (__r.end().base(), __r.begin().base());
3435 return reverse_view{std::forward<_Range>(__r)};
3437 } // namespace views
3441 template<typename _Tp, size_t _Nm>
3442 concept __has_tuple_element = requires(_Tp __t)
3444 typename tuple_size<_Tp>::type;
3445 requires _Nm < tuple_size_v<_Tp>;
3446 typename tuple_element_t<_Nm, _Tp>;
3447 { std::get<_Nm>(__t) }
3448 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
3451 template<typename _Tp, size_t _Nm>
3452 concept __returnable_element
3453 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
3456 template<input_range _Vp, size_t _Nm>
3458 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
3459 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
3461 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
3462 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
3465 elements_view() = default;
3468 elements_view(_Vp base)
3469 : _M_base(std::move(base))
3472 constexpr const _Vp&
3473 base() const & noexcept
3478 { return std::move(_M_base); }
3481 begin() requires (!__detail::__simple_view<_Vp>)
3482 { return _Iterator<false>(ranges::begin(_M_base)); }
3485 begin() const requires range<const _Vp>
3486 { return _Iterator<true>(ranges::begin(_M_base)); }
3489 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
3490 { return _Sentinel<false>{ranges::end(_M_base)}; }
3493 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
3494 { return _Iterator<false>{ranges::end(_M_base)}; }
3497 end() const requires range<const _Vp>
3498 { return _Sentinel<true>{ranges::end(_M_base)}; }
3501 end() const requires common_range<const _Vp>
3502 { return _Iterator<true>{ranges::end(_M_base)}; }
3505 size() requires sized_range<_Vp>
3506 { return ranges::size(_M_base); }
3509 size() const requires sized_range<const _Vp>
3510 { return ranges::size(_M_base); }
3513 template<bool _Const>
3514 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3516 template<bool _Const>
3520 template<bool _Const>
3521 requires forward_range<_Base<_Const>>
3522 struct __iter_cat<_Const>
3525 static auto _S_iter_cat()
3527 using _Base = elements_view::_Base<_Const>;
3528 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3529 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
3530 if constexpr (!is_lvalue_reference_v<_Res>)
3531 return input_iterator_tag{};
3532 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
3533 return random_access_iterator_tag{};
3538 using iterator_category = decltype(_S_iter_cat());
3541 template<bool _Const>
3544 template<bool _Const>
3545 struct _Iterator : __iter_cat<_Const>
3548 using _Base = elements_view::_Base<_Const>;
3550 iterator_t<_Base> _M_current = iterator_t<_Base>();
3552 static constexpr decltype(auto)
3553 _S_get_element(const iterator_t<_Base>& __i)
3555 if constexpr (is_reference_v<range_reference_t<_Base>>)
3556 return std::get<_Nm>(*__i);
3559 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
3560 return static_cast<_Et>(std::get<_Nm>(*__i));
3567 if constexpr (random_access_range<_Vp>)
3568 return random_access_iterator_tag{};
3569 else if constexpr (bidirectional_range<_Vp>)
3570 return bidirectional_iterator_tag{};
3571 else if constexpr (forward_range<_Vp>)
3572 return forward_iterator_tag{};
3574 return input_iterator_tag{};
3577 friend _Iterator<!_Const>;
3580 using iterator_concept = decltype(_S_iter_concept());
3581 // iterator_category defined in elements_view::__iter_cat
3583 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
3584 using difference_type = range_difference_t<_Base>;
3586 _Iterator() = default;
3589 _Iterator(iterator_t<_Base> current)
3590 : _M_current(std::move(current))
3594 _Iterator(_Iterator<!_Const> i)
3595 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3596 : _M_current(std::move(i._M_current))
3599 constexpr iterator_t<_Base>
3601 requires copyable<iterator_t<_Base>>
3602 { return _M_current; }
3604 constexpr iterator_t<_Base>
3606 { return std::move(_M_current); }
3608 constexpr decltype(auto)
3610 { return _S_get_element(_M_current); }
3612 constexpr _Iterator&
3624 operator++(int) requires forward_range<_Base>
3631 constexpr _Iterator&
3632 operator--() requires bidirectional_range<_Base>
3639 operator--(int) requires bidirectional_range<_Base>
3646 constexpr _Iterator&
3647 operator+=(difference_type __n)
3648 requires random_access_range<_Base>
3654 constexpr _Iterator&
3655 operator-=(difference_type __n)
3656 requires random_access_range<_Base>
3662 constexpr decltype(auto)
3663 operator[](difference_type __n) const
3664 requires random_access_range<_Base>
3665 { return _S_get_element(_M_current + __n); }
3667 friend constexpr bool
3668 operator==(const _Iterator& __x, const _Iterator& __y)
3669 requires equality_comparable<iterator_t<_Base>>
3670 { return __x._M_current == __y._M_current; }
3672 friend constexpr bool
3673 operator<(const _Iterator& __x, const _Iterator& __y)
3674 requires random_access_range<_Base>
3675 { return __x._M_current < __y._M_current; }
3677 friend constexpr bool
3678 operator>(const _Iterator& __x, const _Iterator& __y)
3679 requires random_access_range<_Base>
3680 { return __y._M_current < __x._M_current; }
3682 friend constexpr bool
3683 operator<=(const _Iterator& __x, const _Iterator& __y)
3684 requires random_access_range<_Base>
3685 { return !(__y._M_current > __x._M_current); }
3687 friend constexpr bool
3688 operator>=(const _Iterator& __x, const _Iterator& __y)
3689 requires random_access_range<_Base>
3690 { return !(__x._M_current > __y._M_current); }
3692 #ifdef __cpp_lib_three_way_comparison
3693 friend constexpr auto
3694 operator<=>(const _Iterator& __x, const _Iterator& __y)
3695 requires random_access_range<_Base>
3696 && three_way_comparable<iterator_t<_Base>>
3697 { return __x._M_current <=> __y._M_current; }
3700 friend constexpr _Iterator
3701 operator+(const _Iterator& __x, difference_type __y)
3702 requires random_access_range<_Base>
3703 { return _Iterator{__x} += __y; }
3705 friend constexpr _Iterator
3706 operator+(difference_type __x, const _Iterator& __y)
3707 requires random_access_range<_Base>
3708 { return __y + __x; }
3710 friend constexpr _Iterator
3711 operator-(const _Iterator& __x, difference_type __y)
3712 requires random_access_range<_Base>
3713 { return _Iterator{__x} -= __y; }
3715 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3716 // 3483. transform_view::iterator's difference is overconstrained
3717 friend constexpr difference_type
3718 operator-(const _Iterator& __x, const _Iterator& __y)
3719 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
3720 { return __x._M_current - __y._M_current; }
3722 template <bool> friend struct _Sentinel;
3725 template<bool _Const>
3729 template<bool _Const2>
3731 _M_equal(const _Iterator<_Const2>& __x) const
3732 { return __x._M_current == _M_end; }
3734 template<bool _Const2>
3736 _M_distance_from(const _Iterator<_Const2>& __i) const
3737 { return _M_end - __i._M_current; }
3739 using _Base = elements_view::_Base<_Const>;
3740 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3743 _Sentinel() = default;
3746 _Sentinel(sentinel_t<_Base> __end)
3747 : _M_end(std::move(__end))
3751 _Sentinel(_Sentinel<!_Const> __other)
3753 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3754 : _M_end(std::move(__other._M_end))
3757 constexpr sentinel_t<_Base>
3761 template<bool _Const2>
3762 requires sentinel_for<sentinel_t<_Base>,
3763 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3764 friend constexpr bool
3765 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3766 { return __y._M_equal(__x); }
3768 template<bool _Const2,
3769 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
3770 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
3771 friend constexpr range_difference_t<_Base2>
3772 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3773 { return -__y._M_distance_from(__x); }
3775 template<bool _Const2,
3776 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
3777 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
3778 friend constexpr range_difference_t<_Base2>
3779 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
3780 { return __x._M_distance_from(__y); }
3782 friend _Sentinel<!_Const>;
3785 _Vp _M_base = _Vp();
3788 template<typename _Tp, size_t _Nm>
3789 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
3790 = enable_borrowed_range<_Tp>;
3792 template<typename _Range>
3793 using keys_view = elements_view<views::all_t<_Range>, 0>;
3795 template<typename _Range>
3796 using values_view = elements_view<views::all_t<_Range>, 1>;
3800 template<size_t _Nm>
3801 inline constexpr __adaptor::_RangeAdaptorClosure elements
3802 = [] <viewable_range _Range> (_Range&& __r)
3804 using _El = elements_view<views::all_t<_Range>, _Nm>;
3805 return _El{std::forward<_Range>(__r)};
3808 inline constexpr __adaptor::_RangeAdaptorClosure keys = elements<0>;
3809 inline constexpr __adaptor::_RangeAdaptorClosure values = elements<1>;
3810 } // namespace views
3812 } // namespace ranges
3814 namespace views = ranges::views;
3816 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3817 struct tuple_size<ranges::subrange<_Iter, _Sent, _Kind>>
3818 : integral_constant<size_t, 2>
3821 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3822 struct tuple_element<0, ranges::subrange<_Iter, _Sent, _Kind>>
3823 { using type = _Iter; };
3825 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3826 struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>>
3827 { using type = _Sent; };
3829 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3830 struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>>
3831 { using type = _Iter; };
3833 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3834 struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>>
3835 { using type = _Sent; };
3837 _GLIBCXX_END_NAMESPACE_VERSION
3839 #endif // library concepts
3841 #endif /* _GLIBCXX_RANGES */