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 template<typename _Tp>
226 concept __iterator_sentinel_pair
227 = !range<_Tp> && __pair_like<_Tp>
228 && sentinel_for<tuple_element_t<1, _Tp>, tuple_element_t<0, _Tp>>;
230 } // namespace __detail
232 enum class subrange_kind : bool { unsized, sized };
234 template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It,
235 subrange_kind _Kind = sized_sentinel_for<_Sent, _It>
236 ? subrange_kind::sized : subrange_kind::unsized>
237 requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>)
238 class subrange : public view_interface<subrange<_It, _Sent, _Kind>>
241 // XXX: gcc complains when using constexpr here
242 static const bool _S_store_size
243 = _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _It>;
245 _It _M_begin = _It();
246 _Sent _M_end = _Sent();
248 template<typename, bool = _S_store_size>
252 template<typename _Tp>
253 struct _Size<_Tp, true>
254 { __detail::__make_unsigned_like_t<_Tp> _M_size; };
256 [[no_unique_address]] _Size<iter_difference_t<_It>> _M_size = {};
259 subrange() = default;
262 subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s)
263 requires (!_S_store_size)
264 : _M_begin(std::move(__i)), _M_end(__s)
268 subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s,
269 __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
270 requires (_Kind == subrange_kind::sized)
271 : _M_begin(std::move(__i)), _M_end(__s)
273 using __detail::__to_unsigned_like;
274 __glibcxx_assert(__n == __to_unsigned_like(ranges::distance(__i, __s)));
275 if constexpr (_S_store_size)
276 _M_size._M_size = __n;
279 template<__detail::__not_same_as<subrange> _Rng>
280 requires borrowed_range<_Rng>
281 && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
282 && convertible_to<sentinel_t<_Rng>, _Sent>
284 subrange(_Rng&& __r) requires _S_store_size && sized_range<_Rng>
285 : subrange{__r, ranges::size(__r)}
288 template<__detail::__not_same_as<subrange> _Rng>
289 requires borrowed_range<_Rng>
290 && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
291 && convertible_to<sentinel_t<_Rng>, _Sent>
293 subrange(_Rng&& __r) requires (!_S_store_size)
294 : subrange{ranges::begin(__r), ranges::end(__r)}
297 template<borrowed_range _Rng>
298 requires __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
299 && convertible_to<sentinel_t<_Rng>, _Sent>
302 __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
303 requires (_Kind == subrange_kind::sized)
304 : subrange{ranges::begin(__r), ranges::end(__r), __n}
307 template<__detail::__not_same_as<subrange> _PairLike>
308 requires __detail::__pair_like_convertible_from<_PairLike, const _It&,
311 operator _PairLike() const
312 { return _PairLike(_M_begin, _M_end); }
315 begin() const requires copyable<_It>
318 [[nodiscard]] constexpr _It
319 begin() requires (!copyable<_It>)
320 { return std::move(_M_begin); }
322 constexpr _Sent end() const { return _M_end; }
324 constexpr bool empty() const { return _M_begin == _M_end; }
326 constexpr __detail::__make_unsigned_like_t<iter_difference_t<_It>>
327 size() const requires (_Kind == subrange_kind::sized)
329 if constexpr (_S_store_size)
330 return _M_size._M_size;
332 return __detail::__to_unsigned_like(_M_end - _M_begin);
335 [[nodiscard]] constexpr subrange
336 next(iter_difference_t<_It> __n = 1) const &
337 requires forward_iterator<_It>
344 [[nodiscard]] constexpr subrange
345 next(iter_difference_t<_It> __n = 1) &&
348 return std::move(*this);
351 [[nodiscard]] constexpr subrange
352 prev(iter_difference_t<_It> __n = 1) const
353 requires bidirectional_iterator<_It>
361 advance(iter_difference_t<_It> __n)
363 // _GLIBCXX_RESOLVE_LIB_DEFECTS
364 // 3433. subrange::advance(n) has UB when n < 0
365 if constexpr (bidirectional_iterator<_It>)
368 ranges::advance(_M_begin, __n);
369 if constexpr (_S_store_size)
370 _M_size._M_size += __detail::__to_unsigned_like(-__n);
374 __glibcxx_assert(__n >= 0);
375 auto __d = __n - ranges::advance(_M_begin, __n, _M_end);
376 if constexpr (_S_store_size)
377 _M_size._M_size -= __detail::__to_unsigned_like(__d);
382 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
383 subrange(_It, _Sent) -> subrange<_It, _Sent>;
385 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
387 __detail::__make_unsigned_like_t<iter_difference_t<_It>>)
388 -> subrange<_It, _Sent, subrange_kind::sized>;
390 template<__detail::__iterator_sentinel_pair _Pr>
392 -> subrange<tuple_element_t<0, _Pr>, tuple_element_t<1, _Pr>>;
394 template<__detail::__iterator_sentinel_pair _Pr>
395 subrange(_Pr, __detail::__make_unsigned_like_t<iter_difference_t<
396 tuple_element_t<0, _Pr>>>)
397 -> subrange<tuple_element_t<0, _Pr>, tuple_element_t<1, _Pr>,
398 subrange_kind::sized>;
400 template<borrowed_range _Rng>
402 -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>,
404 || sized_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>)
405 ? subrange_kind::sized : subrange_kind::unsized>;
407 template<borrowed_range _Rng>
409 __detail::__make_unsigned_like_t<range_difference_t<_Rng>>)
410 -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, subrange_kind::sized>;
412 template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
415 get(const subrange<_It, _Sent, _Kind>& __r)
417 if constexpr (_Num == 0)
423 template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
426 get(subrange<_It, _Sent, _Kind>&& __r)
428 if constexpr (_Num == 0)
434 template<input_or_output_iterator _It, sentinel_for<_It> _Sent,
436 inline constexpr bool
437 enable_borrowed_range<subrange<_It, _Sent, _Kind>> = true;
439 } // namespace ranges
445 /// Type returned by algorithms instead of a dangling iterator or subrange.
448 constexpr dangling() noexcept = default;
449 template<typename... _Args>
450 constexpr dangling(_Args&&...) noexcept { }
453 template<range _Range>
454 using borrowed_iterator_t = conditional_t<borrowed_range<_Range>,
458 template<range _Range>
459 using borrowed_subrange_t = conditional_t<borrowed_range<_Range>,
460 subrange<iterator_t<_Range>>,
463 template<typename _Tp> requires is_object_v<_Tp>
465 : public view_interface<empty_view<_Tp>>
468 static constexpr _Tp* begin() noexcept { return nullptr; }
469 static constexpr _Tp* end() noexcept { return nullptr; }
470 static constexpr _Tp* data() noexcept { return nullptr; }
471 static constexpr size_t size() noexcept { return 0; }
472 static constexpr bool empty() noexcept { return true; }
475 template<typename _Tp>
476 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
480 template<copy_constructible _Tp> requires is_object_v<_Tp>
481 struct __box : std::optional<_Tp>
483 using std::optional<_Tp>::optional;
487 noexcept(is_nothrow_default_constructible_v<_Tp>)
488 requires default_initializable<_Tp>
489 : std::optional<_Tp>{std::in_place}
492 __box(const __box&) = default;
493 __box(__box&&) = default;
495 using std::optional<_Tp>::operator=;
498 operator=(const __box& __that)
499 noexcept(is_nothrow_copy_constructible_v<_Tp>)
500 requires (!assignable_from<_Tp&, const _Tp&>)
503 this->emplace(*__that);
510 operator=(__box&& __that)
511 noexcept(is_nothrow_move_constructible_v<_Tp>)
512 requires (!assignable_from<_Tp&, _Tp>)
515 this->emplace(std::move(*__that));
522 } // namespace __detail
524 /// A view that contains exactly one element.
525 template<copy_constructible _Tp> requires is_object_v<_Tp>
526 class single_view : public view_interface<single_view<_Tp>>
529 single_view() = default;
532 single_view(const _Tp& __t)
537 single_view(_Tp&& __t)
538 : _M_value(std::move(__t))
541 // _GLIBCXX_RESOLVE_LIB_DEFECTS
542 // 3428. single_view's in place constructor should be explicit
543 template<typename... _Args>
544 requires constructible_from<_Tp, _Args...>
546 single_view(in_place_t, _Args&&... __args)
547 : _M_value{in_place, std::forward<_Args>(__args)...}
555 begin() const noexcept
560 { return data() + 1; }
564 { return data() + 1; }
566 static constexpr size_t
572 { return _M_value.operator->(); }
575 data() const noexcept
576 { return _M_value.operator->(); }
579 __detail::__box<_Tp> _M_value;
584 template<typename _Wp>
585 constexpr auto __to_signed_like(_Wp __w) noexcept
587 if constexpr (!integral<_Wp>)
588 return iter_difference_t<_Wp>();
589 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
590 return iter_difference_t<_Wp>(__w);
591 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
592 return ptrdiff_t(__w);
593 else if constexpr (sizeof(long long) > sizeof(_Wp))
594 return (long long)(__w);
595 #ifdef __SIZEOF_INT128__
596 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
597 return __int128(__w);
600 return __max_diff_type(__w);
603 template<typename _Wp>
604 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
606 template<typename _It>
607 concept __decrementable = incrementable<_It>
610 { --__i } -> same_as<_It&>;
611 { __i-- } -> same_as<_It>;
614 template<typename _It>
615 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
616 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
618 { __i += __n } -> same_as<_It&>;
619 { __i -= __n } -> same_as<_It&>;
623 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
626 } // namespace __detail
628 template<weakly_incrementable _Winc,
629 semiregular _Bound = unreachable_sentinel_t>
630 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
631 && semiregular<_Winc>
632 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
643 using namespace __detail;
644 if constexpr (__advanceable<_Winc>)
645 return random_access_iterator_tag{};
646 else if constexpr (__decrementable<_Winc>)
647 return bidirectional_iterator_tag{};
648 else if constexpr (incrementable<_Winc>)
649 return forward_iterator_tag{};
651 return input_iterator_tag{};
655 using iterator_category = decltype(_S_iter_cat());
656 using value_type = _Winc;
657 using difference_type = __detail::__iota_diff_t<_Winc>;
659 _Iterator() = default;
662 _Iterator(_Winc __value)
663 : _M_value(__value) { }
666 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
681 operator++(int) requires incrementable<_Winc>
689 operator--() requires __detail::__decrementable<_Winc>
696 operator--(int) requires __detail::__decrementable<_Winc>
704 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
706 using __detail::__is_integer_like;
707 using __detail::__is_signed_integer_like;
708 if constexpr (__is_integer_like<_Winc>
709 && !__is_signed_integer_like<_Winc>)
711 if (__n >= difference_type(0))
712 _M_value += static_cast<_Winc>(__n);
714 _M_value -= static_cast<_Winc>(-__n);
722 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
724 using __detail::__is_integer_like;
725 using __detail::__is_signed_integer_like;
726 if constexpr (__is_integer_like<_Winc>
727 && !__is_signed_integer_like<_Winc>)
729 if (__n >= difference_type(0))
730 _M_value -= static_cast<_Winc>(__n);
732 _M_value += static_cast<_Winc>(-__n);
740 operator[](difference_type __n) const
741 requires __detail::__advanceable<_Winc>
742 { return _Winc(_M_value + __n); }
744 friend constexpr bool
745 operator==(const _Iterator& __x, const _Iterator& __y)
746 requires equality_comparable<_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 __x._M_value < __y._M_value; }
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 !(__y < __x); }
764 friend constexpr bool
765 operator>=(const _Iterator& __x, const _Iterator& __y)
766 requires totally_ordered<_Winc>
767 { return !(__x < __y); }
769 #ifdef __cpp_lib_three_way_comparison
770 friend constexpr auto
771 operator<=>(const _Iterator& __x, const _Iterator& __y)
772 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
773 { return __x._M_value <=> __y._M_value; }
776 friend constexpr _Iterator
777 operator+(_Iterator __i, difference_type __n)
778 requires __detail::__advanceable<_Winc>
779 { return __i += __n; }
781 friend constexpr _Iterator
782 operator+(difference_type __n, _Iterator __i)
783 requires __detail::__advanceable<_Winc>
784 { return __i += __n; }
786 friend constexpr _Iterator
787 operator-(_Iterator __i, difference_type __n)
788 requires __detail::__advanceable<_Winc>
789 { return __i -= __n; }
791 friend constexpr difference_type
792 operator-(const _Iterator& __x, const _Iterator& __y)
793 requires __detail::__advanceable<_Winc>
795 using __detail::__is_integer_like;
796 using __detail::__is_signed_integer_like;
797 using _Dt = difference_type;
798 if constexpr (__is_integer_like<_Winc>)
800 if constexpr (__is_signed_integer_like<_Winc>)
801 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
803 return (__y._M_value > __x._M_value)
804 ? _Dt(-_Dt(__y._M_value - __x._M_value))
805 : _Dt(__x._M_value - __y._M_value);
808 return __x._M_value - __y._M_value;
812 _Winc _M_value = _Winc();
821 _M_equal(const _Iterator& __x) const
822 { return __x._M_value == _M_bound; }
824 _Bound _M_bound = _Bound();
827 _Sentinel() = default;
830 _Sentinel(_Bound __bound)
831 : _M_bound(__bound) { }
833 friend constexpr bool
834 operator==(const _Iterator& __x, const _Sentinel& __y)
835 { return __y._M_equal(__x); }
837 friend constexpr iter_difference_t<_Winc>
838 operator-(const _Iterator& __x, const _Sentinel& __y)
839 requires sized_sentinel_for<_Bound, _Winc>
840 { return __x._M_value - __y._M_bound; }
842 friend constexpr iter_difference_t<_Winc>
843 operator-(const _Sentinel& __x, const _Iterator& __y)
844 requires sized_sentinel_for<_Bound, _Winc>
845 { return -(__y - __x); }
848 _Winc _M_value = _Winc();
849 _Bound _M_bound = _Bound();
852 iota_view() = default;
855 iota_view(_Winc __value)
860 iota_view(type_identity_t<_Winc> __value,
861 type_identity_t<_Bound> __bound)
862 : _M_value(__value), _M_bound(__bound)
864 if constexpr (totally_ordered_with<_Winc, _Bound>)
866 __glibcxx_assert( bool(__value <= __bound) );
871 begin() const { return _Iterator{_M_value}; }
876 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
877 return unreachable_sentinel;
879 return _Sentinel{_M_bound};
883 end() const requires same_as<_Winc, _Bound>
884 { return _Iterator{_M_bound}; }
888 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
889 || (integral<_Winc> && integral<_Bound>)
890 || sized_sentinel_for<_Bound, _Winc>
892 using __detail::__is_integer_like;
893 using __detail::__to_unsigned_like;
894 if constexpr (__is_integer_like<_Winc> && __is_integer_like<_Bound>)
895 return (_M_value < 0)
897 ? __to_unsigned_like(-_M_value) - __to_unsigned_like(-_M_bound)
898 : __to_unsigned_like(_M_bound) + __to_unsigned_like(-_M_value))
899 : __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(std::__addressof(__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 // XXX: the following algos are copied from ranges_algo.h to avoid a circular
1293 // dependency with that header.
1296 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1297 typename _Proj = identity,
1298 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
1300 find_if(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {})
1302 while (__first != __last
1303 && !(bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
1308 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1309 typename _Proj = identity,
1310 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
1312 find_if_not(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {})
1314 while (__first != __last
1315 && (bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
1320 template<typename _Tp, typename _Proj = identity,
1321 indirect_strict_weak_order<projected<const _Tp*, _Proj>>
1322 _Comp = ranges::less>
1323 constexpr const _Tp&
1324 min(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {})
1326 if (std::__invoke(std::move(__comp),
1327 std::__invoke(__proj, __b),
1328 std::__invoke(__proj, __a)))
1334 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
1335 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
1336 typename _Pred = ranges::equal_to,
1337 typename _Proj1 = identity, typename _Proj2 = identity>
1338 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
1339 constexpr pair<_Iter1, _Iter2>
1340 mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
1341 _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
1343 while (__first1 != __last1 && __first2 != __last2
1344 && (bool)std::__invoke(__pred,
1345 std::__invoke(__proj1, *__first1),
1346 std::__invoke(__proj2, *__first2)))
1351 return { std::move(__first1), std::move(__first2) };
1353 } // namespace __detail
1357 template<range _Range>
1358 struct _CachedPosition
1361 _M_has_value() const
1364 constexpr iterator_t<_Range>
1365 _M_get(const _Range&) const
1367 __glibcxx_assert(false);
1372 _M_set(const _Range&, const iterator_t<_Range>&) const
1376 template<forward_range _Range>
1377 struct _CachedPosition<_Range>
1380 iterator_t<_Range> _M_iter{};
1384 _M_has_value() const
1385 { return _M_iter != iterator_t<_Range>{}; }
1387 constexpr iterator_t<_Range>
1388 _M_get(const _Range&) const
1390 __glibcxx_assert(_M_has_value());
1395 _M_set(const _Range&, const iterator_t<_Range>& __it)
1397 __glibcxx_assert(!_M_has_value());
1402 template<random_access_range _Range>
1403 requires (sizeof(range_difference_t<_Range>)
1404 <= sizeof(iterator_t<_Range>))
1405 struct _CachedPosition<_Range>
1408 range_difference_t<_Range> _M_offset = -1;
1412 _M_has_value() const
1413 { return _M_offset >= 0; }
1415 constexpr iterator_t<_Range>
1416 _M_get(_Range& __r) const
1418 __glibcxx_assert(_M_has_value());
1419 return ranges::begin(__r) + _M_offset;
1423 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1425 __glibcxx_assert(!_M_has_value());
1426 _M_offset = __it - ranges::begin(__r);
1430 } // namespace __detail
1432 template<input_range _Vp,
1433 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1434 requires view<_Vp> && is_object_v<_Pred>
1435 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1443 static constexpr auto
1446 if constexpr (bidirectional_range<_Vp>)
1447 return bidirectional_iterator_tag{};
1448 else if constexpr (forward_range<_Vp>)
1449 return forward_iterator_tag{};
1451 return input_iterator_tag{};
1454 static constexpr auto
1457 using _Cat = typename iterator_traits<_Vp_iter>::iterator_category;
1458 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1459 return bidirectional_iterator_tag{};
1460 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1461 return forward_iterator_tag{};
1468 using _Vp_iter = iterator_t<_Vp>;
1470 _Vp_iter _M_current = _Vp_iter();
1471 filter_view* _M_parent = nullptr;
1474 using iterator_concept = decltype(_S_iter_concept());
1475 using iterator_category = decltype(_S_iter_cat());
1476 using value_type = range_value_t<_Vp>;
1477 using difference_type = range_difference_t<_Vp>;
1479 _Iterator() = default;
1482 _Iterator(filter_view& __parent, _Vp_iter __current)
1483 : _M_current(std::move(__current)),
1484 _M_parent(std::__addressof(__parent))
1489 requires copyable<_Vp_iter>
1490 { return _M_current; }
1494 { return std::move(_M_current); }
1496 constexpr range_reference_t<_Vp>
1498 { return *_M_current; }
1502 requires __detail::__has_arrow<_Vp_iter>
1503 && copyable<_Vp_iter>
1504 { return _M_current; }
1506 constexpr _Iterator&
1509 _M_current = __detail::find_if(std::move(++_M_current),
1510 ranges::end(_M_parent->_M_base),
1511 std::ref(*_M_parent->_M_pred));
1520 operator++(int) requires forward_range<_Vp>
1527 constexpr _Iterator&
1528 operator--() requires bidirectional_range<_Vp>
1532 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1537 operator--(int) requires bidirectional_range<_Vp>
1544 friend constexpr bool
1545 operator==(const _Iterator& __x, const _Iterator& __y)
1546 requires equality_comparable<_Vp_iter>
1547 { return __x._M_current == __y._M_current; }
1549 friend constexpr range_rvalue_reference_t<_Vp>
1550 iter_move(const _Iterator& __i)
1551 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1552 { return ranges::iter_move(__i._M_current); }
1554 friend constexpr void
1555 iter_swap(const _Iterator& __x, const _Iterator& __y)
1556 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1557 requires indirectly_swappable<_Vp_iter>
1558 { ranges::iter_swap(__x._M_current, __y._M_current); }
1564 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1567 __equal(const _Iterator& __i) const
1568 { return __i._M_current == _M_end; }
1571 _Sentinel() = default;
1574 _Sentinel(filter_view& __parent)
1575 : _M_end(ranges::end(__parent._M_base))
1578 constexpr sentinel_t<_Vp>
1582 friend constexpr bool
1583 operator==(const _Iterator& __x, const _Sentinel& __y)
1584 { return __y.__equal(__x); }
1587 _Vp _M_base = _Vp();
1588 __detail::__box<_Pred> _M_pred;
1589 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1592 filter_view() = default;
1595 filter_view(_Vp __base, _Pred __pred)
1596 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1600 base() const& requires copy_constructible<_Vp>
1605 { return std::move(_M_base); }
1607 constexpr const _Pred&
1609 { return *_M_pred; }
1614 if (_M_cached_begin._M_has_value())
1615 return {*this, _M_cached_begin._M_get(_M_base)};
1617 __glibcxx_assert(_M_pred.has_value());
1618 auto __it = __detail::find_if(ranges::begin(_M_base),
1619 ranges::end(_M_base),
1620 std::ref(*_M_pred));
1621 _M_cached_begin._M_set(_M_base, __it);
1622 return {*this, std::move(__it)};
1628 if constexpr (common_range<_Vp>)
1629 return _Iterator{*this, ranges::end(_M_base)};
1631 return _Sentinel{*this};
1635 template<typename _Range, typename _Pred>
1636 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1640 inline constexpr __adaptor::_RangeAdaptor filter
1641 = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p)
1643 return filter_view{std::forward<_Range>(__r), std::forward<_Pred>(__p)};
1645 } // namespace views
1647 template<input_range _Vp, copy_constructible _Fp>
1648 requires view<_Vp> && is_object_v<_Fp>
1649 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1650 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1651 range_reference_t<_Vp>>>
1652 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1655 template<bool _Const>
1658 template<bool _Const>
1662 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1663 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1665 static constexpr auto
1668 if constexpr (random_access_range<_Vp>)
1669 return random_access_iterator_tag{};
1670 else if constexpr (bidirectional_range<_Vp>)
1671 return bidirectional_iterator_tag{};
1672 else if constexpr (forward_range<_Vp>)
1673 return forward_iterator_tag{};
1675 return input_iterator_tag{};
1678 static constexpr auto
1681 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1682 if constexpr (is_lvalue_reference_v<_Res>)
1685 = typename iterator_traits<_Base_iter>::iterator_category;
1686 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1687 return random_access_iterator_tag{};
1692 return input_iterator_tag{};
1695 using _Base_iter = iterator_t<_Base>;
1697 _Base_iter _M_current = _Base_iter();
1698 _Parent* _M_parent = nullptr;
1701 using iterator_concept = decltype(_S_iter_concept());
1702 using iterator_category = decltype(_S_iter_cat());
1704 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1705 using difference_type = range_difference_t<_Base>;
1707 _Iterator() = default;
1710 _Iterator(_Parent& __parent, _Base_iter __current)
1711 : _M_current(std::move(__current)),
1712 _M_parent(std::__addressof(__parent))
1716 _Iterator(_Iterator<!_Const> __i)
1718 && convertible_to<iterator_t<_Vp>, _Base_iter>
1719 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1722 constexpr _Base_iter
1724 requires copyable<_Base_iter>
1725 { return _M_current; }
1727 constexpr _Base_iter
1729 { return std::move(_M_current); }
1731 constexpr decltype(auto)
1733 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1734 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1736 constexpr _Iterator&
1748 operator++(int) requires forward_range<_Base>
1755 constexpr _Iterator&
1756 operator--() requires bidirectional_range<_Base>
1763 operator--(int) requires bidirectional_range<_Base>
1770 constexpr _Iterator&
1771 operator+=(difference_type __n) requires random_access_range<_Base>
1777 constexpr _Iterator&
1778 operator-=(difference_type __n) requires random_access_range<_Base>
1784 constexpr decltype(auto)
1785 operator[](difference_type __n) const
1786 requires random_access_range<_Base>
1787 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1789 friend constexpr bool
1790 operator==(const _Iterator& __x, const _Iterator& __y)
1791 requires equality_comparable<_Base_iter>
1792 { return __x._M_current == __y._M_current; }
1794 friend constexpr bool
1795 operator<(const _Iterator& __x, const _Iterator& __y)
1796 requires random_access_range<_Base>
1797 { return __x._M_current < __y._M_current; }
1799 friend constexpr bool
1800 operator>(const _Iterator& __x, const _Iterator& __y)
1801 requires random_access_range<_Base>
1802 { return __y < __x; }
1804 friend constexpr bool
1805 operator<=(const _Iterator& __x, const _Iterator& __y)
1806 requires random_access_range<_Base>
1807 { return !(__y < __x); }
1809 friend constexpr bool
1810 operator>=(const _Iterator& __x, const _Iterator& __y)
1811 requires random_access_range<_Base>
1812 { return !(__x < __y); }
1814 #ifdef __cpp_lib_three_way_comparison
1815 friend constexpr auto
1816 operator<=>(const _Iterator& __x, const _Iterator& __y)
1817 requires random_access_range<_Base>
1818 && three_way_comparable<_Base_iter>
1819 { return __x._M_current <=> __y._M_current; }
1822 friend constexpr _Iterator
1823 operator+(_Iterator __i, difference_type __n)
1824 requires random_access_range<_Base>
1825 { return {*__i._M_parent, __i._M_current + __n}; }
1827 friend constexpr _Iterator
1828 operator+(difference_type __n, _Iterator __i)
1829 requires random_access_range<_Base>
1830 { return {*__i._M_parent, __i._M_current + __n}; }
1832 friend constexpr _Iterator
1833 operator-(_Iterator __i, difference_type __n)
1834 requires random_access_range<_Base>
1835 { return {*__i._M_parent, __i._M_current - __n}; }
1837 friend constexpr difference_type
1838 operator-(const _Iterator& __x, const _Iterator& __y)
1839 requires random_access_range<_Base>
1840 { return __x._M_current - __y._M_current; }
1842 friend constexpr decltype(auto)
1843 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
1845 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
1846 return std::move(*__i);
1851 friend constexpr void
1852 iter_swap(const _Iterator& __x, const _Iterator& __y)
1853 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1854 requires indirectly_swappable<_Base_iter>
1855 { return ranges::iter_swap(__x._M_current, __y._M_current); }
1857 friend _Iterator<!_Const>;
1858 template<bool> friend struct _Sentinel;
1861 template<bool _Const>
1865 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1866 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1868 template<bool _Const2>
1870 __distance_from(const _Iterator<_Const2>& __i) const
1871 { return _M_end - __i._M_current; }
1873 template<bool _Const2>
1875 __equal(const _Iterator<_Const2>& __i) const
1876 { return __i._M_current == _M_end; }
1878 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1881 _Sentinel() = default;
1884 _Sentinel(sentinel_t<_Base> __end)
1889 _Sentinel(_Sentinel<!_Const> __i)
1891 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1892 : _M_end(std::move(__i._M_end))
1895 constexpr sentinel_t<_Base>
1899 template<bool _Const2>
1900 requires sentinel_for<sentinel_t<_Base>,
1901 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
1902 friend constexpr bool
1903 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1904 { return __y.__equal(__x); }
1906 template<bool _Const2,
1907 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1908 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1909 friend constexpr range_difference_t<_Base2>
1910 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1911 { return -__y.__distance_from(__x); }
1913 template<bool _Const2,
1914 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1915 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1916 friend constexpr range_difference_t<_Base2>
1917 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
1918 { return __y.__distance_from(__x); }
1920 friend _Sentinel<!_Const>;
1923 _Vp _M_base = _Vp();
1924 __detail::__box<_Fp> _M_fun;
1927 transform_view() = default;
1930 transform_view(_Vp __base, _Fp __fun)
1931 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
1935 base() const& requires copy_constructible<_Vp>
1936 { return _M_base ; }
1940 { return std::move(_M_base); }
1942 constexpr _Iterator<false>
1944 { return _Iterator<false>{*this, ranges::begin(_M_base)}; }
1946 constexpr _Iterator<true>
1948 requires range<const _Vp>
1949 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1950 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
1952 constexpr _Sentinel<false>
1954 { return _Sentinel<false>{ranges::end(_M_base)}; }
1956 constexpr _Iterator<false>
1957 end() requires common_range<_Vp>
1958 { return _Iterator<false>{*this, ranges::end(_M_base)}; }
1960 constexpr _Sentinel<true>
1962 requires range<const _Vp>
1963 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1964 { return _Sentinel<true>{ranges::end(_M_base)}; }
1966 constexpr _Iterator<true>
1968 requires common_range<const _Vp>
1969 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
1970 { return _Iterator<true>{*this, ranges::end(_M_base)}; }
1973 size() requires sized_range<_Vp>
1974 { return ranges::size(_M_base); }
1977 size() const requires sized_range<const _Vp>
1978 { return ranges::size(_M_base); }
1981 template<typename _Range, typename _Fp>
1982 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
1986 inline constexpr __adaptor::_RangeAdaptor transform
1987 = [] <viewable_range _Range, typename _Fp> (_Range&& __r, _Fp&& __f)
1989 return transform_view{std::forward<_Range>(__r), std::forward<_Fp>(__f)};
1991 } // namespace views
1994 class take_view : public view_interface<take_view<_Vp>>
1997 template<bool _Const>
2001 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2002 using _CI = counted_iterator<iterator_t<_Base>>;
2004 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2007 _Sentinel() = default;
2010 _Sentinel(sentinel_t<_Base> __end)
2015 _Sentinel(_Sentinel<!_Const> __s)
2016 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2017 : _M_end(std::move(__s._M_end))
2020 constexpr sentinel_t<_Base>
2024 friend constexpr bool operator==(const _CI& __y, const _Sentinel& __x)
2025 { return __y.count() == 0 || __y.base() == __x._M_end; }
2027 friend _Sentinel<!_Const>;
2030 _Vp _M_base = _Vp();
2031 range_difference_t<_Vp> _M_count = 0;
2034 take_view() = default;
2037 take_view(_Vp base, range_difference_t<_Vp> __count)
2038 : _M_base(std::move(base)), _M_count(std::move(__count))
2042 base() const& requires copy_constructible<_Vp>
2047 { return std::move(_M_base); }
2050 begin() requires (!__detail::__simple_view<_Vp>)
2052 if constexpr (sized_range<_Vp>)
2054 if constexpr (random_access_range<_Vp>)
2055 return ranges::begin(_M_base);
2059 return counted_iterator{ranges::begin(_M_base), __sz};
2063 return counted_iterator{ranges::begin(_M_base), _M_count};
2067 begin() const requires range<const _Vp>
2069 if constexpr (sized_range<const _Vp>)
2071 if constexpr (random_access_range<const _Vp>)
2072 return ranges::begin(_M_base);
2076 return counted_iterator{ranges::begin(_M_base), __sz};
2080 return counted_iterator{ranges::begin(_M_base), _M_count};
2084 end() requires (!__detail::__simple_view<_Vp>)
2086 if constexpr (sized_range<_Vp>)
2088 if constexpr (random_access_range<_Vp>)
2089 return ranges::begin(_M_base) + size();
2091 return default_sentinel;
2094 return _Sentinel<false>{ranges::end(_M_base)};
2098 end() const requires range<const _Vp>
2100 if constexpr (sized_range<const _Vp>)
2102 if constexpr (random_access_range<const _Vp>)
2103 return ranges::begin(_M_base) + size();
2105 return default_sentinel;
2108 return _Sentinel<true>{ranges::end(_M_base)};
2112 size() requires sized_range<_Vp>
2114 auto __n = ranges::size(_M_base);
2115 return __detail::min(__n, static_cast<decltype(__n)>(_M_count));
2119 size() const requires sized_range<const _Vp>
2121 auto __n = ranges::size(_M_base);
2122 return __detail::min(__n, static_cast<decltype(__n)>(_M_count));
2126 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2127 // 3447. Deduction guides for take_view and drop_view have different
2129 template<typename _Range>
2130 take_view(_Range&&, range_difference_t<_Range>)
2131 -> take_view<views::all_t<_Range>>;
2135 inline constexpr __adaptor::_RangeAdaptor take
2136 = [] <viewable_range _Range, typename _Tp> (_Range&& __r, _Tp&& __n)
2138 return take_view{std::forward<_Range>(__r), std::forward<_Tp>(__n)};
2140 } // namespace views
2142 template<view _Vp, typename _Pred>
2143 requires input_range<_Vp> && is_object_v<_Pred>
2144 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2145 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2147 template<bool _Const>
2151 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2153 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2154 const _Pred* _M_pred = nullptr;
2157 _Sentinel() = default;
2160 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2161 : _M_end(__end), _M_pred(__pred)
2165 _Sentinel(_Sentinel<!_Const> __s)
2166 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2167 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2170 constexpr sentinel_t<_Base>
2171 base() const { return _M_end; }
2173 friend constexpr bool
2174 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2175 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2177 friend _Sentinel<!_Const>;
2180 _Vp _M_base = _Vp();
2181 __detail::__box<_Pred> _M_pred;
2184 take_while_view() = default;
2187 take_while_view(_Vp base, _Pred __pred)
2188 : _M_base(std::move(base)), _M_pred(std::move(__pred))
2193 base() const& requires copy_constructible<_Vp>
2198 { return std::move(_M_base); }
2200 constexpr const _Pred&
2202 { return *_M_pred; }
2205 begin() requires (!__detail::__simple_view<_Vp>)
2206 { return ranges::begin(_M_base); }
2209 begin() const requires range<const _Vp>
2210 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2211 { return ranges::begin(_M_base); }
2214 end() requires (!__detail::__simple_view<_Vp>)
2215 { return _Sentinel<false>(ranges::end(_M_base),
2216 std::__addressof(*_M_pred)); }
2219 end() const requires range<const _Vp>
2220 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2221 { return _Sentinel<true>(ranges::end(_M_base),
2222 std::__addressof(*_M_pred)); }
2225 template<typename _Range, typename _Pred>
2226 take_while_view(_Range&&, _Pred)
2227 -> take_while_view<views::all_t<_Range>, _Pred>;
2231 inline constexpr __adaptor::_RangeAdaptor take_while
2232 = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p)
2234 return take_while_view{std::forward<_Range>(__r), std::forward<_Pred>(__p)};
2236 } // namespace views
2239 class drop_view : public view_interface<drop_view<_Vp>>
2242 _Vp _M_base = _Vp();
2243 range_difference_t<_Vp> _M_count = 0;
2245 static constexpr bool _S_needs_cached_begin = !random_access_range<_Vp>;
2246 [[no_unique_address]]
2247 __detail::__maybe_present_t<_S_needs_cached_begin,
2248 __detail::_CachedPosition<_Vp>>
2252 drop_view() = default;
2255 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2256 : _M_base(std::move(__base)), _M_count(__count)
2257 { __glibcxx_assert(__count >= 0); }
2260 base() const& requires copy_constructible<_Vp>
2265 { return std::move(_M_base); }
2268 begin() requires (!(__detail::__simple_view<_Vp>
2269 && random_access_range<_Vp>))
2271 if constexpr (_S_needs_cached_begin)
2272 if (_M_cached_begin._M_has_value())
2273 return _M_cached_begin._M_get(_M_base);
2275 auto __it = ranges::next(ranges::begin(_M_base),
2276 _M_count, ranges::end(_M_base));
2277 if constexpr (_S_needs_cached_begin)
2278 _M_cached_begin._M_set(_M_base, __it);
2283 begin() const requires random_access_range<const _Vp>
2285 return ranges::next(ranges::begin(_M_base), _M_count,
2286 ranges::end(_M_base));
2290 end() requires (!__detail::__simple_view<_Vp>)
2291 { return ranges::end(_M_base); }
2294 end() const requires range<const _Vp>
2295 { return ranges::end(_M_base); }
2298 size() requires sized_range<_Vp>
2300 const auto __s = ranges::size(_M_base);
2301 const auto __c = static_cast<decltype(__s)>(_M_count);
2302 return __s < __c ? 0 : __s - __c;
2306 size() const requires sized_range<const _Vp>
2308 const auto __s = ranges::size(_M_base);
2309 const auto __c = static_cast<decltype(__s)>(_M_count);
2310 return __s < __c ? 0 : __s - __c;
2314 template<typename _Range>
2315 drop_view(_Range&&, range_difference_t<_Range>)
2316 -> drop_view<views::all_t<_Range>>;
2320 inline constexpr __adaptor::_RangeAdaptor drop
2321 = [] <viewable_range _Range, typename _Tp> (_Range&& __r, _Tp&& __n)
2323 return drop_view{std::forward<_Range>(__r), std::forward<_Tp>(__n)};
2325 } // namespace views
2327 template<view _Vp, typename _Pred>
2328 requires input_range<_Vp> && is_object_v<_Pred>
2329 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2330 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2333 _Vp _M_base = _Vp();
2334 __detail::__box<_Pred> _M_pred;
2335 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2338 drop_while_view() = default;
2341 drop_while_view(_Vp __base, _Pred __pred)
2342 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2346 base() const& requires copy_constructible<_Vp>
2351 { return std::move(_M_base); }
2353 constexpr const _Pred&
2355 { return *_M_pred; }
2360 if (_M_cached_begin._M_has_value())
2361 return _M_cached_begin._M_get(_M_base);
2363 auto __it = __detail::find_if_not(ranges::begin(_M_base),
2364 ranges::end(_M_base),
2365 std::cref(*_M_pred));
2366 _M_cached_begin._M_set(_M_base, __it);
2372 { return ranges::end(_M_base); }
2375 template<typename _Range, typename _Pred>
2376 drop_while_view(_Range&&, _Pred)
2377 -> drop_while_view<views::all_t<_Range>, _Pred>;
2381 inline constexpr __adaptor::_RangeAdaptor drop_while
2382 = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p)
2384 return drop_while_view{std::forward<_Range>(__r),
2385 std::forward<_Pred>(__p)};
2387 } // namespace views
2389 template<input_range _Vp>
2390 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2391 && (is_reference_v<range_reference_t<_Vp>>
2392 || view<range_value_t<_Vp>>)
2393 class join_view : public view_interface<join_view<_Vp>>
2396 using _InnerRange = range_reference_t<_Vp>;
2398 template<bool _Const>
2401 template<bool _Const>
2405 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2406 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2408 static constexpr bool _S_ref_is_glvalue
2409 = is_reference_v<range_reference_t<_Base>>;
2414 auto __update_inner = [this] (range_reference_t<_Base> __x) -> auto&
2416 if constexpr (_S_ref_is_glvalue)
2419 return (_M_parent->_M_inner = views::all(std::move(__x)));
2422 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2424 auto& __inner = __update_inner(*_M_outer);
2425 _M_inner = ranges::begin(__inner);
2426 if (_M_inner != ranges::end(__inner))
2430 if constexpr (_S_ref_is_glvalue)
2431 _M_inner = _Inner_iter();
2434 static constexpr auto
2437 if constexpr (_S_ref_is_glvalue
2438 && bidirectional_range<_Base>
2439 && bidirectional_range<range_reference_t<_Base>>)
2440 return bidirectional_iterator_tag{};
2441 else if constexpr (_S_ref_is_glvalue
2442 && forward_range<_Base>
2443 && forward_range<range_reference_t<_Base>>)
2444 return forward_iterator_tag{};
2446 return input_iterator_tag{};
2449 static constexpr auto
2453 = typename iterator_traits<_Outer_iter>::iterator_category;
2455 = typename iterator_traits<_Inner_iter>::iterator_category;
2456 if constexpr (_S_ref_is_glvalue
2457 && derived_from<_OuterCat, bidirectional_iterator_tag>
2458 && derived_from<_InnerCat, bidirectional_iterator_tag>)
2459 return bidirectional_iterator_tag{};
2460 else if constexpr (_S_ref_is_glvalue
2461 && derived_from<_OuterCat, forward_iterator_tag>
2462 && derived_from<_InnerCat, forward_iterator_tag>)
2463 return forward_iterator_tag{};
2464 else if constexpr (derived_from<_OuterCat, input_iterator_tag>
2465 && derived_from<_InnerCat, input_iterator_tag>)
2466 return input_iterator_tag{};
2468 return output_iterator_tag{};
2471 using _Outer_iter = iterator_t<_Base>;
2472 using _Inner_iter = iterator_t<range_reference_t<_Base>>;
2474 _Outer_iter _M_outer = _Outer_iter();
2475 _Inner_iter _M_inner = _Inner_iter();
2476 _Parent* _M_parent = nullptr;
2479 using iterator_concept = decltype(_S_iter_concept());
2480 using iterator_category = decltype(_S_iter_cat());
2481 using value_type = range_value_t<range_reference_t<_Base>>;
2482 using difference_type
2483 = common_type_t<range_difference_t<_Base>,
2484 range_difference_t<range_reference_t<_Base>>>;
2486 _Iterator() = default;
2489 _Iterator(_Parent& __parent, _Outer_iter __outer)
2490 : _M_outer(std::move(__outer)),
2491 _M_parent(std::__addressof(__parent))
2495 _Iterator(_Iterator<!_Const> __i)
2497 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2498 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2499 : _M_outer(std::move(__i._M_outer)), _M_inner(__i._M_inner),
2500 _M_parent(__i._M_parent)
2503 constexpr decltype(auto)
2505 { return *_M_inner; }
2507 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2508 // 3500. join_view::iterator::operator->() is bogus
2509 constexpr _Inner_iter
2511 requires __detail::__has_arrow<_Inner_iter>
2512 && copyable<_Inner_iter>
2513 { return _M_inner; }
2515 constexpr _Iterator&
2518 auto&& __inner_range = [this] () -> decltype(auto) {
2519 if constexpr (_S_ref_is_glvalue)
2522 return _M_parent->_M_inner;
2524 if (++_M_inner == ranges::end(__inner_range))
2538 requires _S_ref_is_glvalue && forward_range<_Base>
2539 && forward_range<range_reference_t<_Base>>
2546 constexpr _Iterator&
2548 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2549 && bidirectional_range<range_reference_t<_Base>>
2550 && common_range<range_reference_t<_Base>>
2552 if (_M_outer == ranges::end(_M_parent->_M_base))
2553 _M_inner = ranges::end(*--_M_outer);
2554 while (_M_inner == ranges::begin(*_M_outer))
2555 _M_inner = ranges::end(*--_M_outer);
2562 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2563 && bidirectional_range<range_reference_t<_Base>>
2564 && common_range<range_reference_t<_Base>>
2571 friend constexpr bool
2572 operator==(const _Iterator& __x, const _Iterator& __y)
2573 requires _S_ref_is_glvalue
2574 && equality_comparable<_Outer_iter>
2575 && equality_comparable<_Inner_iter>
2577 return (__x._M_outer == __y._M_outer
2578 && __x._M_inner == __y._M_inner);
2581 friend constexpr decltype(auto)
2582 iter_move(const _Iterator& __i)
2583 noexcept(noexcept(ranges::iter_move(__i._M_inner)))
2584 { return ranges::iter_move(__i._M_inner); }
2586 friend constexpr void
2587 iter_swap(const _Iterator& __x, const _Iterator& __y)
2588 noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner)))
2589 { return ranges::iter_swap(__x._M_inner, __y._M_inner); }
2591 friend _Iterator<!_Const>;
2592 template<bool> friend struct _Sentinel;
2595 template<bool _Const>
2599 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2600 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2602 template<bool _Const2>
2604 __equal(const _Iterator<_Const2>& __i) const
2605 { return __i._M_outer == _M_end; }
2607 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2610 _Sentinel() = default;
2613 _Sentinel(_Parent& __parent)
2614 : _M_end(ranges::end(__parent._M_base))
2618 _Sentinel(_Sentinel<!_Const> __s)
2619 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2620 : _M_end(std::move(__s._M_end))
2623 template<bool _Const2>
2624 requires sentinel_for<sentinel_t<_Base>,
2625 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2626 friend constexpr bool
2627 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2628 { return __y.__equal(__x); }
2630 friend _Sentinel<!_Const>;
2633 _Vp _M_base = _Vp();
2635 // XXX: _M_inner is "present only when !is_reference_v<_InnerRange>"
2636 [[no_unique_address]]
2637 __detail::__maybe_present_t<!is_reference_v<_InnerRange>,
2638 views::all_t<_InnerRange>> _M_inner;
2641 join_view() = default;
2644 join_view(_Vp __base)
2645 : _M_base(std::move(__base))
2649 base() const& requires copy_constructible<_Vp>
2654 { return std::move(_M_base); }
2659 constexpr bool __use_const
2660 = (__detail::__simple_view<_Vp>
2661 && is_reference_v<range_reference_t<_Vp>>);
2662 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
2667 requires input_range<const _Vp>
2668 && is_reference_v<range_reference_t<const _Vp>>
2670 return _Iterator<true>{*this, ranges::begin(_M_base)};
2676 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
2677 && forward_range<_InnerRange>
2678 && common_range<_Vp> && common_range<_InnerRange>)
2679 return _Iterator<__detail::__simple_view<_Vp>>{*this,
2680 ranges::end(_M_base)};
2682 return _Sentinel<__detail::__simple_view<_Vp>>{*this};
2687 requires input_range<const _Vp>
2688 && is_reference_v<range_reference_t<const _Vp>>
2690 if constexpr (forward_range<const _Vp>
2691 && is_reference_v<range_reference_t<const _Vp>>
2692 && forward_range<range_reference_t<const _Vp>>
2693 && common_range<const _Vp>
2694 && common_range<range_reference_t<const _Vp>>)
2695 return _Iterator<true>{*this, ranges::end(_M_base)};
2697 return _Sentinel<true>{*this};
2701 template<typename _Range>
2702 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
2706 inline constexpr __adaptor::_RangeAdaptorClosure join
2707 = [] <viewable_range _Range> (_Range&& __r)
2709 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2710 // 3474. Nesting join_views is broken because of CTAD
2711 return join_view<views::all_t<_Range>>{std::forward<_Range>(__r)};
2713 } // namespace views
2718 struct __require_constant;
2720 template<typename _Range>
2721 concept __tiny_range = sized_range<_Range>
2723 { typename __require_constant<remove_reference_t<_Range>::size()>; }
2724 && (remove_reference_t<_Range>::size() <= 1);
2727 template<input_range _Vp, forward_range _Pattern>
2728 requires view<_Vp> && view<_Pattern>
2729 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
2731 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
2732 class split_view : public view_interface<split_view<_Vp, _Pattern>>
2735 template<bool _Const>
2738 template<bool _Const>
2742 using _Parent = __detail::__maybe_const_t<_Const, split_view>;
2743 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2747 { return __current() == ranges::end(_M_parent->_M_base); }
2749 // [range.split.outer] p1
2750 // Many of the following specifications refer to the notional member
2751 // current of outer-iterator. current is equivalent to current_ if
2752 // V models forward_range, and parent_->current_ otherwise.
2754 __current() noexcept
2756 if constexpr (forward_range<_Vp>)
2759 return _M_parent->_M_current;
2763 __current() const noexcept
2765 if constexpr (forward_range<_Vp>)
2768 return _M_parent->_M_current;
2771 _Parent* _M_parent = nullptr;
2773 // XXX: _M_current is present only if "V models forward_range"
2774 [[no_unique_address]]
2775 __detail::__maybe_present_t<forward_range<_Vp>,
2776 iterator_t<_Base>> _M_current;
2779 using iterator_concept = conditional_t<forward_range<_Base>,
2780 forward_iterator_tag,
2781 input_iterator_tag>;
2782 using iterator_category = input_iterator_tag;
2783 using difference_type = range_difference_t<_Base>;
2785 struct value_type : view_interface<value_type>
2788 _OuterIter _M_i = _OuterIter();
2791 value_type() = default;
2794 value_type(_OuterIter __i)
2795 : _M_i(std::move(__i))
2798 constexpr _InnerIter<_Const>
2800 requires copyable<_OuterIter>
2801 { return _InnerIter<_Const>{_M_i}; }
2803 constexpr _InnerIter<_Const>
2805 requires (!copyable<_OuterIter>)
2806 { return _InnerIter<_Const>{std::move(_M_i)}; }
2808 constexpr default_sentinel_t
2810 { return default_sentinel; }
2813 _OuterIter() = default;
2816 _OuterIter(_Parent& __parent) requires (!forward_range<_Base>)
2817 : _M_parent(std::__addressof(__parent))
2821 _OuterIter(_Parent& __parent, iterator_t<_Base> __current)
2822 requires forward_range<_Base>
2823 : _M_parent(std::__addressof(__parent)),
2824 _M_current(std::move(__current))
2828 _OuterIter(_OuterIter<!_Const> __i)
2830 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
2831 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current))
2834 constexpr value_type
2836 { return value_type{*this}; }
2838 constexpr _OuterIter&
2841 const auto __end = ranges::end(_M_parent->_M_base);
2842 if (__current() == __end)
2844 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
2845 if (__pbegin == __pend)
2851 = __detail::mismatch(std::move(__current()), __end,
2853 __current() = std::move(__b);
2856 } while (++__current() != __end);
2860 constexpr decltype(auto)
2863 if constexpr (forward_range<_Base>)
2873 friend constexpr bool
2874 operator==(const _OuterIter& __x, const _OuterIter& __y)
2875 requires forward_range<_Base>
2876 { return __x._M_current == __y._M_current; }
2878 friend constexpr bool
2879 operator==(const _OuterIter& __x, default_sentinel_t)
2880 { return __x.__at_end(); };
2882 friend _OuterIter<!_Const>;
2883 friend _InnerIter<_Const>;
2886 template<bool _Const>
2890 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2895 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
2896 auto __end = ranges::end(_M_i._M_parent->_M_base);
2897 if constexpr (__detail::__tiny_range<_Pattern>)
2899 const auto& __cur = _M_i_current();
2902 if (__pcur == __pend)
2903 return _M_incremented;
2904 return *__cur == *__pcur;
2908 auto __cur = _M_i_current();
2911 if (__pcur == __pend)
2912 return _M_incremented;
2915 if (*__cur != *__pcur)
2917 if (++__pcur == __pend)
2919 } while (++__cur != __end);
2924 static constexpr auto
2928 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
2929 if constexpr (derived_from<_Cat, forward_iterator_tag>)
2930 return forward_iterator_tag{};
2936 _M_i_current() noexcept
2937 { return _M_i.__current(); }
2940 _M_i_current() const noexcept
2941 { return _M_i.__current(); }
2943 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
2944 bool _M_incremented = false;
2947 using iterator_concept
2948 = typename _OuterIter<_Const>::iterator_concept;
2949 using iterator_category = decltype(_S_iter_cat());
2950 using value_type = range_value_t<_Base>;
2951 using difference_type = range_difference_t<_Base>;
2953 _InnerIter() = default;
2956 _InnerIter(_OuterIter<_Const> __i)
2957 : _M_i(std::move(__i))
2960 constexpr decltype(auto)
2962 { return *_M_i_current(); }
2964 constexpr _InnerIter&
2967 _M_incremented = true;
2968 if constexpr (!forward_range<_Base>)
2969 if constexpr (_Pattern::size() == 0)
2975 constexpr decltype(auto)
2978 if constexpr (forward_range<_Vp>)
2988 friend constexpr bool
2989 operator==(const _InnerIter& __x, const _InnerIter& __y)
2990 requires forward_range<_Base>
2991 { return __x._M_i == __y._M_i; }
2993 friend constexpr bool
2994 operator==(const _InnerIter& __x, default_sentinel_t)
2995 { return __x.__at_end(); }
2997 friend constexpr decltype(auto)
2998 iter_move(const _InnerIter& __i)
2999 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3000 { return ranges::iter_move(__i._M_i_current()); }
3002 friend constexpr void
3003 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3004 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3005 __y._M_i_current())))
3006 requires indirectly_swappable<iterator_t<_Base>>
3007 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3010 _Vp _M_base = _Vp();
3011 _Pattern _M_pattern = _Pattern();
3013 // XXX: _M_current is "present only if !forward_range<V>"
3014 [[no_unique_address]]
3015 __detail::__maybe_present_t<!forward_range<_Vp>, iterator_t<_Vp>>
3020 split_view() = default;
3023 split_view(_Vp __base, _Pattern __pattern)
3024 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3027 template<input_range _Range>
3028 requires constructible_from<_Vp, views::all_t<_Range>>
3029 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3031 split_view(_Range&& __r, range_value_t<_Range> __e)
3032 : _M_base(views::all(std::forward<_Range>(__r))),
3033 _M_pattern(std::move(__e))
3037 base() const& requires copy_constructible<_Vp>
3042 { return std::move(_M_base); }
3047 if constexpr (forward_range<_Vp>)
3048 return _OuterIter<__detail::__simple_view<_Vp>>{
3049 *this, ranges::begin(_M_base)};
3052 _M_current = ranges::begin(_M_base);
3053 return _OuterIter<false>{*this};
3058 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3060 return _OuterIter<true>{*this, ranges::begin(_M_base)};
3064 end() requires forward_range<_Vp> && common_range<_Vp>
3066 return _OuterIter<__detail::__simple_view<_Vp>>{
3067 *this, ranges::end(_M_base)};
3073 if constexpr (forward_range<_Vp>
3074 && forward_range<const _Vp>
3075 && common_range<const _Vp>)
3076 return _OuterIter<true>{*this, ranges::end(_M_base)};
3078 return default_sentinel;
3082 template<typename _Range, typename _Pred>
3083 split_view(_Range&&, _Pred&&)
3084 -> split_view<views::all_t<_Range>, views::all_t<_Pred>>;
3086 template<input_range _Range>
3087 split_view(_Range&&, range_value_t<_Range>)
3088 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3092 inline constexpr __adaptor::_RangeAdaptor split
3093 = [] <viewable_range _Range, typename _Fp> (_Range&& __r, _Fp&& __f)
3095 return split_view{std::forward<_Range>(__r), std::forward<_Fp>(__f)};
3097 } // namespace views
3103 template<input_or_output_iterator _Iter>
3105 operator()(_Iter __i, iter_difference_t<_Iter> __n) const
3107 if constexpr (random_access_iterator<_Iter>)
3108 return subrange{__i, __i + __n};
3110 return subrange{counted_iterator{std::move(__i), __n},
3115 inline constexpr _Counted counted{};
3116 } // namespace views
3119 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3120 class common_view : public view_interface<common_view<_Vp>>
3123 _Vp _M_base = _Vp();
3126 common_view() = default;
3129 common_view(_Vp __r)
3130 : _M_base(std::move(__r))
3133 /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
3134 template<viewable_range _Range>
3135 requires (!common_range<_Range>)
3136 && constructible_from<_Vp, views::all_t<_Range>>
3138 common_view(_Range&& __r)
3139 : _M_base(views::all(std::forward<_Range>(__r)))
3144 base() const& requires copy_constructible<_Vp>
3149 { return std::move(_M_base); }
3154 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3155 return ranges::begin(_M_base);
3157 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3158 (ranges::begin(_M_base));
3162 begin() const requires range<const _Vp>
3164 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3165 return ranges::begin(_M_base);
3167 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3168 (ranges::begin(_M_base));
3174 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3175 return ranges::begin(_M_base) + ranges::size(_M_base);
3177 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3178 (ranges::end(_M_base));
3182 end() const requires range<const _Vp>
3184 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3185 return ranges::begin(_M_base) + ranges::size(_M_base);
3187 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3188 (ranges::end(_M_base));
3192 size() requires sized_range<_Vp>
3193 { return ranges::size(_M_base); }
3196 size() const requires sized_range<const _Vp>
3197 { return ranges::size(_M_base); }
3200 template<typename _Range>
3201 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3205 inline constexpr __adaptor::_RangeAdaptorClosure common
3206 = [] <viewable_range _Range> (_Range&& __r)
3208 if constexpr (common_range<_Range>
3209 && requires { views::all(std::forward<_Range>(__r)); })
3210 return views::all(std::forward<_Range>(__r));
3212 return common_view{std::forward<_Range>(__r)};
3215 } // namespace views
3218 requires bidirectional_range<_Vp>
3219 class reverse_view : public view_interface<reverse_view<_Vp>>
3222 _Vp _M_base = _Vp();
3224 static constexpr bool _S_needs_cached_begin
3225 = !common_range<_Vp> && !random_access_range<_Vp>;
3226 [[no_unique_address]]
3227 __detail::__maybe_present_t<_S_needs_cached_begin,
3228 __detail::_CachedPosition<_Vp>>
3232 reverse_view() = default;
3235 reverse_view(_Vp __r)
3236 : _M_base(std::move(__r))
3240 base() const& requires copy_constructible<_Vp>
3245 { return std::move(_M_base); }
3247 constexpr reverse_iterator<iterator_t<_Vp>>
3250 if constexpr (_S_needs_cached_begin)
3251 if (_M_cached_begin._M_has_value())
3252 return make_reverse_iterator(_M_cached_begin._M_get(_M_base));
3254 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3255 if constexpr (_S_needs_cached_begin)
3256 _M_cached_begin._M_set(_M_base, __it);
3257 return make_reverse_iterator(std::move(__it));
3261 begin() requires common_range<_Vp>
3262 { return make_reverse_iterator(ranges::end(_M_base)); }
3265 begin() const requires common_range<const _Vp>
3266 { return make_reverse_iterator(ranges::end(_M_base)); }
3268 constexpr reverse_iterator<iterator_t<_Vp>>
3270 { return make_reverse_iterator(ranges::begin(_M_base)); }
3273 end() const requires common_range<const _Vp>
3274 { return make_reverse_iterator(ranges::begin(_M_base)); }
3277 size() requires sized_range<_Vp>
3278 { return ranges::size(_M_base); }
3281 size() const requires sized_range<const _Vp>
3282 { return ranges::size(_M_base); }
3285 template<typename _Range>
3286 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3293 inline constexpr bool __is_reversible_subrange = false;
3295 template<typename _Iter, subrange_kind _Kind>
3296 inline constexpr bool
3297 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3298 reverse_iterator<_Iter>,
3302 inline constexpr bool __is_reverse_view = false;
3304 template<typename _Vp>
3305 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
3308 inline constexpr __adaptor::_RangeAdaptorClosure reverse
3309 = [] <viewable_range _Range> (_Range&& __r)
3311 using _Tp = remove_cvref_t<_Range>;
3312 if constexpr (__detail::__is_reverse_view<_Tp>)
3313 return std::forward<_Range>(__r).base();
3314 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3316 using _Iter = decltype(ranges::begin(__r).base());
3317 if constexpr (sized_range<_Tp>)
3318 return subrange<_Iter, _Iter, subrange_kind::sized>
3319 (__r.end().base(), __r.begin().base(), __r.size());
3321 return subrange<_Iter, _Iter, subrange_kind::unsized>
3322 (__r.end().base(), __r.begin().base());
3325 return reverse_view{std::forward<_Range>(__r)};
3327 } // namespace views
3331 template<typename _Tp, size_t _Nm>
3332 concept __has_tuple_element = requires(_Tp __t)
3334 typename tuple_size<_Tp>::type;
3335 requires _Nm < tuple_size_v<_Tp>;
3336 typename tuple_element_t<_Nm, _Tp>;
3337 { std::get<_Nm>(__t) }
3338 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
3342 template<input_range _Vp, size_t _Nm>
3344 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
3345 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
3347 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
3350 elements_view() = default;
3353 elements_view(_Vp base)
3354 : _M_base(std::move(base))
3358 base() const& requires copy_constructible<_Vp>
3363 { return std::move(_M_base); }
3366 begin() requires (!__detail::__simple_view<_Vp>)
3367 { return _Iterator<false>(ranges::begin(_M_base)); }
3370 begin() const requires range<const _Vp>
3371 { return _Iterator<true>(ranges::begin(_M_base)); }
3374 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
3375 { return _Sentinel<false>{ranges::end(_M_base)}; }
3378 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
3379 { return _Iterator<false>{ranges::end(_M_base)}; }
3382 end() const requires range<const _Vp>
3383 { return _Sentinel<true>{ranges::end(_M_base)}; }
3386 end() const requires common_range<const _Vp>
3387 { return _Iterator<true>{ranges::end(_M_base)}; }
3390 size() requires sized_range<_Vp>
3391 { return ranges::size(_M_base); }
3394 size() const requires sized_range<const _Vp>
3395 { return ranges::size(_M_base); }
3398 template<bool _Const>
3401 template<bool _Const>
3404 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3406 iterator_t<_Base> _M_current = iterator_t<_Base>();
3408 friend _Iterator<!_Const>;
3411 using iterator_category
3412 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3414 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
3415 using difference_type = range_difference_t<_Base>;
3417 _Iterator() = default;
3420 _Iterator(iterator_t<_Base> current)
3421 : _M_current(std::move(current))
3425 _Iterator(_Iterator<!_Const> i)
3426 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3427 : _M_current(std::move(i._M_current))
3430 constexpr iterator_t<_Base>
3432 requires copyable<iterator_t<_Base>>
3433 { return _M_current; }
3435 constexpr iterator_t<_Base>
3437 { return std::move(_M_current); }
3439 constexpr decltype(auto)
3441 { return std::get<_Nm>(*_M_current); }
3443 constexpr _Iterator&
3451 operator++(int) requires (!forward_range<_Base>)
3455 operator++(int) requires forward_range<_Base>
3462 constexpr _Iterator&
3463 operator--() requires bidirectional_range<_Base>
3470 operator--(int) requires bidirectional_range<_Base>
3477 constexpr _Iterator&
3478 operator+=(difference_type __n)
3479 requires random_access_range<_Base>
3485 constexpr _Iterator&
3486 operator-=(difference_type __n)
3487 requires random_access_range<_Base>
3493 constexpr decltype(auto)
3494 operator[](difference_type __n) const
3495 requires random_access_range<_Base>
3496 { return std::get<_Nm>(*(_M_current + __n)); }
3498 friend constexpr bool
3499 operator==(const _Iterator& __x, const _Iterator& __y)
3500 requires equality_comparable<iterator_t<_Base>>
3501 { return __x._M_current == __y._M_current; }
3503 friend constexpr bool
3504 operator<(const _Iterator& __x, const _Iterator& __y)
3505 requires random_access_range<_Base>
3506 { return __x._M_current < __y._M_current; }
3508 friend constexpr bool
3509 operator>(const _Iterator& __x, const _Iterator& __y)
3510 requires random_access_range<_Base>
3511 { return __y._M_current < __x._M_current; }
3513 friend constexpr bool
3514 operator<=(const _Iterator& __x, const _Iterator& __y)
3515 requires random_access_range<_Base>
3516 { return !(__y._M_current > __x._M_current); }
3518 friend constexpr bool
3519 operator>=(const _Iterator& __x, const _Iterator& __y)
3520 requires random_access_range<_Base>
3521 { return !(__x._M_current > __y._M_current); }
3523 #ifdef __cpp_lib_three_way_comparison
3524 friend constexpr auto
3525 operator<=>(const _Iterator& __x, const _Iterator& __y)
3526 requires random_access_range<_Base>
3527 && three_way_comparable<iterator_t<_Base>>
3528 { return __x._M_current <=> __y._M_current; }
3531 friend constexpr _Iterator
3532 operator+(const _Iterator& __x, difference_type __y)
3533 requires random_access_range<_Base>
3534 { return _Iterator{__x} += __y; }
3536 friend constexpr _Iterator
3537 operator+(difference_type __x, const _Iterator& __y)
3538 requires random_access_range<_Base>
3539 { return __y + __x; }
3541 friend constexpr _Iterator
3542 operator-(const _Iterator& __x, difference_type __y)
3543 requires random_access_range<_Base>
3544 { return _Iterator{__x} -= __y; }
3546 friend constexpr difference_type
3547 operator-(const _Iterator& __x, const _Iterator& __y)
3548 requires random_access_range<_Base>
3549 { return __x._M_current - __y._M_current; }
3551 friend _Sentinel<_Const>;
3554 template<bool _Const>
3559 _M_equal(const _Iterator<_Const>& __x) const
3560 { return __x._M_current == _M_end; }
3562 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3563 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3566 _Sentinel() = default;
3569 _Sentinel(sentinel_t<_Base> __end)
3570 : _M_end(std::move(__end))
3574 _Sentinel(_Sentinel<!_Const> __other)
3576 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3577 : _M_end(std::move(__other._M_end))
3580 constexpr sentinel_t<_Base>
3584 template<bool _Const2>
3585 requires sentinel_for<sentinel_t<_Base>,
3586 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3587 friend constexpr bool
3588 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3589 { return __y._M_equal(__x); }
3591 template<bool _Const2,
3592 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
3593 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
3594 friend constexpr range_difference_t<_Base2>
3595 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3596 { return __x._M_current - __y._M_end; }
3598 template<bool _Const2,
3599 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
3600 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
3601 friend constexpr range_difference_t<_Base>
3602 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
3603 { return __x._M_end - __y._M_current; }
3605 friend _Sentinel<!_Const>;
3608 _Vp _M_base = _Vp();
3611 template<typename _Range>
3612 using keys_view = elements_view<views::all_t<_Range>, 0>;
3614 template<typename _Range>
3615 using values_view = elements_view<views::all_t<_Range>, 1>;
3619 template<size_t _Nm>
3620 inline constexpr __adaptor::_RangeAdaptorClosure elements
3621 = [] <viewable_range _Range> (_Range&& __r)
3623 using _El = elements_view<views::all_t<_Range>, _Nm>;
3624 return _El{std::forward<_Range>(__r)};
3627 inline constexpr __adaptor::_RangeAdaptorClosure keys = elements<0>;
3628 inline constexpr __adaptor::_RangeAdaptorClosure values = elements<1>;
3629 } // namespace views
3631 } // namespace ranges
3633 namespace views = ranges::views;
3635 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3636 struct tuple_size<ranges::subrange<_Iter, _Sent, _Kind>>
3637 : integral_constant<size_t, 2>
3640 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3641 struct tuple_element<0, ranges::subrange<_Iter, _Sent, _Kind>>
3642 { using type = _Iter; };
3644 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3645 struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>>
3646 { using type = _Sent; };
3648 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3649 struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>>
3650 { using type = _Iter; };
3652 template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
3653 struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>>
3654 { using type = _Sent; };
3656 _GLIBCXX_END_NAMESPACE_VERSION
3658 #endif // library concepts
3660 #endif /* _GLIBCXX_RANGES */