14c3eb207Smrg// <ranges> -*- C++ -*- 24c3eb207Smrg 34c3eb207Smrg// Copyright (C) 2019-2020 Free Software Foundation, Inc. 44c3eb207Smrg// 54c3eb207Smrg// This file is part of the GNU ISO C++ Library. This library is free 64c3eb207Smrg// software; you can redistribute it and/or modify it under the 74c3eb207Smrg// terms of the GNU General Public License as published by the 84c3eb207Smrg// Free Software Foundation; either version 3, or (at your option) 94c3eb207Smrg// any later version. 104c3eb207Smrg 114c3eb207Smrg// This library is distributed in the hope that it will be useful, 124c3eb207Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 134c3eb207Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144c3eb207Smrg// GNU General Public License for more details. 154c3eb207Smrg 164c3eb207Smrg// Under Section 7 of GPL version 3, you are granted additional 174c3eb207Smrg// permissions described in the GCC Runtime Library Exception, version 184c3eb207Smrg// 3.1, as published by the Free Software Foundation. 194c3eb207Smrg 204c3eb207Smrg// You should have received a copy of the GNU General Public License and 214c3eb207Smrg// a copy of the GCC Runtime Library Exception along with this program; 224c3eb207Smrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 234c3eb207Smrg// <http://www.gnu.org/licenses/>. 244c3eb207Smrg 254c3eb207Smrg/** @file include/ranges 264c3eb207Smrg * This is a Standard C++ Library header. 274c3eb207Smrg * @ingroup concepts 284c3eb207Smrg */ 294c3eb207Smrg 304c3eb207Smrg#ifndef _GLIBCXX_RANGES 314c3eb207Smrg#define _GLIBCXX_RANGES 1 324c3eb207Smrg 334c3eb207Smrg#if __cplusplus > 201703L 344c3eb207Smrg 354c3eb207Smrg#pragma GCC system_header 364c3eb207Smrg 374c3eb207Smrg#include <concepts> 384c3eb207Smrg 394c3eb207Smrg#if __cpp_lib_concepts 404c3eb207Smrg 414c3eb207Smrg#include <bits/refwrap.h> 424c3eb207Smrg#include <compare> 434c3eb207Smrg#include <initializer_list> 444c3eb207Smrg#include <iterator> 454c3eb207Smrg#include <optional> 464c3eb207Smrg#include <tuple> 474c3eb207Smrg 484c3eb207Smrg/** 494c3eb207Smrg * @defgroup ranges Ranges 504c3eb207Smrg * 514c3eb207Smrg * Components for dealing with ranges of elements. 524c3eb207Smrg */ 534c3eb207Smrg 544c3eb207Smrgnamespace std _GLIBCXX_VISIBILITY(default) 554c3eb207Smrg{ 564c3eb207Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 574c3eb207Smrgnamespace ranges 584c3eb207Smrg{ 594c3eb207Smrg // [range.range] The range concept. 604c3eb207Smrg // [range.sized] The sized_range concept. 614c3eb207Smrg // Defined in <bits/range_access.h> 624c3eb207Smrg 634c3eb207Smrg // [range.refinements] 644c3eb207Smrg // Defined in <bits/range_access.h> 654c3eb207Smrg 664c3eb207Smrg struct view_base { }; 674c3eb207Smrg 684c3eb207Smrg template<typename _Tp> 694c3eb207Smrg inline constexpr bool enable_view = derived_from<_Tp, view_base>; 704c3eb207Smrg 714c3eb207Smrg template<typename _Tp> 724c3eb207Smrg concept view 734c3eb207Smrg = range<_Tp> && movable<_Tp> && enable_view<_Tp>; 744c3eb207Smrg 754c3eb207Smrg /// A range which can be safely converted to a view. 764c3eb207Smrg template<typename _Tp> 774c3eb207Smrg concept viewable_range = range<_Tp> 784c3eb207Smrg && (borrowed_range<_Tp> || view<remove_cvref_t<_Tp>>); 794c3eb207Smrg 804c3eb207Smrg namespace __detail 814c3eb207Smrg { 824c3eb207Smrg template<typename _Range> 834c3eb207Smrg concept __simple_view = view<_Range> && range<const _Range> 844c3eb207Smrg && same_as<iterator_t<_Range>, iterator_t<const _Range>> 854c3eb207Smrg && same_as<sentinel_t<_Range>, sentinel_t<const _Range>>; 864c3eb207Smrg 874c3eb207Smrg template<typename _It> 884c3eb207Smrg concept __has_arrow = input_iterator<_It> 894c3eb207Smrg && (is_pointer_v<_It> || requires(_It __it) { __it.operator->(); }); 904c3eb207Smrg 914c3eb207Smrg template<typename _Tp, typename _Up> 924c3eb207Smrg concept __not_same_as 934c3eb207Smrg = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>; 944c3eb207Smrg } // namespace __detail 954c3eb207Smrg 964c3eb207Smrg template<typename _Derived> 974c3eb207Smrg requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> 984c3eb207Smrg class view_interface : public view_base 994c3eb207Smrg { 1004c3eb207Smrg private: 1014c3eb207Smrg constexpr _Derived& _M_derived() noexcept 1024c3eb207Smrg { 1034c3eb207Smrg static_assert(derived_from<_Derived, view_interface<_Derived>>); 1044c3eb207Smrg static_assert(view<_Derived>); 1054c3eb207Smrg return static_cast<_Derived&>(*this); 1064c3eb207Smrg } 1074c3eb207Smrg 1084c3eb207Smrg constexpr const _Derived& _M_derived() const noexcept 1094c3eb207Smrg { 1104c3eb207Smrg static_assert(derived_from<_Derived, view_interface<_Derived>>); 1114c3eb207Smrg static_assert(view<_Derived>); 1124c3eb207Smrg return static_cast<const _Derived&>(*this); 1134c3eb207Smrg } 1144c3eb207Smrg 1154c3eb207Smrg public: 1164c3eb207Smrg constexpr bool 1174c3eb207Smrg empty() requires forward_range<_Derived> 1184c3eb207Smrg { return ranges::begin(_M_derived()) == ranges::end(_M_derived()); } 1194c3eb207Smrg 1204c3eb207Smrg constexpr bool 1214c3eb207Smrg empty() const requires forward_range<const _Derived> 1224c3eb207Smrg { return ranges::begin(_M_derived()) == ranges::end(_M_derived()); } 1234c3eb207Smrg 1244c3eb207Smrg constexpr explicit 1254c3eb207Smrg operator bool() requires requires { ranges::empty(_M_derived()); } 1264c3eb207Smrg { return !ranges::empty(_M_derived()); } 1274c3eb207Smrg 1284c3eb207Smrg constexpr explicit 1294c3eb207Smrg operator bool() const requires requires { ranges::empty(_M_derived()); } 1304c3eb207Smrg { return !ranges::empty(_M_derived()); } 1314c3eb207Smrg 1324c3eb207Smrg constexpr auto 1334c3eb207Smrg data() requires contiguous_iterator<iterator_t<_Derived>> 1344c3eb207Smrg { return to_address(ranges::begin(_M_derived())); } 1354c3eb207Smrg 1364c3eb207Smrg constexpr auto 1374c3eb207Smrg data() const 1384c3eb207Smrg requires range<const _Derived> 1394c3eb207Smrg && contiguous_iterator<iterator_t<const _Derived>> 1404c3eb207Smrg { return to_address(ranges::begin(_M_derived())); } 1414c3eb207Smrg 1424c3eb207Smrg constexpr auto 1434c3eb207Smrg size() 1444c3eb207Smrg requires forward_range<_Derived> 1454c3eb207Smrg && sized_sentinel_for<sentinel_t<_Derived>, iterator_t<_Derived>> 1464c3eb207Smrg { return ranges::end(_M_derived()) - ranges::begin(_M_derived()); } 1474c3eb207Smrg 1484c3eb207Smrg constexpr auto 1494c3eb207Smrg size() const 1504c3eb207Smrg requires forward_range<const _Derived> 1514c3eb207Smrg && sized_sentinel_for<sentinel_t<const _Derived>, 1524c3eb207Smrg iterator_t<const _Derived>> 1534c3eb207Smrg { return ranges::end(_M_derived()) - ranges::begin(_M_derived()); } 1544c3eb207Smrg 1554c3eb207Smrg constexpr decltype(auto) 1564c3eb207Smrg front() requires forward_range<_Derived> 1574c3eb207Smrg { 1584c3eb207Smrg __glibcxx_assert(!empty()); 1594c3eb207Smrg return *ranges::begin(_M_derived()); 1604c3eb207Smrg } 1614c3eb207Smrg 1624c3eb207Smrg constexpr decltype(auto) 1634c3eb207Smrg front() const requires forward_range<const _Derived> 1644c3eb207Smrg { 1654c3eb207Smrg __glibcxx_assert(!empty()); 1664c3eb207Smrg return *ranges::begin(_M_derived()); 1674c3eb207Smrg } 1684c3eb207Smrg 1694c3eb207Smrg constexpr decltype(auto) 1704c3eb207Smrg back() 1714c3eb207Smrg requires bidirectional_range<_Derived> && common_range<_Derived> 1724c3eb207Smrg { 1734c3eb207Smrg __glibcxx_assert(!empty()); 1744c3eb207Smrg return *ranges::prev(ranges::end(_M_derived())); 1754c3eb207Smrg } 1764c3eb207Smrg 1774c3eb207Smrg constexpr decltype(auto) 1784c3eb207Smrg back() const 1794c3eb207Smrg requires bidirectional_range<const _Derived> 1804c3eb207Smrg && common_range<const _Derived> 1814c3eb207Smrg { 1824c3eb207Smrg __glibcxx_assert(!empty()); 1834c3eb207Smrg return *ranges::prev(ranges::end(_M_derived())); 1844c3eb207Smrg } 1854c3eb207Smrg 1864c3eb207Smrg template<random_access_range _Range = _Derived> 1874c3eb207Smrg constexpr decltype(auto) 1884c3eb207Smrg operator[](range_difference_t<_Range> __n) 1894c3eb207Smrg { return ranges::begin(_M_derived())[__n]; } 1904c3eb207Smrg 1914c3eb207Smrg template<random_access_range _Range = const _Derived> 1924c3eb207Smrg constexpr decltype(auto) 1934c3eb207Smrg operator[](range_difference_t<_Range> __n) const 1944c3eb207Smrg { return ranges::begin(_M_derived())[__n]; } 1954c3eb207Smrg }; 1964c3eb207Smrg 1974c3eb207Smrg namespace __detail 1984c3eb207Smrg { 1994c3eb207Smrg template<class _From, class _To> 2004c3eb207Smrg concept __convertible_to_non_slicing = convertible_to<_From, _To> 2014c3eb207Smrg && !(is_pointer_v<decay_t<_From>> && is_pointer_v<decay_t<_To>> 2024c3eb207Smrg && __not_same_as<remove_pointer_t<decay_t<_From>>, 2034c3eb207Smrg remove_pointer_t<decay_t<_To>>>); 2044c3eb207Smrg 2054c3eb207Smrg template<typename _Tp> 2064c3eb207Smrg concept __pair_like 2074c3eb207Smrg = !is_reference_v<_Tp> && requires(_Tp __t) 2084c3eb207Smrg { 2094c3eb207Smrg typename tuple_size<_Tp>::type; 2104c3eb207Smrg requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>; 2114c3eb207Smrg typename tuple_element_t<0, remove_const_t<_Tp>>; 2124c3eb207Smrg typename tuple_element_t<1, remove_const_t<_Tp>>; 2134c3eb207Smrg { get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>; 2144c3eb207Smrg { get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>; 2154c3eb207Smrg }; 2164c3eb207Smrg 2174c3eb207Smrg template<typename _Tp, typename _Up, typename _Vp> 2184c3eb207Smrg concept __pair_like_convertible_from 2194c3eb207Smrg = !range<_Tp> && __pair_like<_Tp> 2204c3eb207Smrg && constructible_from<_Tp, _Up, _Vp> 2214c3eb207Smrg && __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>> 2224c3eb207Smrg && convertible_to<_Vp, tuple_element_t<1, _Tp>>; 2234c3eb207Smrg 2244c3eb207Smrg } // namespace __detail 2254c3eb207Smrg 2264c3eb207Smrg enum class subrange_kind : bool { unsized, sized }; 2274c3eb207Smrg 2284c3eb207Smrg template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It, 2294c3eb207Smrg subrange_kind _Kind = sized_sentinel_for<_Sent, _It> 2304c3eb207Smrg ? subrange_kind::sized : subrange_kind::unsized> 2314c3eb207Smrg requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>) 2324c3eb207Smrg class subrange : public view_interface<subrange<_It, _Sent, _Kind>> 2334c3eb207Smrg { 2344c3eb207Smrg private: 2354c3eb207Smrg // XXX: gcc complains when using constexpr here 2364c3eb207Smrg static const bool _S_store_size 2374c3eb207Smrg = _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _It>; 2384c3eb207Smrg 2394c3eb207Smrg _It _M_begin = _It(); 2404c3eb207Smrg _Sent _M_end = _Sent(); 2414c3eb207Smrg 2424c3eb207Smrg template<typename, bool = _S_store_size> 2434c3eb207Smrg struct _Size 2444c3eb207Smrg { }; 2454c3eb207Smrg 2464c3eb207Smrg template<typename _Tp> 2474c3eb207Smrg struct _Size<_Tp, true> 2484c3eb207Smrg { __detail::__make_unsigned_like_t<_Tp> _M_size; }; 2494c3eb207Smrg 2504c3eb207Smrg [[no_unique_address]] _Size<iter_difference_t<_It>> _M_size = {}; 2514c3eb207Smrg 2524c3eb207Smrg public: 2534c3eb207Smrg subrange() requires default_initializable<_It> = default; 2544c3eb207Smrg 2554c3eb207Smrg constexpr 2564c3eb207Smrg subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s) 2574c3eb207Smrg requires (!_S_store_size) 2584c3eb207Smrg : _M_begin(std::move(__i)), _M_end(__s) 2594c3eb207Smrg { } 2604c3eb207Smrg 2614c3eb207Smrg constexpr 2624c3eb207Smrg subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s, 2634c3eb207Smrg __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n) 2644c3eb207Smrg requires (_Kind == subrange_kind::sized) 2654c3eb207Smrg : _M_begin(std::move(__i)), _M_end(__s) 2664c3eb207Smrg { 2674c3eb207Smrg if constexpr (_S_store_size) 2684c3eb207Smrg _M_size._M_size = __n; 2694c3eb207Smrg } 2704c3eb207Smrg 2714c3eb207Smrg template<__detail::__not_same_as<subrange> _Rng> 2724c3eb207Smrg requires borrowed_range<_Rng> 2734c3eb207Smrg && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It> 2744c3eb207Smrg && convertible_to<sentinel_t<_Rng>, _Sent> 2754c3eb207Smrg constexpr 2764c3eb207Smrg subrange(_Rng&& __r) requires _S_store_size && sized_range<_Rng> 2774c3eb207Smrg : subrange(__r, ranges::size(__r)) 2784c3eb207Smrg { } 2794c3eb207Smrg 2804c3eb207Smrg template<__detail::__not_same_as<subrange> _Rng> 2814c3eb207Smrg requires borrowed_range<_Rng> 2824c3eb207Smrg && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It> 2834c3eb207Smrg && convertible_to<sentinel_t<_Rng>, _Sent> 2844c3eb207Smrg constexpr 2854c3eb207Smrg subrange(_Rng&& __r) requires (!_S_store_size) 2864c3eb207Smrg : subrange{ranges::begin(__r), ranges::end(__r)} 2874c3eb207Smrg { } 2884c3eb207Smrg 2894c3eb207Smrg template<borrowed_range _Rng> 2904c3eb207Smrg requires __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It> 2914c3eb207Smrg && convertible_to<sentinel_t<_Rng>, _Sent> 2924c3eb207Smrg constexpr 2934c3eb207Smrg subrange(_Rng&& __r, 2944c3eb207Smrg __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n) 2954c3eb207Smrg requires (_Kind == subrange_kind::sized) 2964c3eb207Smrg : subrange{ranges::begin(__r), ranges::end(__r), __n} 2974c3eb207Smrg { } 2984c3eb207Smrg 2994c3eb207Smrg template<__detail::__not_same_as<subrange> _PairLike> 3004c3eb207Smrg requires __detail::__pair_like_convertible_from<_PairLike, const _It&, 3014c3eb207Smrg const _Sent&> 3024c3eb207Smrg constexpr 3034c3eb207Smrg operator _PairLike() const 3044c3eb207Smrg { return _PairLike(_M_begin, _M_end); } 3054c3eb207Smrg 3064c3eb207Smrg constexpr _It 3074c3eb207Smrg begin() const requires copyable<_It> 3084c3eb207Smrg { return _M_begin; } 3094c3eb207Smrg 3104c3eb207Smrg [[nodiscard]] constexpr _It 3114c3eb207Smrg begin() requires (!copyable<_It>) 3124c3eb207Smrg { return std::move(_M_begin); } 3134c3eb207Smrg 3144c3eb207Smrg constexpr _Sent end() const { return _M_end; } 3154c3eb207Smrg 3164c3eb207Smrg constexpr bool empty() const { return _M_begin == _M_end; } 3174c3eb207Smrg 3184c3eb207Smrg constexpr __detail::__make_unsigned_like_t<iter_difference_t<_It>> 3194c3eb207Smrg size() const requires (_Kind == subrange_kind::sized) 3204c3eb207Smrg { 3214c3eb207Smrg if constexpr (_S_store_size) 3224c3eb207Smrg return _M_size._M_size; 3234c3eb207Smrg else 3244c3eb207Smrg return __detail::__to_unsigned_like(_M_end - _M_begin); 3254c3eb207Smrg } 3264c3eb207Smrg 3274c3eb207Smrg [[nodiscard]] constexpr subrange 3284c3eb207Smrg next(iter_difference_t<_It> __n = 1) const & 3294c3eb207Smrg requires forward_iterator<_It> 3304c3eb207Smrg { 3314c3eb207Smrg auto __tmp = *this; 3324c3eb207Smrg __tmp.advance(__n); 3334c3eb207Smrg return __tmp; 3344c3eb207Smrg } 3354c3eb207Smrg 3364c3eb207Smrg [[nodiscard]] constexpr subrange 3374c3eb207Smrg next(iter_difference_t<_It> __n = 1) && 3384c3eb207Smrg { 3394c3eb207Smrg advance(__n); 3404c3eb207Smrg return std::move(*this); 3414c3eb207Smrg } 3424c3eb207Smrg 3434c3eb207Smrg [[nodiscard]] constexpr subrange 3444c3eb207Smrg prev(iter_difference_t<_It> __n = 1) const 3454c3eb207Smrg requires bidirectional_iterator<_It> 3464c3eb207Smrg { 3474c3eb207Smrg auto __tmp = *this; 3484c3eb207Smrg __tmp.advance(-__n); 3494c3eb207Smrg return __tmp; 3504c3eb207Smrg } 3514c3eb207Smrg 3524c3eb207Smrg constexpr subrange& 3534c3eb207Smrg advance(iter_difference_t<_It> __n) 3544c3eb207Smrg { 3554c3eb207Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 3564c3eb207Smrg // 3433. subrange::advance(n) has UB when n < 0 3574c3eb207Smrg if constexpr (bidirectional_iterator<_It>) 3584c3eb207Smrg if (__n < 0) 3594c3eb207Smrg { 3604c3eb207Smrg ranges::advance(_M_begin, __n); 3614c3eb207Smrg if constexpr (_S_store_size) 3624c3eb207Smrg _M_size._M_size += __detail::__to_unsigned_like(-__n); 3634c3eb207Smrg return *this; 3644c3eb207Smrg } 3654c3eb207Smrg 3664c3eb207Smrg __glibcxx_assert(__n >= 0); 3674c3eb207Smrg auto __d = __n - ranges::advance(_M_begin, __n, _M_end); 3684c3eb207Smrg if constexpr (_S_store_size) 3694c3eb207Smrg _M_size._M_size -= __detail::__to_unsigned_like(__d); 3704c3eb207Smrg return *this; 3714c3eb207Smrg } 3724c3eb207Smrg }; 3734c3eb207Smrg 3744c3eb207Smrg template<input_or_output_iterator _It, sentinel_for<_It> _Sent> 3754c3eb207Smrg subrange(_It, _Sent) -> subrange<_It, _Sent>; 3764c3eb207Smrg 3774c3eb207Smrg template<input_or_output_iterator _It, sentinel_for<_It> _Sent> 3784c3eb207Smrg subrange(_It, _Sent, 3794c3eb207Smrg __detail::__make_unsigned_like_t<iter_difference_t<_It>>) 3804c3eb207Smrg -> subrange<_It, _Sent, subrange_kind::sized>; 3814c3eb207Smrg 3824c3eb207Smrg template<borrowed_range _Rng> 3834c3eb207Smrg subrange(_Rng&&) 3844c3eb207Smrg -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, 3854c3eb207Smrg (sized_range<_Rng> 3864c3eb207Smrg || sized_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>) 3874c3eb207Smrg ? subrange_kind::sized : subrange_kind::unsized>; 3884c3eb207Smrg 3894c3eb207Smrg template<borrowed_range _Rng> 3904c3eb207Smrg subrange(_Rng&&, 3914c3eb207Smrg __detail::__make_unsigned_like_t<range_difference_t<_Rng>>) 3924c3eb207Smrg -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, subrange_kind::sized>; 3934c3eb207Smrg 3944c3eb207Smrg template<size_t _Num, class _It, class _Sent, subrange_kind _Kind> 3954c3eb207Smrg requires (_Num < 2) 3964c3eb207Smrg constexpr auto 3974c3eb207Smrg get(const subrange<_It, _Sent, _Kind>& __r) 3984c3eb207Smrg { 3994c3eb207Smrg if constexpr (_Num == 0) 4004c3eb207Smrg return __r.begin(); 4014c3eb207Smrg else 4024c3eb207Smrg return __r.end(); 4034c3eb207Smrg } 4044c3eb207Smrg 4054c3eb207Smrg template<size_t _Num, class _It, class _Sent, subrange_kind _Kind> 4064c3eb207Smrg requires (_Num < 2) 4074c3eb207Smrg constexpr auto 4084c3eb207Smrg get(subrange<_It, _Sent, _Kind>&& __r) 4094c3eb207Smrg { 4104c3eb207Smrg if constexpr (_Num == 0) 4114c3eb207Smrg return __r.begin(); 4124c3eb207Smrg else 4134c3eb207Smrg return __r.end(); 4144c3eb207Smrg } 4154c3eb207Smrg 4164c3eb207Smrg template<input_or_output_iterator _It, sentinel_for<_It> _Sent, 4174c3eb207Smrg subrange_kind _Kind> 4184c3eb207Smrg inline constexpr bool 4194c3eb207Smrg enable_borrowed_range<subrange<_It, _Sent, _Kind>> = true; 4204c3eb207Smrg 4214c3eb207Smrg} // namespace ranges 4224c3eb207Smrg 4234c3eb207Smrg using ranges::get; 4244c3eb207Smrg 4254c3eb207Smrgnamespace ranges 4264c3eb207Smrg{ 4274c3eb207Smrg /// Type returned by algorithms instead of a dangling iterator or subrange. 4284c3eb207Smrg struct dangling 4294c3eb207Smrg { 4304c3eb207Smrg constexpr dangling() noexcept = default; 4314c3eb207Smrg template<typename... _Args> 4324c3eb207Smrg constexpr dangling(_Args&&...) noexcept { } 4334c3eb207Smrg }; 4344c3eb207Smrg 4354c3eb207Smrg template<range _Range> 4364c3eb207Smrg using borrowed_iterator_t = conditional_t<borrowed_range<_Range>, 4374c3eb207Smrg iterator_t<_Range>, 4384c3eb207Smrg dangling>; 4394c3eb207Smrg 4404c3eb207Smrg template<range _Range> 4414c3eb207Smrg using borrowed_subrange_t = conditional_t<borrowed_range<_Range>, 4424c3eb207Smrg subrange<iterator_t<_Range>>, 4434c3eb207Smrg dangling>; 4444c3eb207Smrg 4454c3eb207Smrg template<typename _Tp> requires is_object_v<_Tp> 4464c3eb207Smrg class empty_view 4474c3eb207Smrg : public view_interface<empty_view<_Tp>> 4484c3eb207Smrg { 4494c3eb207Smrg public: 4504c3eb207Smrg static constexpr _Tp* begin() noexcept { return nullptr; } 4514c3eb207Smrg static constexpr _Tp* end() noexcept { return nullptr; } 4524c3eb207Smrg static constexpr _Tp* data() noexcept { return nullptr; } 4534c3eb207Smrg static constexpr size_t size() noexcept { return 0; } 4544c3eb207Smrg static constexpr bool empty() noexcept { return true; } 4554c3eb207Smrg }; 4564c3eb207Smrg 4574c3eb207Smrg template<typename _Tp> 4584c3eb207Smrg inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true; 4594c3eb207Smrg 4604c3eb207Smrg namespace __detail 4614c3eb207Smrg { 4624c3eb207Smrg template<copy_constructible _Tp> requires is_object_v<_Tp> 4634c3eb207Smrg struct __box : std::optional<_Tp> 4644c3eb207Smrg { 4654c3eb207Smrg using std::optional<_Tp>::optional; 4664c3eb207Smrg 4674c3eb207Smrg constexpr 4684c3eb207Smrg __box() 4694c3eb207Smrg noexcept(is_nothrow_default_constructible_v<_Tp>) 4704c3eb207Smrg requires default_initializable<_Tp> 4714c3eb207Smrg : std::optional<_Tp>{std::in_place} 4724c3eb207Smrg { } 4734c3eb207Smrg 4744c3eb207Smrg __box(const __box&) = default; 4754c3eb207Smrg __box(__box&&) = default; 4764c3eb207Smrg 4774c3eb207Smrg using std::optional<_Tp>::operator=; 4784c3eb207Smrg 4794c3eb207Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 4804c3eb207Smrg // 3477. Simplify constraints for semiregular-box 4814c3eb207Smrg __box& 4824c3eb207Smrg operator=(const __box& __that) 4834c3eb207Smrg noexcept(is_nothrow_copy_constructible_v<_Tp>) 4844c3eb207Smrg requires (!copyable<_Tp>) 4854c3eb207Smrg { 4864c3eb207Smrg if (this != std::__addressof(__that)) 4874c3eb207Smrg { 4884c3eb207Smrg if ((bool)__that) 4894c3eb207Smrg this->emplace(*__that); 4904c3eb207Smrg else 4914c3eb207Smrg this->reset(); 4924c3eb207Smrg } 4934c3eb207Smrg return *this; 4944c3eb207Smrg } 4954c3eb207Smrg 4964c3eb207Smrg __box& 4974c3eb207Smrg operator=(__box&& __that) 4984c3eb207Smrg noexcept(is_nothrow_move_constructible_v<_Tp>) 4994c3eb207Smrg requires (!movable<_Tp>) 5004c3eb207Smrg { 5014c3eb207Smrg if (this != std::__addressof(__that)) 5024c3eb207Smrg { 5034c3eb207Smrg if ((bool)__that) 5044c3eb207Smrg this->emplace(std::move(*__that)); 5054c3eb207Smrg else 5064c3eb207Smrg this->reset(); 5074c3eb207Smrg } 5084c3eb207Smrg return *this; 5094c3eb207Smrg } 5104c3eb207Smrg }; 5114c3eb207Smrg 5124c3eb207Smrg } // namespace __detail 5134c3eb207Smrg 5144c3eb207Smrg /// A view that contains exactly one element. 5154c3eb207Smrg template<copy_constructible _Tp> requires is_object_v<_Tp> 5164c3eb207Smrg class single_view : public view_interface<single_view<_Tp>> 5174c3eb207Smrg { 5184c3eb207Smrg public: 519*4ac76180Smrg single_view() = default; 5204c3eb207Smrg 5214c3eb207Smrg constexpr explicit 5224c3eb207Smrg single_view(const _Tp& __t) 5234c3eb207Smrg : _M_value(__t) 5244c3eb207Smrg { } 5254c3eb207Smrg 5264c3eb207Smrg constexpr explicit 5274c3eb207Smrg single_view(_Tp&& __t) 5284c3eb207Smrg : _M_value(std::move(__t)) 5294c3eb207Smrg { } 5304c3eb207Smrg 5314c3eb207Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 5324c3eb207Smrg // 3428. single_view's in place constructor should be explicit 5334c3eb207Smrg template<typename... _Args> 5344c3eb207Smrg requires constructible_from<_Tp, _Args...> 5354c3eb207Smrg constexpr explicit 5364c3eb207Smrg single_view(in_place_t, _Args&&... __args) 5374c3eb207Smrg : _M_value{in_place, std::forward<_Args>(__args)...} 5384c3eb207Smrg { } 5394c3eb207Smrg 5404c3eb207Smrg constexpr _Tp* 5414c3eb207Smrg begin() noexcept 5424c3eb207Smrg { return data(); } 5434c3eb207Smrg 5444c3eb207Smrg constexpr const _Tp* 5454c3eb207Smrg begin() const noexcept 5464c3eb207Smrg { return data(); } 5474c3eb207Smrg 5484c3eb207Smrg constexpr _Tp* 5494c3eb207Smrg end() noexcept 5504c3eb207Smrg { return data() + 1; } 5514c3eb207Smrg 5524c3eb207Smrg constexpr const _Tp* 5534c3eb207Smrg end() const noexcept 5544c3eb207Smrg { return data() + 1; } 5554c3eb207Smrg 5564c3eb207Smrg static constexpr size_t 5574c3eb207Smrg size() noexcept 5584c3eb207Smrg { return 1; } 5594c3eb207Smrg 5604c3eb207Smrg constexpr _Tp* 5614c3eb207Smrg data() noexcept 5624c3eb207Smrg { return _M_value.operator->(); } 5634c3eb207Smrg 5644c3eb207Smrg constexpr const _Tp* 5654c3eb207Smrg data() const noexcept 5664c3eb207Smrg { return _M_value.operator->(); } 5674c3eb207Smrg 5684c3eb207Smrg private: 5694c3eb207Smrg __detail::__box<_Tp> _M_value; 5704c3eb207Smrg }; 5714c3eb207Smrg 5724c3eb207Smrg namespace __detail 5734c3eb207Smrg { 5744c3eb207Smrg template<typename _Wp> 5754c3eb207Smrg constexpr auto __to_signed_like(_Wp __w) noexcept 5764c3eb207Smrg { 5774c3eb207Smrg if constexpr (!integral<_Wp>) 5784c3eb207Smrg return iter_difference_t<_Wp>(); 5794c3eb207Smrg else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp)) 5804c3eb207Smrg return iter_difference_t<_Wp>(__w); 5814c3eb207Smrg else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp)) 5824c3eb207Smrg return ptrdiff_t(__w); 5834c3eb207Smrg else if constexpr (sizeof(long long) > sizeof(_Wp)) 5844c3eb207Smrg return (long long)(__w); 5854c3eb207Smrg#ifdef __SIZEOF_INT128__ 5864c3eb207Smrg else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp)) 5874c3eb207Smrg return __int128(__w); 5884c3eb207Smrg#endif 5894c3eb207Smrg else 5904c3eb207Smrg return __max_diff_type(__w); 5914c3eb207Smrg } 5924c3eb207Smrg 5934c3eb207Smrg template<typename _Wp> 5944c3eb207Smrg using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>())); 5954c3eb207Smrg 5964c3eb207Smrg template<typename _It> 5974c3eb207Smrg concept __decrementable = incrementable<_It> 5984c3eb207Smrg && requires(_It __i) 5994c3eb207Smrg { 6004c3eb207Smrg { --__i } -> same_as<_It&>; 6014c3eb207Smrg { __i-- } -> same_as<_It>; 6024c3eb207Smrg }; 6034c3eb207Smrg 6044c3eb207Smrg template<typename _It> 6054c3eb207Smrg concept __advanceable = __decrementable<_It> && totally_ordered<_It> 6064c3eb207Smrg && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n) 6074c3eb207Smrg { 6084c3eb207Smrg { __i += __n } -> same_as<_It&>; 6094c3eb207Smrg { __i -= __n } -> same_as<_It&>; 6104c3eb207Smrg _It(__j + __n); 6114c3eb207Smrg _It(__n + __j); 6124c3eb207Smrg _It(__j - __n); 6134c3eb207Smrg { __j - __j } -> convertible_to<__iota_diff_t<_It>>; 6144c3eb207Smrg }; 6154c3eb207Smrg 6164c3eb207Smrg template<typename _Winc> 6174c3eb207Smrg struct __iota_view_iter_cat 6184c3eb207Smrg { }; 6194c3eb207Smrg 6204c3eb207Smrg template<incrementable _Winc> 6214c3eb207Smrg struct __iota_view_iter_cat<_Winc> 6224c3eb207Smrg { using iterator_category = input_iterator_tag; }; 6234c3eb207Smrg } // namespace __detail 6244c3eb207Smrg 6254c3eb207Smrg template<weakly_incrementable _Winc, 6264c3eb207Smrg semiregular _Bound = unreachable_sentinel_t> 6274c3eb207Smrg requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound> 6284c3eb207Smrg && copyable<_Winc> 6294c3eb207Smrg class iota_view : public view_interface<iota_view<_Winc, _Bound>> 6304c3eb207Smrg { 6314c3eb207Smrg private: 6324c3eb207Smrg struct _Sentinel; 6334c3eb207Smrg 6344c3eb207Smrg struct _Iterator : __detail::__iota_view_iter_cat<_Winc> 6354c3eb207Smrg { 6364c3eb207Smrg private: 6374c3eb207Smrg static auto 6384c3eb207Smrg _S_iter_concept() 6394c3eb207Smrg { 6404c3eb207Smrg using namespace __detail; 6414c3eb207Smrg if constexpr (__advanceable<_Winc>) 6424c3eb207Smrg return random_access_iterator_tag{}; 6434c3eb207Smrg else if constexpr (__decrementable<_Winc>) 6444c3eb207Smrg return bidirectional_iterator_tag{}; 6454c3eb207Smrg else if constexpr (incrementable<_Winc>) 6464c3eb207Smrg return forward_iterator_tag{}; 6474c3eb207Smrg else 6484c3eb207Smrg return input_iterator_tag{}; 6494c3eb207Smrg } 6504c3eb207Smrg 6514c3eb207Smrg public: 6524c3eb207Smrg using iterator_concept = decltype(_S_iter_concept()); 6534c3eb207Smrg // iterator_category defined in __iota_view_iter_cat 6544c3eb207Smrg using value_type = _Winc; 6554c3eb207Smrg using difference_type = __detail::__iota_diff_t<_Winc>; 6564c3eb207Smrg 6574c3eb207Smrg _Iterator() requires default_initializable<_Winc> = default; 6584c3eb207Smrg 6594c3eb207Smrg constexpr explicit 6604c3eb207Smrg _Iterator(_Winc __value) 6614c3eb207Smrg : _M_value(__value) { } 6624c3eb207Smrg 6634c3eb207Smrg constexpr _Winc 6644c3eb207Smrg operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>) 6654c3eb207Smrg { return _M_value; } 6664c3eb207Smrg 6674c3eb207Smrg constexpr _Iterator& 6684c3eb207Smrg operator++() 6694c3eb207Smrg { 6704c3eb207Smrg ++_M_value; 6714c3eb207Smrg return *this; 6724c3eb207Smrg } 6734c3eb207Smrg 6744c3eb207Smrg constexpr void 6754c3eb207Smrg operator++(int) 6764c3eb207Smrg { ++*this; } 6774c3eb207Smrg 6784c3eb207Smrg constexpr _Iterator 6794c3eb207Smrg operator++(int) requires incrementable<_Winc> 6804c3eb207Smrg { 6814c3eb207Smrg auto __tmp = *this; 6824c3eb207Smrg ++*this; 6834c3eb207Smrg return __tmp; 6844c3eb207Smrg } 6854c3eb207Smrg 6864c3eb207Smrg constexpr _Iterator& 6874c3eb207Smrg operator--() requires __detail::__decrementable<_Winc> 6884c3eb207Smrg { 6894c3eb207Smrg --_M_value; 6904c3eb207Smrg return *this; 6914c3eb207Smrg } 6924c3eb207Smrg 6934c3eb207Smrg constexpr _Iterator 6944c3eb207Smrg operator--(int) requires __detail::__decrementable<_Winc> 6954c3eb207Smrg { 6964c3eb207Smrg auto __tmp = *this; 6974c3eb207Smrg --*this; 6984c3eb207Smrg return __tmp; 6994c3eb207Smrg } 7004c3eb207Smrg 7014c3eb207Smrg constexpr _Iterator& 7024c3eb207Smrg operator+=(difference_type __n) requires __detail::__advanceable<_Winc> 7034c3eb207Smrg { 7044c3eb207Smrg using __detail::__is_integer_like; 7054c3eb207Smrg using __detail::__is_signed_integer_like; 7064c3eb207Smrg if constexpr (__is_integer_like<_Winc> 7074c3eb207Smrg && !__is_signed_integer_like<_Winc>) 7084c3eb207Smrg { 7094c3eb207Smrg if (__n >= difference_type(0)) 7104c3eb207Smrg _M_value += static_cast<_Winc>(__n); 7114c3eb207Smrg else 7124c3eb207Smrg _M_value -= static_cast<_Winc>(-__n); 7134c3eb207Smrg } 7144c3eb207Smrg else 7154c3eb207Smrg _M_value += __n; 7164c3eb207Smrg return *this; 7174c3eb207Smrg } 7184c3eb207Smrg 7194c3eb207Smrg constexpr _Iterator& 7204c3eb207Smrg operator-=(difference_type __n) requires __detail::__advanceable<_Winc> 7214c3eb207Smrg { 7224c3eb207Smrg using __detail::__is_integer_like; 7234c3eb207Smrg using __detail::__is_signed_integer_like; 7244c3eb207Smrg if constexpr (__is_integer_like<_Winc> 7254c3eb207Smrg && !__is_signed_integer_like<_Winc>) 7264c3eb207Smrg { 7274c3eb207Smrg if (__n >= difference_type(0)) 7284c3eb207Smrg _M_value -= static_cast<_Winc>(__n); 7294c3eb207Smrg else 7304c3eb207Smrg _M_value += static_cast<_Winc>(-__n); 7314c3eb207Smrg } 7324c3eb207Smrg else 7334c3eb207Smrg _M_value -= __n; 7344c3eb207Smrg return *this; 7354c3eb207Smrg } 7364c3eb207Smrg 7374c3eb207Smrg constexpr _Winc 7384c3eb207Smrg operator[](difference_type __n) const 7394c3eb207Smrg requires __detail::__advanceable<_Winc> 7404c3eb207Smrg { return _Winc(_M_value + __n); } 7414c3eb207Smrg 7424c3eb207Smrg friend constexpr bool 7434c3eb207Smrg operator==(const _Iterator& __x, const _Iterator& __y) 7444c3eb207Smrg requires equality_comparable<_Winc> 7454c3eb207Smrg { return __x._M_value == __y._M_value; } 7464c3eb207Smrg 7474c3eb207Smrg friend constexpr bool 7484c3eb207Smrg operator<(const _Iterator& __x, const _Iterator& __y) 7494c3eb207Smrg requires totally_ordered<_Winc> 7504c3eb207Smrg { return __x._M_value < __y._M_value; } 7514c3eb207Smrg 7524c3eb207Smrg friend constexpr bool 7534c3eb207Smrg operator>(const _Iterator& __x, const _Iterator& __y) 7544c3eb207Smrg requires totally_ordered<_Winc> 7554c3eb207Smrg { return __y < __x; } 7564c3eb207Smrg 7574c3eb207Smrg friend constexpr bool 7584c3eb207Smrg operator<=(const _Iterator& __x, const _Iterator& __y) 7594c3eb207Smrg requires totally_ordered<_Winc> 7604c3eb207Smrg { return !(__y < __x); } 7614c3eb207Smrg 7624c3eb207Smrg friend constexpr bool 7634c3eb207Smrg operator>=(const _Iterator& __x, const _Iterator& __y) 7644c3eb207Smrg requires totally_ordered<_Winc> 7654c3eb207Smrg { return !(__x < __y); } 7664c3eb207Smrg 7674c3eb207Smrg#ifdef __cpp_lib_three_way_comparison 7684c3eb207Smrg friend constexpr auto 7694c3eb207Smrg operator<=>(const _Iterator& __x, const _Iterator& __y) 7704c3eb207Smrg requires totally_ordered<_Winc> && three_way_comparable<_Winc> 7714c3eb207Smrg { return __x._M_value <=> __y._M_value; } 7724c3eb207Smrg#endif 7734c3eb207Smrg 7744c3eb207Smrg friend constexpr _Iterator 7754c3eb207Smrg operator+(_Iterator __i, difference_type __n) 7764c3eb207Smrg requires __detail::__advanceable<_Winc> 7774c3eb207Smrg { return __i += __n; } 7784c3eb207Smrg 7794c3eb207Smrg friend constexpr _Iterator 7804c3eb207Smrg operator+(difference_type __n, _Iterator __i) 7814c3eb207Smrg requires __detail::__advanceable<_Winc> 7824c3eb207Smrg { return __i += __n; } 7834c3eb207Smrg 7844c3eb207Smrg friend constexpr _Iterator 7854c3eb207Smrg operator-(_Iterator __i, difference_type __n) 7864c3eb207Smrg requires __detail::__advanceable<_Winc> 7874c3eb207Smrg { return __i -= __n; } 7884c3eb207Smrg 7894c3eb207Smrg friend constexpr difference_type 7904c3eb207Smrg operator-(const _Iterator& __x, const _Iterator& __y) 7914c3eb207Smrg requires __detail::__advanceable<_Winc> 7924c3eb207Smrg { 7934c3eb207Smrg using __detail::__is_integer_like; 7944c3eb207Smrg using __detail::__is_signed_integer_like; 7954c3eb207Smrg using _Dt = difference_type; 7964c3eb207Smrg if constexpr (__is_integer_like<_Winc>) 7974c3eb207Smrg { 7984c3eb207Smrg if constexpr (__is_signed_integer_like<_Winc>) 7994c3eb207Smrg return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value)); 8004c3eb207Smrg else 8014c3eb207Smrg return (__y._M_value > __x._M_value) 8024c3eb207Smrg ? _Dt(-_Dt(__y._M_value - __x._M_value)) 8034c3eb207Smrg : _Dt(__x._M_value - __y._M_value); 8044c3eb207Smrg } 8054c3eb207Smrg else 8064c3eb207Smrg return __x._M_value - __y._M_value; 8074c3eb207Smrg } 8084c3eb207Smrg 8094c3eb207Smrg private: 8104c3eb207Smrg _Winc _M_value = _Winc(); 8114c3eb207Smrg 8124c3eb207Smrg friend _Sentinel; 8134c3eb207Smrg }; 8144c3eb207Smrg 8154c3eb207Smrg struct _Sentinel 8164c3eb207Smrg { 8174c3eb207Smrg private: 8184c3eb207Smrg constexpr bool 8194c3eb207Smrg _M_equal(const _Iterator& __x) const 8204c3eb207Smrg { return __x._M_value == _M_bound; } 8214c3eb207Smrg 8224c3eb207Smrg constexpr auto 8234c3eb207Smrg _M_distance_from(const _Iterator& __x) const 8244c3eb207Smrg { return _M_bound - __x._M_value; } 8254c3eb207Smrg 8264c3eb207Smrg _Bound _M_bound = _Bound(); 8274c3eb207Smrg 8284c3eb207Smrg public: 8294c3eb207Smrg _Sentinel() = default; 8304c3eb207Smrg 8314c3eb207Smrg constexpr explicit 8324c3eb207Smrg _Sentinel(_Bound __bound) 8334c3eb207Smrg : _M_bound(__bound) { } 8344c3eb207Smrg 8354c3eb207Smrg friend constexpr bool 8364c3eb207Smrg operator==(const _Iterator& __x, const _Sentinel& __y) 8374c3eb207Smrg { return __y._M_equal(__x); } 8384c3eb207Smrg 8394c3eb207Smrg friend constexpr iter_difference_t<_Winc> 8404c3eb207Smrg operator-(const _Iterator& __x, const _Sentinel& __y) 8414c3eb207Smrg requires sized_sentinel_for<_Bound, _Winc> 8424c3eb207Smrg { return -__y._M_distance_from(__x); } 8434c3eb207Smrg 8444c3eb207Smrg friend constexpr iter_difference_t<_Winc> 8454c3eb207Smrg operator-(const _Sentinel& __x, const _Iterator& __y) 8464c3eb207Smrg requires sized_sentinel_for<_Bound, _Winc> 8474c3eb207Smrg { return __x._M_distance_from(__y); } 8484c3eb207Smrg }; 8494c3eb207Smrg 8504c3eb207Smrg _Winc _M_value = _Winc(); 8514c3eb207Smrg _Bound _M_bound = _Bound(); 8524c3eb207Smrg 8534c3eb207Smrg public: 8544c3eb207Smrg iota_view() requires default_initializable<_Winc> = default; 8554c3eb207Smrg 8564c3eb207Smrg constexpr explicit 8574c3eb207Smrg iota_view(_Winc __value) 8584c3eb207Smrg : _M_value(__value) 8594c3eb207Smrg { } 8604c3eb207Smrg 8614c3eb207Smrg constexpr 8624c3eb207Smrg iota_view(type_identity_t<_Winc> __value, 8634c3eb207Smrg type_identity_t<_Bound> __bound) 8644c3eb207Smrg : _M_value(__value), _M_bound(__bound) 8654c3eb207Smrg { 8664c3eb207Smrg if constexpr (totally_ordered_with<_Winc, _Bound>) 8674c3eb207Smrg { 8684c3eb207Smrg __glibcxx_assert( bool(__value <= __bound) ); 8694c3eb207Smrg } 8704c3eb207Smrg } 8714c3eb207Smrg 8724c3eb207Smrg constexpr _Iterator 8734c3eb207Smrg begin() const { return _Iterator{_M_value}; } 8744c3eb207Smrg 8754c3eb207Smrg constexpr auto 8764c3eb207Smrg end() const 8774c3eb207Smrg { 8784c3eb207Smrg if constexpr (same_as<_Bound, unreachable_sentinel_t>) 8794c3eb207Smrg return unreachable_sentinel; 8804c3eb207Smrg else 8814c3eb207Smrg return _Sentinel{_M_bound}; 8824c3eb207Smrg } 8834c3eb207Smrg 8844c3eb207Smrg constexpr _Iterator 8854c3eb207Smrg end() const requires same_as<_Winc, _Bound> 8864c3eb207Smrg { return _Iterator{_M_bound}; } 8874c3eb207Smrg 8884c3eb207Smrg constexpr auto 8894c3eb207Smrg size() const 8904c3eb207Smrg requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>) 8914c3eb207Smrg || (integral<_Winc> && integral<_Bound>) 8924c3eb207Smrg || sized_sentinel_for<_Bound, _Winc> 8934c3eb207Smrg { 8944c3eb207Smrg using __detail::__is_integer_like; 8954c3eb207Smrg using __detail::__to_unsigned_like; 8964c3eb207Smrg if constexpr (integral<_Winc> && integral<_Bound>) 8974c3eb207Smrg { 8984c3eb207Smrg using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>; 8994c3eb207Smrg return _Up(_M_bound) - _Up(_M_value); 9004c3eb207Smrg } 9014c3eb207Smrg else if constexpr (__is_integer_like<_Winc>) 9024c3eb207Smrg return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value); 9034c3eb207Smrg else 9044c3eb207Smrg return __to_unsigned_like(_M_bound - _M_value); 9054c3eb207Smrg } 9064c3eb207Smrg }; 9074c3eb207Smrg 9084c3eb207Smrg template<typename _Winc, typename _Bound> 9094c3eb207Smrg requires (!__detail::__is_integer_like<_Winc> 9104c3eb207Smrg || !__detail::__is_integer_like<_Bound> 9114c3eb207Smrg || (__detail::__is_signed_integer_like<_Winc> 9124c3eb207Smrg == __detail::__is_signed_integer_like<_Bound>)) 9134c3eb207Smrg iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>; 9144c3eb207Smrg 9154c3eb207Smrg template<weakly_incrementable _Winc, semiregular _Bound> 9164c3eb207Smrg inline constexpr bool 9174c3eb207Smrg enable_borrowed_range<iota_view<_Winc, _Bound>> = true; 9184c3eb207Smrg 9194c3eb207Smrgnamespace views 9204c3eb207Smrg{ 9214c3eb207Smrg template<typename _Tp> 9224c3eb207Smrg inline constexpr empty_view<_Tp> empty{}; 9234c3eb207Smrg 9244c3eb207Smrg struct _Single 9254c3eb207Smrg { 9264c3eb207Smrg template<typename _Tp> 9274c3eb207Smrg constexpr auto 9284c3eb207Smrg operator()(_Tp&& __e) const 9294c3eb207Smrg { return single_view{std::forward<_Tp>(__e)}; } 9304c3eb207Smrg }; 9314c3eb207Smrg 9324c3eb207Smrg inline constexpr _Single single{}; 9334c3eb207Smrg 9344c3eb207Smrg struct _Iota 9354c3eb207Smrg { 9364c3eb207Smrg template<typename _Tp> 9374c3eb207Smrg constexpr auto 9384c3eb207Smrg operator()(_Tp&& __e) const 9394c3eb207Smrg { return iota_view{std::forward<_Tp>(__e)}; } 9404c3eb207Smrg 9414c3eb207Smrg template<typename _Tp, typename _Up> 9424c3eb207Smrg constexpr auto 9434c3eb207Smrg operator()(_Tp&& __e, _Up&& __f) const 9444c3eb207Smrg { return iota_view{std::forward<_Tp>(__e), std::forward<_Up>(__f)}; } 9454c3eb207Smrg }; 9464c3eb207Smrg 9474c3eb207Smrg inline constexpr _Iota iota{}; 9484c3eb207Smrg} // namespace views 9494c3eb207Smrg 9504c3eb207Smrg namespace __detail 9514c3eb207Smrg { 9524c3eb207Smrg template<typename _Val, typename _CharT, typename _Traits> 9534c3eb207Smrg concept __stream_extractable 9544c3eb207Smrg = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; }; 9554c3eb207Smrg } // namespace __detail 9564c3eb207Smrg 9574c3eb207Smrg template<movable _Val, typename _CharT, 9584c3eb207Smrg typename _Traits = char_traits<_CharT>> 9594c3eb207Smrg requires default_initializable<_Val> 9604c3eb207Smrg && __detail::__stream_extractable<_Val, _CharT, _Traits> 9614c3eb207Smrg class basic_istream_view 9624c3eb207Smrg : public view_interface<basic_istream_view<_Val, _CharT, _Traits>> 9634c3eb207Smrg { 9644c3eb207Smrg public: 9654c3eb207Smrg basic_istream_view() = default; 9664c3eb207Smrg 9674c3eb207Smrg constexpr explicit 9684c3eb207Smrg basic_istream_view(basic_istream<_CharT, _Traits>& __stream) 9694c3eb207Smrg : _M_stream(std::__addressof(__stream)) 9704c3eb207Smrg { } 9714c3eb207Smrg 9724c3eb207Smrg constexpr auto 9734c3eb207Smrg begin() 9744c3eb207Smrg { 9754c3eb207Smrg if (_M_stream != nullptr) 9764c3eb207Smrg *_M_stream >> _M_object; 9774c3eb207Smrg return _Iterator{this}; 9784c3eb207Smrg } 9794c3eb207Smrg 9804c3eb207Smrg constexpr default_sentinel_t 9814c3eb207Smrg end() const noexcept 9824c3eb207Smrg { return default_sentinel; } 9834c3eb207Smrg 9844c3eb207Smrg private: 9854c3eb207Smrg basic_istream<_CharT, _Traits>* _M_stream = nullptr; 9864c3eb207Smrg _Val _M_object = _Val(); 9874c3eb207Smrg 9884c3eb207Smrg struct _Iterator 9894c3eb207Smrg { 9904c3eb207Smrg public: 9914c3eb207Smrg using iterator_concept = input_iterator_tag; 9924c3eb207Smrg using difference_type = ptrdiff_t; 9934c3eb207Smrg using value_type = _Val; 9944c3eb207Smrg 9954c3eb207Smrg _Iterator() = default; 9964c3eb207Smrg 9974c3eb207Smrg constexpr explicit 9984c3eb207Smrg _Iterator(basic_istream_view* __parent) noexcept 9994c3eb207Smrg : _M_parent(__parent) 10004c3eb207Smrg { } 10014c3eb207Smrg 10024c3eb207Smrg _Iterator(const _Iterator&) = delete; 10034c3eb207Smrg _Iterator(_Iterator&&) = default; 10044c3eb207Smrg _Iterator& operator=(const _Iterator&) = delete; 10054c3eb207Smrg _Iterator& operator=(_Iterator&&) = default; 10064c3eb207Smrg 10074c3eb207Smrg _Iterator& 10084c3eb207Smrg operator++() 10094c3eb207Smrg { 10104c3eb207Smrg __glibcxx_assert(_M_parent->_M_stream != nullptr); 10114c3eb207Smrg *_M_parent->_M_stream >> _M_parent->_M_object; 10124c3eb207Smrg return *this; 10134c3eb207Smrg } 10144c3eb207Smrg 10154c3eb207Smrg void 10164c3eb207Smrg operator++(int) 10174c3eb207Smrg { ++*this; } 10184c3eb207Smrg 10194c3eb207Smrg _Val& 10204c3eb207Smrg operator*() const 10214c3eb207Smrg { 10224c3eb207Smrg __glibcxx_assert(_M_parent->_M_stream != nullptr); 10234c3eb207Smrg return _M_parent->_M_object; 10244c3eb207Smrg } 10254c3eb207Smrg 10264c3eb207Smrg friend bool 10274c3eb207Smrg operator==(const _Iterator& __x, default_sentinel_t) 10284c3eb207Smrg { return __x._M_at_end(); } 10294c3eb207Smrg 10304c3eb207Smrg private: 10314c3eb207Smrg basic_istream_view* _M_parent = nullptr; 10324c3eb207Smrg 10334c3eb207Smrg bool 10344c3eb207Smrg _M_at_end() const 10354c3eb207Smrg { return _M_parent == nullptr || !*_M_parent->_M_stream; } 10364c3eb207Smrg }; 10374c3eb207Smrg 10384c3eb207Smrg friend _Iterator; 10394c3eb207Smrg }; 10404c3eb207Smrg 10414c3eb207Smrg template<typename _Val, typename _CharT, typename _Traits> 10424c3eb207Smrg basic_istream_view<_Val, _CharT, _Traits> 10434c3eb207Smrg istream_view(basic_istream<_CharT, _Traits>& __s) 10444c3eb207Smrg { return basic_istream_view<_Val, _CharT, _Traits>{__s}; } 10454c3eb207Smrg 10464c3eb207Smrgnamespace __detail 10474c3eb207Smrg{ 10484c3eb207Smrg struct _Empty { }; 10494c3eb207Smrg 10504c3eb207Smrg // Alias for a type that is conditionally present 10514c3eb207Smrg // (and is an empty type otherwise). 10524c3eb207Smrg // Data members using this alias should use [[no_unique_address]] so that 10534c3eb207Smrg // they take no space when not needed. 10544c3eb207Smrg template<bool _Present, typename _Tp> 10554c3eb207Smrg using __maybe_present_t = conditional_t<_Present, _Tp, _Empty>; 10564c3eb207Smrg 10574c3eb207Smrg // Alias for a type that is conditionally const. 10584c3eb207Smrg template<bool _Const, typename _Tp> 10594c3eb207Smrg using __maybe_const_t = conditional_t<_Const, const _Tp, _Tp>; 10604c3eb207Smrg 10614c3eb207Smrg} // namespace __detail 10624c3eb207Smrg 10634c3eb207Smrgnamespace views 10644c3eb207Smrg{ 10654c3eb207Smrg namespace __adaptor 10664c3eb207Smrg { 10674c3eb207Smrg template<typename _Tp> 10684c3eb207Smrg inline constexpr auto 10694c3eb207Smrg __maybe_refwrap(_Tp& __arg) 10704c3eb207Smrg { return reference_wrapper<_Tp>{__arg}; } 10714c3eb207Smrg 10724c3eb207Smrg template<typename _Tp> 10734c3eb207Smrg inline constexpr auto 10744c3eb207Smrg __maybe_refwrap(const _Tp& __arg) 10754c3eb207Smrg { return reference_wrapper<const _Tp>{__arg}; } 10764c3eb207Smrg 10774c3eb207Smrg template<typename _Tp> 10784c3eb207Smrg inline constexpr decltype(auto) 10794c3eb207Smrg __maybe_refwrap(_Tp&& __arg) 10804c3eb207Smrg { return std::forward<_Tp>(__arg); } 10814c3eb207Smrg 10824c3eb207Smrg template<typename _Callable> 10834c3eb207Smrg struct _RangeAdaptorClosure; 10844c3eb207Smrg 10854c3eb207Smrg template<typename _Callable> 10864c3eb207Smrg struct _RangeAdaptor 10874c3eb207Smrg { 10884c3eb207Smrg protected: 10894c3eb207Smrg [[no_unique_address]] 10904c3eb207Smrg __detail::__maybe_present_t<!is_default_constructible_v<_Callable>, 10914c3eb207Smrg _Callable> _M_callable; 10924c3eb207Smrg 10934c3eb207Smrg public: 10944c3eb207Smrg constexpr 10954c3eb207Smrg _RangeAdaptor(const _Callable& = {}) 10964c3eb207Smrg requires is_default_constructible_v<_Callable> 10974c3eb207Smrg { } 10984c3eb207Smrg 10994c3eb207Smrg constexpr 11004c3eb207Smrg _RangeAdaptor(_Callable __callable) 11014c3eb207Smrg requires (!is_default_constructible_v<_Callable>) 11024c3eb207Smrg : _M_callable(std::move(__callable)) 11034c3eb207Smrg { } 11044c3eb207Smrg 11054c3eb207Smrg template<typename... _Args> 11064c3eb207Smrg requires (sizeof...(_Args) >= 1) 11074c3eb207Smrg constexpr auto 11084c3eb207Smrg operator()(_Args&&... __args) const 11094c3eb207Smrg { 11104c3eb207Smrg // [range.adaptor.object]: If a range adaptor object accepts more 11114c3eb207Smrg // than one argument, then the following expressions are equivalent: 11124c3eb207Smrg // 11134c3eb207Smrg // (1) adaptor(range, args...) 11144c3eb207Smrg // (2) adaptor(args...)(range) 11154c3eb207Smrg // (3) range | adaptor(args...) 11164c3eb207Smrg // 11174c3eb207Smrg // In this case, adaptor(args...) is a range adaptor closure object. 11184c3eb207Smrg // 11194c3eb207Smrg // We handle (1) and (2) here, and (3) is just a special case of a 11204c3eb207Smrg // more general case already handled by _RangeAdaptorClosure. 11214c3eb207Smrg if constexpr (is_invocable_v<_Callable, _Args...>) 11224c3eb207Smrg { 11234c3eb207Smrg static_assert(sizeof...(_Args) != 1, 11244c3eb207Smrg "a _RangeAdaptor that accepts only one argument " 11254c3eb207Smrg "should be defined as a _RangeAdaptorClosure"); 11264c3eb207Smrg // Here we handle adaptor(range, args...) -- just forward all 11274c3eb207Smrg // arguments to the underlying adaptor routine. 11284c3eb207Smrg return _Callable{}(std::forward<_Args>(__args)...); 11294c3eb207Smrg } 11304c3eb207Smrg else 11314c3eb207Smrg { 11324c3eb207Smrg // Here we handle adaptor(args...)(range). 11334c3eb207Smrg // Given args..., we return a _RangeAdaptorClosure that takes a 11344c3eb207Smrg // range argument, such that (2) is equivalent to (1). 11354c3eb207Smrg // 11364c3eb207Smrg // We need to be careful about how we capture args... in this 11374c3eb207Smrg // closure. By using __maybe_refwrap, we capture lvalue 11384c3eb207Smrg // references by reference (through a reference_wrapper) and 11394c3eb207Smrg // otherwise capture by value. 11404c3eb207Smrg auto __closure 11414c3eb207Smrg = [...__args(__maybe_refwrap(std::forward<_Args>(__args)))] 11424c3eb207Smrg <typename _Range> (_Range&& __r) { 11434c3eb207Smrg // This static_cast has two purposes: it forwards a 11444c3eb207Smrg // reference_wrapper<T> capture as a T&, and otherwise 11454c3eb207Smrg // forwards the captured argument as an rvalue. 11464c3eb207Smrg return _Callable{}(std::forward<_Range>(__r), 11474c3eb207Smrg (static_cast<unwrap_reference_t 11484c3eb207Smrg <remove_const_t<decltype(__args)>>> 11494c3eb207Smrg (__args))...); 11504c3eb207Smrg }; 11514c3eb207Smrg using _ClosureType = decltype(__closure); 11524c3eb207Smrg return _RangeAdaptorClosure<_ClosureType>(std::move(__closure)); 11534c3eb207Smrg } 11544c3eb207Smrg } 11554c3eb207Smrg }; 11564c3eb207Smrg 11574c3eb207Smrg template<typename _Callable> 11584c3eb207Smrg _RangeAdaptor(_Callable) -> _RangeAdaptor<_Callable>; 11594c3eb207Smrg 11604c3eb207Smrg template<typename _Callable> 11614c3eb207Smrg struct _RangeAdaptorClosure : public _RangeAdaptor<_Callable> 11624c3eb207Smrg { 11634c3eb207Smrg using _RangeAdaptor<_Callable>::_RangeAdaptor; 11644c3eb207Smrg 11654c3eb207Smrg template<viewable_range _Range> 11664c3eb207Smrg requires requires { declval<_Callable>()(declval<_Range>()); } 11674c3eb207Smrg constexpr auto 11684c3eb207Smrg operator()(_Range&& __r) const 11694c3eb207Smrg { 11704c3eb207Smrg if constexpr (is_default_constructible_v<_Callable>) 11714c3eb207Smrg return _Callable{}(std::forward<_Range>(__r)); 11724c3eb207Smrg else 11734c3eb207Smrg return this->_M_callable(std::forward<_Range>(__r)); 11744c3eb207Smrg } 11754c3eb207Smrg 11764c3eb207Smrg template<viewable_range _Range> 11774c3eb207Smrg requires requires { declval<_Callable>()(declval<_Range>()); } 11784c3eb207Smrg friend constexpr auto 11794c3eb207Smrg operator|(_Range&& __r, const _RangeAdaptorClosure& __o) 11804c3eb207Smrg { return __o(std::forward<_Range>(__r)); } 11814c3eb207Smrg 11824c3eb207Smrg template<typename _Tp> 11834c3eb207Smrg friend constexpr auto 11844c3eb207Smrg operator|(const _RangeAdaptorClosure<_Tp>& __x, 11854c3eb207Smrg const _RangeAdaptorClosure& __y) 11864c3eb207Smrg { 11874c3eb207Smrg if constexpr (is_default_constructible_v<_Tp> 11884c3eb207Smrg && is_default_constructible_v<_Callable>) 11894c3eb207Smrg { 11904c3eb207Smrg auto __closure = [] <typename _Up> (_Up&& __e) { 11914c3eb207Smrg return std::forward<_Up>(__e) | decltype(__x){} | decltype(__y){}; 11924c3eb207Smrg }; 11934c3eb207Smrg return _RangeAdaptorClosure<decltype(__closure)>(__closure); 11944c3eb207Smrg } 11954c3eb207Smrg else if constexpr (is_default_constructible_v<_Tp> 11964c3eb207Smrg && !is_default_constructible_v<_Callable>) 11974c3eb207Smrg { 11984c3eb207Smrg auto __closure = [__y] <typename _Up> (_Up&& __e) { 11994c3eb207Smrg return std::forward<_Up>(__e) | decltype(__x){} | __y; 12004c3eb207Smrg }; 12014c3eb207Smrg return _RangeAdaptorClosure<decltype(__closure)>(__closure); 12024c3eb207Smrg } 12034c3eb207Smrg else if constexpr (!is_default_constructible_v<_Tp> 12044c3eb207Smrg && is_default_constructible_v<_Callable>) 12054c3eb207Smrg { 12064c3eb207Smrg auto __closure = [__x] <typename _Up> (_Up&& __e) { 12074c3eb207Smrg return std::forward<_Up>(__e) | __x | decltype(__y){}; 12084c3eb207Smrg }; 12094c3eb207Smrg return _RangeAdaptorClosure<decltype(__closure)>(__closure); 12104c3eb207Smrg } 12114c3eb207Smrg else 12124c3eb207Smrg { 12134c3eb207Smrg auto __closure = [__x, __y] <typename _Up> (_Up&& __e) { 12144c3eb207Smrg return std::forward<_Up>(__e) | __x | __y; 12154c3eb207Smrg }; 12164c3eb207Smrg return _RangeAdaptorClosure<decltype(__closure)>(__closure); 12174c3eb207Smrg } 12184c3eb207Smrg } 12194c3eb207Smrg }; 12204c3eb207Smrg 12214c3eb207Smrg template<typename _Callable> 12224c3eb207Smrg _RangeAdaptorClosure(_Callable) -> _RangeAdaptorClosure<_Callable>; 12234c3eb207Smrg } // namespace __adaptor 12244c3eb207Smrg} // namespace views 12254c3eb207Smrg 12264c3eb207Smrg template<range _Range> requires is_object_v<_Range> 12274c3eb207Smrg class ref_view : public view_interface<ref_view<_Range>> 12284c3eb207Smrg { 12294c3eb207Smrg private: 12304c3eb207Smrg _Range* _M_r = nullptr; 12314c3eb207Smrg 12324c3eb207Smrg static void _S_fun(_Range&); // not defined 12334c3eb207Smrg static void _S_fun(_Range&&) = delete; 12344c3eb207Smrg 12354c3eb207Smrg public: 12364c3eb207Smrg constexpr 12374c3eb207Smrg ref_view() noexcept = default; 12384c3eb207Smrg 12394c3eb207Smrg template<__detail::__not_same_as<ref_view> _Tp> 12404c3eb207Smrg requires convertible_to<_Tp, _Range&> 12414c3eb207Smrg && requires { _S_fun(declval<_Tp>()); } 12424c3eb207Smrg constexpr 12434c3eb207Smrg ref_view(_Tp&& __t) 12444c3eb207Smrg : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t)))) 12454c3eb207Smrg { } 12464c3eb207Smrg 12474c3eb207Smrg constexpr _Range& 12484c3eb207Smrg base() const 12494c3eb207Smrg { return *_M_r; } 12504c3eb207Smrg 12514c3eb207Smrg constexpr iterator_t<_Range> 12524c3eb207Smrg begin() const 12534c3eb207Smrg { return ranges::begin(*_M_r); } 12544c3eb207Smrg 12554c3eb207Smrg constexpr sentinel_t<_Range> 12564c3eb207Smrg end() const 12574c3eb207Smrg { return ranges::end(*_M_r); } 12584c3eb207Smrg 12594c3eb207Smrg constexpr bool 12604c3eb207Smrg empty() const requires requires { ranges::empty(*_M_r); } 12614c3eb207Smrg { return ranges::empty(*_M_r); } 12624c3eb207Smrg 12634c3eb207Smrg constexpr auto 12644c3eb207Smrg size() const requires sized_range<_Range> 12654c3eb207Smrg { return ranges::size(*_M_r); } 12664c3eb207Smrg 12674c3eb207Smrg constexpr auto 12684c3eb207Smrg data() const requires contiguous_range<_Range> 12694c3eb207Smrg { return ranges::data(*_M_r); } 12704c3eb207Smrg }; 12714c3eb207Smrg 12724c3eb207Smrg template<typename _Range> 12734c3eb207Smrg ref_view(_Range&) -> ref_view<_Range>; 12744c3eb207Smrg 12754c3eb207Smrg template<typename _Tp> 12764c3eb207Smrg inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true; 12774c3eb207Smrg 12784c3eb207Smrg namespace views 12794c3eb207Smrg { 12804c3eb207Smrg inline constexpr __adaptor::_RangeAdaptorClosure all 12814c3eb207Smrg = [] <viewable_range _Range> (_Range&& __r) 12824c3eb207Smrg { 12834c3eb207Smrg if constexpr (view<decay_t<_Range>>) 12844c3eb207Smrg return std::forward<_Range>(__r); 12854c3eb207Smrg else if constexpr (requires { ref_view{std::forward<_Range>(__r)}; }) 12864c3eb207Smrg return ref_view{std::forward<_Range>(__r)}; 12874c3eb207Smrg else 12884c3eb207Smrg return subrange{std::forward<_Range>(__r)}; 12894c3eb207Smrg }; 12904c3eb207Smrg 12914c3eb207Smrg template<viewable_range _Range> 12924c3eb207Smrg using all_t = decltype(all(std::declval<_Range>())); 12934c3eb207Smrg 12944c3eb207Smrg } // namespace views 12954c3eb207Smrg 12964c3eb207Smrg // The following simple algos are transcribed from ranges_algo.h to avoid 12974c3eb207Smrg // having to include that entire header. 12984c3eb207Smrg namespace __detail 12994c3eb207Smrg { 13004c3eb207Smrg template<typename _Iter, typename _Sent, typename _Tp> 13014c3eb207Smrg constexpr _Iter 13024c3eb207Smrg find(_Iter __first, _Sent __last, const _Tp& __value) 13034c3eb207Smrg { 13044c3eb207Smrg while (__first != __last 13054c3eb207Smrg && !(bool)(*__first == __value)) 13064c3eb207Smrg ++__first; 13074c3eb207Smrg return __first; 13084c3eb207Smrg } 13094c3eb207Smrg 13104c3eb207Smrg template<typename _Iter, typename _Sent, typename _Pred> 13114c3eb207Smrg constexpr _Iter 13124c3eb207Smrg find_if(_Iter __first, _Sent __last, _Pred __pred) 13134c3eb207Smrg { 13144c3eb207Smrg while (__first != __last 13154c3eb207Smrg && !(bool)std::__invoke(__pred, *__first)) 13164c3eb207Smrg ++__first; 13174c3eb207Smrg return __first; 13184c3eb207Smrg } 13194c3eb207Smrg 13204c3eb207Smrg template<typename _Iter, typename _Sent, typename _Pred> 13214c3eb207Smrg constexpr _Iter 13224c3eb207Smrg find_if_not(_Iter __first, _Sent __last, _Pred __pred) 13234c3eb207Smrg { 13244c3eb207Smrg while (__first != __last 13254c3eb207Smrg && (bool)std::__invoke(__pred, *__first)) 13264c3eb207Smrg ++__first; 13274c3eb207Smrg return __first; 13284c3eb207Smrg } 13294c3eb207Smrg 13304c3eb207Smrg template<typename _Iter1, typename _Sent1, typename _Iter2, typename _Sent2> 13314c3eb207Smrg constexpr pair<_Iter1, _Iter2> 13324c3eb207Smrg mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2) 13334c3eb207Smrg { 13344c3eb207Smrg while (__first1 != __last1 && __first2 != __last2 13354c3eb207Smrg && (bool)ranges::equal_to{}(*__first1, *__first2)) 13364c3eb207Smrg { 13374c3eb207Smrg ++__first1; 13384c3eb207Smrg ++__first2; 13394c3eb207Smrg } 13404c3eb207Smrg return { std::move(__first1), std::move(__first2) }; 13414c3eb207Smrg } 13424c3eb207Smrg } // namespace __detail 13434c3eb207Smrg 13444c3eb207Smrg namespace __detail 13454c3eb207Smrg { 13464c3eb207Smrg template<range _Range> 13474c3eb207Smrg struct _CachedPosition 13484c3eb207Smrg { 13494c3eb207Smrg constexpr bool 13504c3eb207Smrg _M_has_value() const 13514c3eb207Smrg { return false; } 13524c3eb207Smrg 13534c3eb207Smrg constexpr iterator_t<_Range> 13544c3eb207Smrg _M_get(const _Range&) const 13554c3eb207Smrg { 13564c3eb207Smrg __glibcxx_assert(false); 13574c3eb207Smrg __builtin_unreachable(); 13584c3eb207Smrg } 13594c3eb207Smrg 13604c3eb207Smrg constexpr void 13614c3eb207Smrg _M_set(const _Range&, const iterator_t<_Range>&) const 13624c3eb207Smrg { } 13634c3eb207Smrg }; 13644c3eb207Smrg 13654c3eb207Smrg template<forward_range _Range> 13664c3eb207Smrg struct _CachedPosition<_Range> 13674c3eb207Smrg { 13684c3eb207Smrg private: 13694c3eb207Smrg iterator_t<_Range> _M_iter{}; 13704c3eb207Smrg 13714c3eb207Smrg public: 13724c3eb207Smrg constexpr bool 13734c3eb207Smrg _M_has_value() const 13744c3eb207Smrg { return _M_iter != iterator_t<_Range>{}; } 13754c3eb207Smrg 13764c3eb207Smrg constexpr iterator_t<_Range> 13774c3eb207Smrg _M_get(const _Range&) const 13784c3eb207Smrg { 13794c3eb207Smrg __glibcxx_assert(_M_has_value()); 13804c3eb207Smrg return _M_iter; 13814c3eb207Smrg } 13824c3eb207Smrg 13834c3eb207Smrg constexpr void 13844c3eb207Smrg _M_set(const _Range&, const iterator_t<_Range>& __it) 13854c3eb207Smrg { 13864c3eb207Smrg __glibcxx_assert(!_M_has_value()); 13874c3eb207Smrg _M_iter = __it; 13884c3eb207Smrg } 13894c3eb207Smrg }; 13904c3eb207Smrg 13914c3eb207Smrg template<random_access_range _Range> 13924c3eb207Smrg requires (sizeof(range_difference_t<_Range>) 13934c3eb207Smrg <= sizeof(iterator_t<_Range>)) 13944c3eb207Smrg struct _CachedPosition<_Range> 13954c3eb207Smrg { 13964c3eb207Smrg private: 13974c3eb207Smrg range_difference_t<_Range> _M_offset = -1; 13984c3eb207Smrg 13994c3eb207Smrg public: 14004c3eb207Smrg constexpr bool 14014c3eb207Smrg _M_has_value() const 14024c3eb207Smrg { return _M_offset >= 0; } 14034c3eb207Smrg 14044c3eb207Smrg constexpr iterator_t<_Range> 14054c3eb207Smrg _M_get(_Range& __r) const 14064c3eb207Smrg { 14074c3eb207Smrg __glibcxx_assert(_M_has_value()); 14084c3eb207Smrg return ranges::begin(__r) + _M_offset; 14094c3eb207Smrg } 14104c3eb207Smrg 14114c3eb207Smrg constexpr void 14124c3eb207Smrg _M_set(_Range& __r, const iterator_t<_Range>& __it) 14134c3eb207Smrg { 14144c3eb207Smrg __glibcxx_assert(!_M_has_value()); 14154c3eb207Smrg _M_offset = __it - ranges::begin(__r); 14164c3eb207Smrg } 14174c3eb207Smrg }; 14184c3eb207Smrg } // namespace __detail 14194c3eb207Smrg 14204c3eb207Smrg namespace __detail 14214c3eb207Smrg { 14224c3eb207Smrg template<typename _Base> 14234c3eb207Smrg struct __filter_view_iter_cat 14244c3eb207Smrg { }; 14254c3eb207Smrg 14264c3eb207Smrg template<forward_range _Base> 14274c3eb207Smrg struct __filter_view_iter_cat<_Base> 14284c3eb207Smrg { 14294c3eb207Smrg private: 14304c3eb207Smrg static auto 14314c3eb207Smrg _S_iter_cat() 14324c3eb207Smrg { 14334c3eb207Smrg using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category; 14344c3eb207Smrg if constexpr (derived_from<_Cat, bidirectional_iterator_tag>) 14354c3eb207Smrg return bidirectional_iterator_tag{}; 14364c3eb207Smrg else if constexpr (derived_from<_Cat, forward_iterator_tag>) 14374c3eb207Smrg return forward_iterator_tag{}; 14384c3eb207Smrg else 14394c3eb207Smrg return _Cat{}; 14404c3eb207Smrg } 14414c3eb207Smrg public: 14424c3eb207Smrg using iterator_category = decltype(_S_iter_cat()); 14434c3eb207Smrg }; 14444c3eb207Smrg } // namespace __detail 14454c3eb207Smrg 14464c3eb207Smrg template<input_range _Vp, 14474c3eb207Smrg indirect_unary_predicate<iterator_t<_Vp>> _Pred> 14484c3eb207Smrg requires view<_Vp> && is_object_v<_Pred> 14494c3eb207Smrg class filter_view : public view_interface<filter_view<_Vp, _Pred>> 14504c3eb207Smrg { 14514c3eb207Smrg private: 14524c3eb207Smrg struct _Sentinel; 14534c3eb207Smrg 14544c3eb207Smrg struct _Iterator : __detail::__filter_view_iter_cat<_Vp> 14554c3eb207Smrg { 14564c3eb207Smrg private: 14574c3eb207Smrg static constexpr auto 14584c3eb207Smrg _S_iter_concept() 14594c3eb207Smrg { 14604c3eb207Smrg if constexpr (bidirectional_range<_Vp>) 14614c3eb207Smrg return bidirectional_iterator_tag{}; 14624c3eb207Smrg else if constexpr (forward_range<_Vp>) 14634c3eb207Smrg return forward_iterator_tag{}; 14644c3eb207Smrg else 14654c3eb207Smrg return input_iterator_tag{}; 14664c3eb207Smrg } 14674c3eb207Smrg 14684c3eb207Smrg friend filter_view; 14694c3eb207Smrg 14704c3eb207Smrg using _Vp_iter = iterator_t<_Vp>; 14714c3eb207Smrg 14724c3eb207Smrg _Vp_iter _M_current = _Vp_iter(); 14734c3eb207Smrg filter_view* _M_parent = nullptr; 14744c3eb207Smrg 14754c3eb207Smrg public: 14764c3eb207Smrg using iterator_concept = decltype(_S_iter_concept()); 14774c3eb207Smrg // iterator_category defined in __filter_view_iter_cat 14784c3eb207Smrg using value_type = range_value_t<_Vp>; 14794c3eb207Smrg using difference_type = range_difference_t<_Vp>; 14804c3eb207Smrg 14814c3eb207Smrg _Iterator() requires default_initializable<_Vp_iter> = default; 14824c3eb207Smrg 14834c3eb207Smrg constexpr 14844c3eb207Smrg _Iterator(filter_view* __parent, _Vp_iter __current) 14854c3eb207Smrg : _M_current(std::move(__current)), 14864c3eb207Smrg _M_parent(__parent) 14874c3eb207Smrg { } 14884c3eb207Smrg 14894c3eb207Smrg constexpr const _Vp_iter& 14904c3eb207Smrg base() const & noexcept 14914c3eb207Smrg { return _M_current; } 14924c3eb207Smrg 14934c3eb207Smrg constexpr _Vp_iter 14944c3eb207Smrg base() && 14954c3eb207Smrg { return std::move(_M_current); } 14964c3eb207Smrg 14974c3eb207Smrg constexpr range_reference_t<_Vp> 14984c3eb207Smrg operator*() const 14994c3eb207Smrg { return *_M_current; } 15004c3eb207Smrg 15014c3eb207Smrg constexpr _Vp_iter 15024c3eb207Smrg operator->() const 15034c3eb207Smrg requires __detail::__has_arrow<_Vp_iter> 15044c3eb207Smrg && copyable<_Vp_iter> 15054c3eb207Smrg { return _M_current; } 15064c3eb207Smrg 15074c3eb207Smrg constexpr _Iterator& 15084c3eb207Smrg operator++() 15094c3eb207Smrg { 15104c3eb207Smrg _M_current = __detail::find_if(std::move(++_M_current), 15114c3eb207Smrg ranges::end(_M_parent->_M_base), 15124c3eb207Smrg std::ref(*_M_parent->_M_pred)); 15134c3eb207Smrg return *this; 15144c3eb207Smrg } 15154c3eb207Smrg 15164c3eb207Smrg constexpr void 15174c3eb207Smrg operator++(int) 15184c3eb207Smrg { ++*this; } 15194c3eb207Smrg 15204c3eb207Smrg constexpr _Iterator 15214c3eb207Smrg operator++(int) requires forward_range<_Vp> 15224c3eb207Smrg { 15234c3eb207Smrg auto __tmp = *this; 15244c3eb207Smrg ++*this; 15254c3eb207Smrg return __tmp; 15264c3eb207Smrg } 15274c3eb207Smrg 15284c3eb207Smrg constexpr _Iterator& 15294c3eb207Smrg operator--() requires bidirectional_range<_Vp> 15304c3eb207Smrg { 15314c3eb207Smrg do 15324c3eb207Smrg --_M_current; 15334c3eb207Smrg while (!std::__invoke(*_M_parent->_M_pred, *_M_current)); 15344c3eb207Smrg return *this; 15354c3eb207Smrg } 15364c3eb207Smrg 15374c3eb207Smrg constexpr _Iterator 15384c3eb207Smrg operator--(int) requires bidirectional_range<_Vp> 15394c3eb207Smrg { 15404c3eb207Smrg auto __tmp = *this; 15414c3eb207Smrg --*this; 15424c3eb207Smrg return __tmp; 15434c3eb207Smrg } 15444c3eb207Smrg 15454c3eb207Smrg friend constexpr bool 15464c3eb207Smrg operator==(const _Iterator& __x, const _Iterator& __y) 15474c3eb207Smrg requires equality_comparable<_Vp_iter> 15484c3eb207Smrg { return __x._M_current == __y._M_current; } 15494c3eb207Smrg 15504c3eb207Smrg friend constexpr range_rvalue_reference_t<_Vp> 15514c3eb207Smrg iter_move(const _Iterator& __i) 15524c3eb207Smrg noexcept(noexcept(ranges::iter_move(__i._M_current))) 15534c3eb207Smrg { return ranges::iter_move(__i._M_current); } 15544c3eb207Smrg 15554c3eb207Smrg friend constexpr void 15564c3eb207Smrg iter_swap(const _Iterator& __x, const _Iterator& __y) 15574c3eb207Smrg noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current))) 15584c3eb207Smrg requires indirectly_swappable<_Vp_iter> 15594c3eb207Smrg { ranges::iter_swap(__x._M_current, __y._M_current); } 15604c3eb207Smrg }; 15614c3eb207Smrg 15624c3eb207Smrg struct _Sentinel 15634c3eb207Smrg { 15644c3eb207Smrg private: 15654c3eb207Smrg sentinel_t<_Vp> _M_end = sentinel_t<_Vp>(); 15664c3eb207Smrg 15674c3eb207Smrg constexpr bool 15684c3eb207Smrg __equal(const _Iterator& __i) const 15694c3eb207Smrg { return __i._M_current == _M_end; } 15704c3eb207Smrg 15714c3eb207Smrg public: 15724c3eb207Smrg _Sentinel() = default; 15734c3eb207Smrg 15744c3eb207Smrg constexpr explicit 15754c3eb207Smrg _Sentinel(filter_view* __parent) 15764c3eb207Smrg : _M_end(ranges::end(__parent->_M_base)) 15774c3eb207Smrg { } 15784c3eb207Smrg 15794c3eb207Smrg constexpr sentinel_t<_Vp> 15804c3eb207Smrg base() const 15814c3eb207Smrg { return _M_end; } 15824c3eb207Smrg 15834c3eb207Smrg friend constexpr bool 15844c3eb207Smrg operator==(const _Iterator& __x, const _Sentinel& __y) 15854c3eb207Smrg { return __y.__equal(__x); } 15864c3eb207Smrg }; 15874c3eb207Smrg 15884c3eb207Smrg _Vp _M_base = _Vp(); 15894c3eb207Smrg __detail::__box<_Pred> _M_pred; 15904c3eb207Smrg [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin; 15914c3eb207Smrg 15924c3eb207Smrg public: 1593*4ac76180Smrg filter_view() requires default_initializable<_Vp> = default; 15944c3eb207Smrg 15954c3eb207Smrg constexpr 15964c3eb207Smrg filter_view(_Vp __base, _Pred __pred) 15974c3eb207Smrg : _M_base(std::move(__base)), _M_pred(std::move(__pred)) 15984c3eb207Smrg { } 15994c3eb207Smrg 16004c3eb207Smrg constexpr _Vp 16014c3eb207Smrg base() const& requires copy_constructible<_Vp> 16024c3eb207Smrg { return _M_base; } 16034c3eb207Smrg 16044c3eb207Smrg constexpr _Vp 16054c3eb207Smrg base() && 16064c3eb207Smrg { return std::move(_M_base); } 16074c3eb207Smrg 16084c3eb207Smrg constexpr const _Pred& 16094c3eb207Smrg pred() const 16104c3eb207Smrg { return *_M_pred; } 16114c3eb207Smrg 16124c3eb207Smrg constexpr _Iterator 16134c3eb207Smrg begin() 16144c3eb207Smrg { 16154c3eb207Smrg if (_M_cached_begin._M_has_value()) 16164c3eb207Smrg return {this, _M_cached_begin._M_get(_M_base)}; 16174c3eb207Smrg 16184c3eb207Smrg __glibcxx_assert(_M_pred.has_value()); 16194c3eb207Smrg auto __it = __detail::find_if(ranges::begin(_M_base), 16204c3eb207Smrg ranges::end(_M_base), 16214c3eb207Smrg std::ref(*_M_pred)); 16224c3eb207Smrg _M_cached_begin._M_set(_M_base, __it); 16234c3eb207Smrg return {this, std::move(__it)}; 16244c3eb207Smrg } 16254c3eb207Smrg 16264c3eb207Smrg constexpr auto 16274c3eb207Smrg end() 16284c3eb207Smrg { 16294c3eb207Smrg if constexpr (common_range<_Vp>) 16304c3eb207Smrg return _Iterator{this, ranges::end(_M_base)}; 16314c3eb207Smrg else 16324c3eb207Smrg return _Sentinel{this}; 16334c3eb207Smrg } 16344c3eb207Smrg }; 16354c3eb207Smrg 16364c3eb207Smrg template<typename _Range, typename _Pred> 16374c3eb207Smrg filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>; 16384c3eb207Smrg 16394c3eb207Smrg namespace views 16404c3eb207Smrg { 16414c3eb207Smrg inline constexpr __adaptor::_RangeAdaptor filter 16424c3eb207Smrg = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p) 16434c3eb207Smrg { 16444c3eb207Smrg return filter_view{std::forward<_Range>(__r), std::forward<_Pred>(__p)}; 16454c3eb207Smrg }; 16464c3eb207Smrg } // namespace views 16474c3eb207Smrg 16484c3eb207Smrg template<input_range _Vp, copy_constructible _Fp> 16494c3eb207Smrg requires view<_Vp> && is_object_v<_Fp> 16504c3eb207Smrg && regular_invocable<_Fp&, range_reference_t<_Vp>> 16514c3eb207Smrg && std::__detail::__can_reference<invoke_result_t<_Fp&, 16524c3eb207Smrg range_reference_t<_Vp>>> 16534c3eb207Smrg class transform_view : public view_interface<transform_view<_Vp, _Fp>> 16544c3eb207Smrg { 16554c3eb207Smrg private: 16564c3eb207Smrg template<bool _Const> 16574c3eb207Smrg using _Base = __detail::__maybe_const_t<_Const, _Vp>; 16584c3eb207Smrg 16594c3eb207Smrg template<bool _Const> 16604c3eb207Smrg struct __iter_cat 16614c3eb207Smrg { }; 16624c3eb207Smrg 16634c3eb207Smrg template<bool _Const> 16644c3eb207Smrg requires forward_range<_Base<_Const>> 16654c3eb207Smrg struct __iter_cat<_Const> 16664c3eb207Smrg { 16674c3eb207Smrg private: 16684c3eb207Smrg static auto 16694c3eb207Smrg _S_iter_cat() 16704c3eb207Smrg { 16714c3eb207Smrg using _Base = transform_view::_Base<_Const>; 16724c3eb207Smrg using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>; 16734c3eb207Smrg if constexpr (is_lvalue_reference_v<_Res>) 16744c3eb207Smrg { 16754c3eb207Smrg using _Cat 16764c3eb207Smrg = typename iterator_traits<iterator_t<_Base>>::iterator_category; 16774c3eb207Smrg if constexpr (derived_from<_Cat, contiguous_iterator_tag>) 16784c3eb207Smrg return random_access_iterator_tag{}; 16794c3eb207Smrg else 16804c3eb207Smrg return _Cat{}; 16814c3eb207Smrg } 16824c3eb207Smrg else 16834c3eb207Smrg return input_iterator_tag{}; 16844c3eb207Smrg } 16854c3eb207Smrg public: 16864c3eb207Smrg using iterator_category = decltype(_S_iter_cat()); 16874c3eb207Smrg }; 16884c3eb207Smrg 16894c3eb207Smrg template<bool _Const> 16904c3eb207Smrg struct _Sentinel; 16914c3eb207Smrg 16924c3eb207Smrg template<bool _Const> 16934c3eb207Smrg struct _Iterator : __iter_cat<_Const> 16944c3eb207Smrg { 16954c3eb207Smrg private: 16964c3eb207Smrg using _Parent = __detail::__maybe_const_t<_Const, transform_view>; 16974c3eb207Smrg using _Base = transform_view::_Base<_Const>; 16984c3eb207Smrg 16994c3eb207Smrg static auto 17004c3eb207Smrg _S_iter_concept() 17014c3eb207Smrg { 17024c3eb207Smrg if constexpr (random_access_range<_Base>) 17034c3eb207Smrg return random_access_iterator_tag{}; 17044c3eb207Smrg else if constexpr (bidirectional_range<_Base>) 17054c3eb207Smrg return bidirectional_iterator_tag{}; 17064c3eb207Smrg else if constexpr (forward_range<_Base>) 17074c3eb207Smrg return forward_iterator_tag{}; 17084c3eb207Smrg else 17094c3eb207Smrg return input_iterator_tag{}; 17104c3eb207Smrg } 17114c3eb207Smrg 17124c3eb207Smrg using _Base_iter = iterator_t<_Base>; 17134c3eb207Smrg 17144c3eb207Smrg _Base_iter _M_current = _Base_iter(); 17154c3eb207Smrg _Parent* _M_parent = nullptr; 17164c3eb207Smrg 17174c3eb207Smrg public: 17184c3eb207Smrg using iterator_concept = decltype(_S_iter_concept()); 17194c3eb207Smrg // iterator_category defined in __transform_view_iter_cat 17204c3eb207Smrg using value_type 17214c3eb207Smrg = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>; 17224c3eb207Smrg using difference_type = range_difference_t<_Base>; 17234c3eb207Smrg 17244c3eb207Smrg _Iterator() requires default_initializable<_Base_iter> = default; 17254c3eb207Smrg 17264c3eb207Smrg constexpr 17274c3eb207Smrg _Iterator(_Parent* __parent, _Base_iter __current) 17284c3eb207Smrg : _M_current(std::move(__current)), 17294c3eb207Smrg _M_parent(__parent) 17304c3eb207Smrg { } 17314c3eb207Smrg 17324c3eb207Smrg constexpr 17334c3eb207Smrg _Iterator(_Iterator<!_Const> __i) 17344c3eb207Smrg requires _Const 17354c3eb207Smrg && convertible_to<iterator_t<_Vp>, _Base_iter> 17364c3eb207Smrg : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent) 17374c3eb207Smrg { } 17384c3eb207Smrg 17394c3eb207Smrg constexpr const _Base_iter& 17404c3eb207Smrg base() const & noexcept 17414c3eb207Smrg { return _M_current; } 17424c3eb207Smrg 17434c3eb207Smrg constexpr _Base_iter 17444c3eb207Smrg base() && 17454c3eb207Smrg { return std::move(_M_current); } 17464c3eb207Smrg 17474c3eb207Smrg constexpr decltype(auto) 17484c3eb207Smrg operator*() const 17494c3eb207Smrg noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current))) 17504c3eb207Smrg { return std::__invoke(*_M_parent->_M_fun, *_M_current); } 17514c3eb207Smrg 17524c3eb207Smrg constexpr _Iterator& 17534c3eb207Smrg operator++() 17544c3eb207Smrg { 17554c3eb207Smrg ++_M_current; 17564c3eb207Smrg return *this; 17574c3eb207Smrg } 17584c3eb207Smrg 17594c3eb207Smrg constexpr void 17604c3eb207Smrg operator++(int) 17614c3eb207Smrg { ++_M_current; } 17624c3eb207Smrg 17634c3eb207Smrg constexpr _Iterator 17644c3eb207Smrg operator++(int) requires forward_range<_Base> 17654c3eb207Smrg { 17664c3eb207Smrg auto __tmp = *this; 17674c3eb207Smrg ++*this; 17684c3eb207Smrg return __tmp; 17694c3eb207Smrg } 17704c3eb207Smrg 17714c3eb207Smrg constexpr _Iterator& 17724c3eb207Smrg operator--() requires bidirectional_range<_Base> 17734c3eb207Smrg { 17744c3eb207Smrg --_M_current; 17754c3eb207Smrg return *this; 17764c3eb207Smrg } 17774c3eb207Smrg 17784c3eb207Smrg constexpr _Iterator 17794c3eb207Smrg operator--(int) requires bidirectional_range<_Base> 17804c3eb207Smrg { 17814c3eb207Smrg auto __tmp = *this; 17824c3eb207Smrg --*this; 17834c3eb207Smrg return __tmp; 17844c3eb207Smrg } 17854c3eb207Smrg 17864c3eb207Smrg constexpr _Iterator& 17874c3eb207Smrg operator+=(difference_type __n) requires random_access_range<_Base> 17884c3eb207Smrg { 17894c3eb207Smrg _M_current += __n; 17904c3eb207Smrg return *this; 17914c3eb207Smrg } 17924c3eb207Smrg 17934c3eb207Smrg constexpr _Iterator& 17944c3eb207Smrg operator-=(difference_type __n) requires random_access_range<_Base> 17954c3eb207Smrg { 17964c3eb207Smrg _M_current -= __n; 17974c3eb207Smrg return *this; 17984c3eb207Smrg } 17994c3eb207Smrg 18004c3eb207Smrg constexpr decltype(auto) 18014c3eb207Smrg operator[](difference_type __n) const 18024c3eb207Smrg requires random_access_range<_Base> 18034c3eb207Smrg { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); } 18044c3eb207Smrg 18054c3eb207Smrg friend constexpr bool 18064c3eb207Smrg operator==(const _Iterator& __x, const _Iterator& __y) 18074c3eb207Smrg requires equality_comparable<_Base_iter> 18084c3eb207Smrg { return __x._M_current == __y._M_current; } 18094c3eb207Smrg 18104c3eb207Smrg friend constexpr bool 18114c3eb207Smrg operator<(const _Iterator& __x, const _Iterator& __y) 18124c3eb207Smrg requires random_access_range<_Base> 18134c3eb207Smrg { return __x._M_current < __y._M_current; } 18144c3eb207Smrg 18154c3eb207Smrg friend constexpr bool 18164c3eb207Smrg operator>(const _Iterator& __x, const _Iterator& __y) 18174c3eb207Smrg requires random_access_range<_Base> 18184c3eb207Smrg { return __y < __x; } 18194c3eb207Smrg 18204c3eb207Smrg friend constexpr bool 18214c3eb207Smrg operator<=(const _Iterator& __x, const _Iterator& __y) 18224c3eb207Smrg requires random_access_range<_Base> 18234c3eb207Smrg { return !(__y < __x); } 18244c3eb207Smrg 18254c3eb207Smrg friend constexpr bool 18264c3eb207Smrg operator>=(const _Iterator& __x, const _Iterator& __y) 18274c3eb207Smrg requires random_access_range<_Base> 18284c3eb207Smrg { return !(__x < __y); } 18294c3eb207Smrg 18304c3eb207Smrg#ifdef __cpp_lib_three_way_comparison 18314c3eb207Smrg friend constexpr auto 18324c3eb207Smrg operator<=>(const _Iterator& __x, const _Iterator& __y) 18334c3eb207Smrg requires random_access_range<_Base> 18344c3eb207Smrg && three_way_comparable<_Base_iter> 18354c3eb207Smrg { return __x._M_current <=> __y._M_current; } 18364c3eb207Smrg#endif 18374c3eb207Smrg 18384c3eb207Smrg friend constexpr _Iterator 18394c3eb207Smrg operator+(_Iterator __i, difference_type __n) 18404c3eb207Smrg requires random_access_range<_Base> 18414c3eb207Smrg { return {__i._M_parent, __i._M_current + __n}; } 18424c3eb207Smrg 18434c3eb207Smrg friend constexpr _Iterator 18444c3eb207Smrg operator+(difference_type __n, _Iterator __i) 18454c3eb207Smrg requires random_access_range<_Base> 18464c3eb207Smrg { return {__i._M_parent, __i._M_current + __n}; } 18474c3eb207Smrg 18484c3eb207Smrg friend constexpr _Iterator 18494c3eb207Smrg operator-(_Iterator __i, difference_type __n) 18504c3eb207Smrg requires random_access_range<_Base> 18514c3eb207Smrg { return {__i._M_parent, __i._M_current - __n}; } 18524c3eb207Smrg 18534c3eb207Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 18544c3eb207Smrg // 3483. transform_view::iterator's difference is overconstrained 18554c3eb207Smrg friend constexpr difference_type 18564c3eb207Smrg operator-(const _Iterator& __x, const _Iterator& __y) 18574c3eb207Smrg requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> 18584c3eb207Smrg { return __x._M_current - __y._M_current; } 18594c3eb207Smrg 18604c3eb207Smrg friend constexpr decltype(auto) 18614c3eb207Smrg iter_move(const _Iterator& __i) noexcept(noexcept(*__i)) 18624c3eb207Smrg { 18634c3eb207Smrg if constexpr (is_lvalue_reference_v<decltype(*__i)>) 18644c3eb207Smrg return std::move(*__i); 18654c3eb207Smrg else 18664c3eb207Smrg return *__i; 18674c3eb207Smrg } 18684c3eb207Smrg 18694c3eb207Smrg friend _Iterator<!_Const>; 18704c3eb207Smrg template<bool> friend struct _Sentinel; 18714c3eb207Smrg }; 18724c3eb207Smrg 18734c3eb207Smrg template<bool _Const> 18744c3eb207Smrg struct _Sentinel 18754c3eb207Smrg { 18764c3eb207Smrg private: 18774c3eb207Smrg using _Parent = __detail::__maybe_const_t<_Const, transform_view>; 18784c3eb207Smrg using _Base = transform_view::_Base<_Const>; 18794c3eb207Smrg 18804c3eb207Smrg template<bool _Const2> 18814c3eb207Smrg constexpr auto 18824c3eb207Smrg __distance_from(const _Iterator<_Const2>& __i) const 18834c3eb207Smrg { return _M_end - __i._M_current; } 18844c3eb207Smrg 18854c3eb207Smrg template<bool _Const2> 18864c3eb207Smrg constexpr bool 18874c3eb207Smrg __equal(const _Iterator<_Const2>& __i) const 18884c3eb207Smrg { return __i._M_current == _M_end; } 18894c3eb207Smrg 18904c3eb207Smrg sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 18914c3eb207Smrg 18924c3eb207Smrg public: 18934c3eb207Smrg _Sentinel() = default; 18944c3eb207Smrg 18954c3eb207Smrg constexpr explicit 18964c3eb207Smrg _Sentinel(sentinel_t<_Base> __end) 18974c3eb207Smrg : _M_end(__end) 18984c3eb207Smrg { } 18994c3eb207Smrg 19004c3eb207Smrg constexpr 19014c3eb207Smrg _Sentinel(_Sentinel<!_Const> __i) 19024c3eb207Smrg requires _Const 19034c3eb207Smrg && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 19044c3eb207Smrg : _M_end(std::move(__i._M_end)) 19054c3eb207Smrg { } 19064c3eb207Smrg 19074c3eb207Smrg constexpr sentinel_t<_Base> 19084c3eb207Smrg base() const 19094c3eb207Smrg { return _M_end; } 19104c3eb207Smrg 19114c3eb207Smrg template<bool _Const2> 19124c3eb207Smrg requires sentinel_for<sentinel_t<_Base>, 19134c3eb207Smrg iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>> 19144c3eb207Smrg friend constexpr bool 19154c3eb207Smrg operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y) 19164c3eb207Smrg { return __y.__equal(__x); } 19174c3eb207Smrg 19184c3eb207Smrg template<bool _Const2, 19194c3eb207Smrg typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>> 19204c3eb207Smrg requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 19214c3eb207Smrg friend constexpr range_difference_t<_Base2> 19224c3eb207Smrg operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y) 19234c3eb207Smrg { return -__y.__distance_from(__x); } 19244c3eb207Smrg 19254c3eb207Smrg template<bool _Const2, 19264c3eb207Smrg typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>> 19274c3eb207Smrg requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 19284c3eb207Smrg friend constexpr range_difference_t<_Base2> 19294c3eb207Smrg operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x) 19304c3eb207Smrg { return __y.__distance_from(__x); } 19314c3eb207Smrg 19324c3eb207Smrg friend _Sentinel<!_Const>; 19334c3eb207Smrg }; 19344c3eb207Smrg 19354c3eb207Smrg _Vp _M_base = _Vp(); 19364c3eb207Smrg __detail::__box<_Fp> _M_fun; 19374c3eb207Smrg 19384c3eb207Smrg public: 1939*4ac76180Smrg transform_view() requires default_initializable<_Vp> = default; 19404c3eb207Smrg 19414c3eb207Smrg constexpr 19424c3eb207Smrg transform_view(_Vp __base, _Fp __fun) 19434c3eb207Smrg : _M_base(std::move(__base)), _M_fun(std::move(__fun)) 19444c3eb207Smrg { } 19454c3eb207Smrg 19464c3eb207Smrg constexpr _Vp 19474c3eb207Smrg base() const& requires copy_constructible<_Vp> 19484c3eb207Smrg { return _M_base ; } 19494c3eb207Smrg 19504c3eb207Smrg constexpr _Vp 19514c3eb207Smrg base() && 19524c3eb207Smrg { return std::move(_M_base); } 19534c3eb207Smrg 19544c3eb207Smrg constexpr _Iterator<false> 19554c3eb207Smrg begin() 19564c3eb207Smrg { return _Iterator<false>{this, ranges::begin(_M_base)}; } 19574c3eb207Smrg 19584c3eb207Smrg constexpr _Iterator<true> 19594c3eb207Smrg begin() const 19604c3eb207Smrg requires range<const _Vp> 19614c3eb207Smrg && regular_invocable<const _Fp&, range_reference_t<const _Vp>> 19624c3eb207Smrg { return _Iterator<true>{this, ranges::begin(_M_base)}; } 19634c3eb207Smrg 19644c3eb207Smrg constexpr _Sentinel<false> 19654c3eb207Smrg end() 19664c3eb207Smrg { return _Sentinel<false>{ranges::end(_M_base)}; } 19674c3eb207Smrg 19684c3eb207Smrg constexpr _Iterator<false> 19694c3eb207Smrg end() requires common_range<_Vp> 19704c3eb207Smrg { return _Iterator<false>{this, ranges::end(_M_base)}; } 19714c3eb207Smrg 19724c3eb207Smrg constexpr _Sentinel<true> 19734c3eb207Smrg end() const 19744c3eb207Smrg requires range<const _Vp> 19754c3eb207Smrg && regular_invocable<const _Fp&, range_reference_t<const _Vp>> 19764c3eb207Smrg { return _Sentinel<true>{ranges::end(_M_base)}; } 19774c3eb207Smrg 19784c3eb207Smrg constexpr _Iterator<true> 19794c3eb207Smrg end() const 19804c3eb207Smrg requires common_range<const _Vp> 19814c3eb207Smrg && regular_invocable<const _Fp&, range_reference_t<const _Vp>> 19824c3eb207Smrg { return _Iterator<true>{this, ranges::end(_M_base)}; } 19834c3eb207Smrg 19844c3eb207Smrg constexpr auto 19854c3eb207Smrg size() requires sized_range<_Vp> 19864c3eb207Smrg { return ranges::size(_M_base); } 19874c3eb207Smrg 19884c3eb207Smrg constexpr auto 19894c3eb207Smrg size() const requires sized_range<const _Vp> 19904c3eb207Smrg { return ranges::size(_M_base); } 19914c3eb207Smrg }; 19924c3eb207Smrg 19934c3eb207Smrg template<typename _Range, typename _Fp> 19944c3eb207Smrg transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>; 19954c3eb207Smrg 19964c3eb207Smrg namespace views 19974c3eb207Smrg { 19984c3eb207Smrg inline constexpr __adaptor::_RangeAdaptor transform 19994c3eb207Smrg = [] <viewable_range _Range, typename _Fp> (_Range&& __r, _Fp&& __f) 20004c3eb207Smrg { 20014c3eb207Smrg return transform_view{std::forward<_Range>(__r), std::forward<_Fp>(__f)}; 20024c3eb207Smrg }; 20034c3eb207Smrg } // namespace views 20044c3eb207Smrg 20054c3eb207Smrg template<view _Vp> 20064c3eb207Smrg class take_view : public view_interface<take_view<_Vp>> 20074c3eb207Smrg { 20084c3eb207Smrg private: 20094c3eb207Smrg template<bool _Const> 20104c3eb207Smrg using _CI = counted_iterator< 20114c3eb207Smrg iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>; 20124c3eb207Smrg 20134c3eb207Smrg template<bool _Const> 20144c3eb207Smrg struct _Sentinel 20154c3eb207Smrg { 20164c3eb207Smrg private: 20174c3eb207Smrg using _Base = __detail::__maybe_const_t<_Const, _Vp>; 20184c3eb207Smrg sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 20194c3eb207Smrg 20204c3eb207Smrg public: 20214c3eb207Smrg _Sentinel() = default; 20224c3eb207Smrg 20234c3eb207Smrg constexpr explicit 20244c3eb207Smrg _Sentinel(sentinel_t<_Base> __end) 20254c3eb207Smrg : _M_end(__end) 20264c3eb207Smrg { } 20274c3eb207Smrg 20284c3eb207Smrg constexpr 20294c3eb207Smrg _Sentinel(_Sentinel<!_Const> __s) 20304c3eb207Smrg requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 20314c3eb207Smrg : _M_end(std::move(__s._M_end)) 20324c3eb207Smrg { } 20334c3eb207Smrg 20344c3eb207Smrg constexpr sentinel_t<_Base> 20354c3eb207Smrg base() const 20364c3eb207Smrg { return _M_end; } 20374c3eb207Smrg 20384c3eb207Smrg friend constexpr bool 20394c3eb207Smrg operator==(const _CI<_Const>& __y, const _Sentinel& __x) 20404c3eb207Smrg { return __y.count() == 0 || __y.base() == __x._M_end; } 20414c3eb207Smrg 20424c3eb207Smrg template<bool _OtherConst = !_Const, 20434c3eb207Smrg typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>> 20444c3eb207Smrg requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 20454c3eb207Smrg friend constexpr bool 20464c3eb207Smrg operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x) 20474c3eb207Smrg { return __y.count() == 0 || __y.base() == __x._M_end; } 20484c3eb207Smrg 20494c3eb207Smrg friend _Sentinel<!_Const>; 20504c3eb207Smrg }; 20514c3eb207Smrg 20524c3eb207Smrg _Vp _M_base = _Vp(); 20534c3eb207Smrg range_difference_t<_Vp> _M_count = 0; 20544c3eb207Smrg 20554c3eb207Smrg public: 20564c3eb207Smrg take_view() requires default_initializable<_Vp> = default; 20574c3eb207Smrg 20584c3eb207Smrg constexpr 20594c3eb207Smrg take_view(_Vp base, range_difference_t<_Vp> __count) 20604c3eb207Smrg : _M_base(std::move(base)), _M_count(std::move(__count)) 20614c3eb207Smrg { } 20624c3eb207Smrg 20634c3eb207Smrg constexpr _Vp 20644c3eb207Smrg base() const& requires copy_constructible<_Vp> 20654c3eb207Smrg { return _M_base; } 20664c3eb207Smrg 20674c3eb207Smrg constexpr _Vp 20684c3eb207Smrg base() && 20694c3eb207Smrg { return std::move(_M_base); } 20704c3eb207Smrg 20714c3eb207Smrg constexpr auto 20724c3eb207Smrg begin() requires (!__detail::__simple_view<_Vp>) 20734c3eb207Smrg { 20744c3eb207Smrg if constexpr (sized_range<_Vp>) 20754c3eb207Smrg { 20764c3eb207Smrg if constexpr (random_access_range<_Vp>) 20774c3eb207Smrg return ranges::begin(_M_base); 20784c3eb207Smrg else 20794c3eb207Smrg { 20804c3eb207Smrg auto __sz = size(); 20814c3eb207Smrg return counted_iterator{ranges::begin(_M_base), __sz}; 20824c3eb207Smrg } 20834c3eb207Smrg } 20844c3eb207Smrg else 20854c3eb207Smrg return counted_iterator{ranges::begin(_M_base), _M_count}; 20864c3eb207Smrg } 20874c3eb207Smrg 20884c3eb207Smrg constexpr auto 20894c3eb207Smrg begin() const requires range<const _Vp> 20904c3eb207Smrg { 20914c3eb207Smrg if constexpr (sized_range<const _Vp>) 20924c3eb207Smrg { 20934c3eb207Smrg if constexpr (random_access_range<const _Vp>) 20944c3eb207Smrg return ranges::begin(_M_base); 20954c3eb207Smrg else 20964c3eb207Smrg { 20974c3eb207Smrg auto __sz = size(); 20984c3eb207Smrg return counted_iterator{ranges::begin(_M_base), __sz}; 20994c3eb207Smrg } 21004c3eb207Smrg } 21014c3eb207Smrg else 21024c3eb207Smrg return counted_iterator{ranges::begin(_M_base), _M_count}; 21034c3eb207Smrg } 21044c3eb207Smrg 21054c3eb207Smrg constexpr auto 21064c3eb207Smrg end() requires (!__detail::__simple_view<_Vp>) 21074c3eb207Smrg { 21084c3eb207Smrg if constexpr (sized_range<_Vp>) 21094c3eb207Smrg { 21104c3eb207Smrg if constexpr (random_access_range<_Vp>) 21114c3eb207Smrg return ranges::begin(_M_base) + size(); 21124c3eb207Smrg else 21134c3eb207Smrg return default_sentinel; 21144c3eb207Smrg } 21154c3eb207Smrg else 21164c3eb207Smrg return _Sentinel<false>{ranges::end(_M_base)}; 21174c3eb207Smrg } 21184c3eb207Smrg 21194c3eb207Smrg constexpr auto 21204c3eb207Smrg end() const requires range<const _Vp> 21214c3eb207Smrg { 21224c3eb207Smrg if constexpr (sized_range<const _Vp>) 21234c3eb207Smrg { 21244c3eb207Smrg if constexpr (random_access_range<const _Vp>) 21254c3eb207Smrg return ranges::begin(_M_base) + size(); 21264c3eb207Smrg else 21274c3eb207Smrg return default_sentinel; 21284c3eb207Smrg } 21294c3eb207Smrg else 21304c3eb207Smrg return _Sentinel<true>{ranges::end(_M_base)}; 21314c3eb207Smrg } 21324c3eb207Smrg 21334c3eb207Smrg constexpr auto 21344c3eb207Smrg size() requires sized_range<_Vp> 21354c3eb207Smrg { 21364c3eb207Smrg auto __n = ranges::size(_M_base); 21374c3eb207Smrg return std::min(__n, static_cast<decltype(__n)>(_M_count)); 21384c3eb207Smrg } 21394c3eb207Smrg 21404c3eb207Smrg constexpr auto 21414c3eb207Smrg size() const requires sized_range<const _Vp> 21424c3eb207Smrg { 21434c3eb207Smrg auto __n = ranges::size(_M_base); 21444c3eb207Smrg return std::min(__n, static_cast<decltype(__n)>(_M_count)); 21454c3eb207Smrg } 21464c3eb207Smrg }; 21474c3eb207Smrg 21484c3eb207Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 21494c3eb207Smrg // 3447. Deduction guides for take_view and drop_view have different 21504c3eb207Smrg // constraints 21514c3eb207Smrg template<typename _Range> 21524c3eb207Smrg take_view(_Range&&, range_difference_t<_Range>) 21534c3eb207Smrg -> take_view<views::all_t<_Range>>; 21544c3eb207Smrg 21554c3eb207Smrg template<typename _Tp> 21564c3eb207Smrg inline constexpr bool enable_borrowed_range<take_view<_Tp>> 21574c3eb207Smrg = enable_borrowed_range<_Tp>; 21584c3eb207Smrg 21594c3eb207Smrg namespace views 21604c3eb207Smrg { 21614c3eb207Smrg inline constexpr __adaptor::_RangeAdaptor take 21624c3eb207Smrg = [] <viewable_range _Range, typename _Tp> (_Range&& __r, _Tp&& __n) 21634c3eb207Smrg { 21644c3eb207Smrg return take_view{std::forward<_Range>(__r), std::forward<_Tp>(__n)}; 21654c3eb207Smrg }; 21664c3eb207Smrg } // namespace views 21674c3eb207Smrg 21684c3eb207Smrg template<view _Vp, typename _Pred> 21694c3eb207Smrg requires input_range<_Vp> && is_object_v<_Pred> 21704c3eb207Smrg && indirect_unary_predicate<const _Pred, iterator_t<_Vp>> 21714c3eb207Smrg class take_while_view : public view_interface<take_while_view<_Vp, _Pred>> 21724c3eb207Smrg { 21734c3eb207Smrg template<bool _Const> 21744c3eb207Smrg struct _Sentinel 21754c3eb207Smrg { 21764c3eb207Smrg private: 21774c3eb207Smrg using _Base = __detail::__maybe_const_t<_Const, _Vp>; 21784c3eb207Smrg 21794c3eb207Smrg sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 21804c3eb207Smrg const _Pred* _M_pred = nullptr; 21814c3eb207Smrg 21824c3eb207Smrg public: 21834c3eb207Smrg _Sentinel() = default; 21844c3eb207Smrg 21854c3eb207Smrg constexpr explicit 21864c3eb207Smrg _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred) 21874c3eb207Smrg : _M_end(__end), _M_pred(__pred) 21884c3eb207Smrg { } 21894c3eb207Smrg 21904c3eb207Smrg constexpr 21914c3eb207Smrg _Sentinel(_Sentinel<!_Const> __s) 21924c3eb207Smrg requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 21934c3eb207Smrg : _M_end(__s._M_end), _M_pred(__s._M_pred) 21944c3eb207Smrg { } 21954c3eb207Smrg 21964c3eb207Smrg constexpr sentinel_t<_Base> 21974c3eb207Smrg base() const { return _M_end; } 21984c3eb207Smrg 21994c3eb207Smrg friend constexpr bool 22004c3eb207Smrg operator==(const iterator_t<_Base>& __x, const _Sentinel& __y) 22014c3eb207Smrg { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); } 22024c3eb207Smrg 22034c3eb207Smrg template<bool _OtherConst = !_Const, 22044c3eb207Smrg typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>> 22054c3eb207Smrg requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 22064c3eb207Smrg friend constexpr bool 22074c3eb207Smrg operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y) 22084c3eb207Smrg { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); } 22094c3eb207Smrg 22104c3eb207Smrg friend _Sentinel<!_Const>; 22114c3eb207Smrg }; 22124c3eb207Smrg 22134c3eb207Smrg _Vp _M_base = _Vp(); 22144c3eb207Smrg __detail::__box<_Pred> _M_pred; 22154c3eb207Smrg 22164c3eb207Smrg public: 2217*4ac76180Smrg take_while_view() requires default_initializable<_Vp> = default; 22184c3eb207Smrg 22194c3eb207Smrg constexpr 22204c3eb207Smrg take_while_view(_Vp base, _Pred __pred) 22214c3eb207Smrg : _M_base(std::move(base)), _M_pred(std::move(__pred)) 22224c3eb207Smrg { 22234c3eb207Smrg } 22244c3eb207Smrg 22254c3eb207Smrg constexpr _Vp 22264c3eb207Smrg base() const& requires copy_constructible<_Vp> 22274c3eb207Smrg { return _M_base; } 22284c3eb207Smrg 22294c3eb207Smrg constexpr _Vp 22304c3eb207Smrg base() && 22314c3eb207Smrg { return std::move(_M_base); } 22324c3eb207Smrg 22334c3eb207Smrg constexpr const _Pred& 22344c3eb207Smrg pred() const 22354c3eb207Smrg { return *_M_pred; } 22364c3eb207Smrg 22374c3eb207Smrg constexpr auto 22384c3eb207Smrg begin() requires (!__detail::__simple_view<_Vp>) 22394c3eb207Smrg { return ranges::begin(_M_base); } 22404c3eb207Smrg 22414c3eb207Smrg constexpr auto 22424c3eb207Smrg begin() const requires range<const _Vp> 22434c3eb207Smrg && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>> 22444c3eb207Smrg { return ranges::begin(_M_base); } 22454c3eb207Smrg 22464c3eb207Smrg constexpr auto 22474c3eb207Smrg end() requires (!__detail::__simple_view<_Vp>) 22484c3eb207Smrg { return _Sentinel<false>(ranges::end(_M_base), 22494c3eb207Smrg std::__addressof(*_M_pred)); } 22504c3eb207Smrg 22514c3eb207Smrg constexpr auto 22524c3eb207Smrg end() const requires range<const _Vp> 22534c3eb207Smrg && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>> 22544c3eb207Smrg { return _Sentinel<true>(ranges::end(_M_base), 22554c3eb207Smrg std::__addressof(*_M_pred)); } 22564c3eb207Smrg }; 22574c3eb207Smrg 22584c3eb207Smrg template<typename _Range, typename _Pred> 22594c3eb207Smrg take_while_view(_Range&&, _Pred) 22604c3eb207Smrg -> take_while_view<views::all_t<_Range>, _Pred>; 22614c3eb207Smrg 22624c3eb207Smrg namespace views 22634c3eb207Smrg { 22644c3eb207Smrg inline constexpr __adaptor::_RangeAdaptor take_while 22654c3eb207Smrg = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p) 22664c3eb207Smrg { 22674c3eb207Smrg return take_while_view{std::forward<_Range>(__r), std::forward<_Pred>(__p)}; 22684c3eb207Smrg }; 22694c3eb207Smrg } // namespace views 22704c3eb207Smrg 22714c3eb207Smrg template<view _Vp> 22724c3eb207Smrg class drop_view : public view_interface<drop_view<_Vp>> 22734c3eb207Smrg { 22744c3eb207Smrg private: 22754c3eb207Smrg _Vp _M_base = _Vp(); 22764c3eb207Smrg range_difference_t<_Vp> _M_count = 0; 22774c3eb207Smrg 22784c3eb207Smrg // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies 22794c3eb207Smrg // both random_access_range and sized_range. Otherwise, cache its result. 22804c3eb207Smrg static constexpr bool _S_needs_cached_begin 22814c3eb207Smrg = !(random_access_range<const _Vp> && sized_range<const _Vp>); 22824c3eb207Smrg [[no_unique_address]] 22834c3eb207Smrg __detail::__maybe_present_t<_S_needs_cached_begin, 22844c3eb207Smrg __detail::_CachedPosition<_Vp>> 22854c3eb207Smrg _M_cached_begin; 22864c3eb207Smrg 22874c3eb207Smrg public: 22884c3eb207Smrg drop_view() requires default_initializable<_Vp> = default; 22894c3eb207Smrg 22904c3eb207Smrg constexpr 22914c3eb207Smrg drop_view(_Vp __base, range_difference_t<_Vp> __count) 22924c3eb207Smrg : _M_base(std::move(__base)), _M_count(__count) 22934c3eb207Smrg { __glibcxx_assert(__count >= 0); } 22944c3eb207Smrg 22954c3eb207Smrg constexpr _Vp 22964c3eb207Smrg base() const& requires copy_constructible<_Vp> 22974c3eb207Smrg { return _M_base; } 22984c3eb207Smrg 22994c3eb207Smrg constexpr _Vp 23004c3eb207Smrg base() && 23014c3eb207Smrg { return std::move(_M_base); } 23024c3eb207Smrg 23034c3eb207Smrg // This overload is disabled for simple views with constant-time begin(). 23044c3eb207Smrg constexpr auto 23054c3eb207Smrg begin() 23064c3eb207Smrg requires (!(__detail::__simple_view<_Vp> 23074c3eb207Smrg && random_access_range<const _Vp> 23084c3eb207Smrg && sized_range<const _Vp>)) 23094c3eb207Smrg { 23104c3eb207Smrg if constexpr (_S_needs_cached_begin) 23114c3eb207Smrg if (_M_cached_begin._M_has_value()) 23124c3eb207Smrg return _M_cached_begin._M_get(_M_base); 23134c3eb207Smrg 23144c3eb207Smrg auto __it = ranges::next(ranges::begin(_M_base), 23154c3eb207Smrg _M_count, ranges::end(_M_base)); 23164c3eb207Smrg if constexpr (_S_needs_cached_begin) 23174c3eb207Smrg _M_cached_begin._M_set(_M_base, __it); 23184c3eb207Smrg return __it; 23194c3eb207Smrg } 23204c3eb207Smrg 23214c3eb207Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 23224c3eb207Smrg // 3482. drop_view's const begin should additionally require sized_range 23234c3eb207Smrg constexpr auto 23244c3eb207Smrg begin() const 23254c3eb207Smrg requires random_access_range<const _Vp> && sized_range<const _Vp> 23264c3eb207Smrg { 23274c3eb207Smrg return ranges::next(ranges::begin(_M_base), _M_count, 23284c3eb207Smrg ranges::end(_M_base)); 23294c3eb207Smrg } 23304c3eb207Smrg 23314c3eb207Smrg constexpr auto 23324c3eb207Smrg end() requires (!__detail::__simple_view<_Vp>) 23334c3eb207Smrg { return ranges::end(_M_base); } 23344c3eb207Smrg 23354c3eb207Smrg constexpr auto 23364c3eb207Smrg end() const requires range<const _Vp> 23374c3eb207Smrg { return ranges::end(_M_base); } 23384c3eb207Smrg 23394c3eb207Smrg constexpr auto 23404c3eb207Smrg size() requires sized_range<_Vp> 23414c3eb207Smrg { 23424c3eb207Smrg const auto __s = ranges::size(_M_base); 23434c3eb207Smrg const auto __c = static_cast<decltype(__s)>(_M_count); 23444c3eb207Smrg return __s < __c ? 0 : __s - __c; 23454c3eb207Smrg } 23464c3eb207Smrg 23474c3eb207Smrg constexpr auto 23484c3eb207Smrg size() const requires sized_range<const _Vp> 23494c3eb207Smrg { 23504c3eb207Smrg const auto __s = ranges::size(_M_base); 23514c3eb207Smrg const auto __c = static_cast<decltype(__s)>(_M_count); 23524c3eb207Smrg return __s < __c ? 0 : __s - __c; 23534c3eb207Smrg } 23544c3eb207Smrg }; 23554c3eb207Smrg 23564c3eb207Smrg template<typename _Range> 23574c3eb207Smrg drop_view(_Range&&, range_difference_t<_Range>) 23584c3eb207Smrg -> drop_view<views::all_t<_Range>>; 23594c3eb207Smrg 23604c3eb207Smrg template<typename _Tp> 23614c3eb207Smrg inline constexpr bool enable_borrowed_range<drop_view<_Tp>> 23624c3eb207Smrg = enable_borrowed_range<_Tp>; 23634c3eb207Smrg 23644c3eb207Smrg namespace views 23654c3eb207Smrg { 23664c3eb207Smrg inline constexpr __adaptor::_RangeAdaptor drop 23674c3eb207Smrg = [] <viewable_range _Range, typename _Tp> (_Range&& __r, _Tp&& __n) 23684c3eb207Smrg { 23694c3eb207Smrg return drop_view{std::forward<_Range>(__r), std::forward<_Tp>(__n)}; 23704c3eb207Smrg }; 23714c3eb207Smrg } // namespace views 23724c3eb207Smrg 23734c3eb207Smrg template<view _Vp, typename _Pred> 23744c3eb207Smrg requires input_range<_Vp> && is_object_v<_Pred> 23754c3eb207Smrg && indirect_unary_predicate<const _Pred, iterator_t<_Vp>> 23764c3eb207Smrg class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>> 23774c3eb207Smrg { 23784c3eb207Smrg private: 23794c3eb207Smrg _Vp _M_base = _Vp(); 23804c3eb207Smrg __detail::__box<_Pred> _M_pred; 23814c3eb207Smrg [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin; 23824c3eb207Smrg 23834c3eb207Smrg public: 2384*4ac76180Smrg drop_while_view() requires default_initializable<_Vp> = default; 23854c3eb207Smrg 23864c3eb207Smrg constexpr 23874c3eb207Smrg drop_while_view(_Vp __base, _Pred __pred) 23884c3eb207Smrg : _M_base(std::move(__base)), _M_pred(std::move(__pred)) 23894c3eb207Smrg { } 23904c3eb207Smrg 23914c3eb207Smrg constexpr _Vp 23924c3eb207Smrg base() const& requires copy_constructible<_Vp> 23934c3eb207Smrg { return _M_base; } 23944c3eb207Smrg 23954c3eb207Smrg constexpr _Vp 23964c3eb207Smrg base() && 23974c3eb207Smrg { return std::move(_M_base); } 23984c3eb207Smrg 23994c3eb207Smrg constexpr const _Pred& 24004c3eb207Smrg pred() const 24014c3eb207Smrg { return *_M_pred; } 24024c3eb207Smrg 24034c3eb207Smrg constexpr auto 24044c3eb207Smrg begin() 24054c3eb207Smrg { 24064c3eb207Smrg if (_M_cached_begin._M_has_value()) 24074c3eb207Smrg return _M_cached_begin._M_get(_M_base); 24084c3eb207Smrg 24094c3eb207Smrg __glibcxx_assert(_M_pred.has_value()); 24104c3eb207Smrg auto __it = __detail::find_if_not(ranges::begin(_M_base), 24114c3eb207Smrg ranges::end(_M_base), 24124c3eb207Smrg std::cref(*_M_pred)); 24134c3eb207Smrg _M_cached_begin._M_set(_M_base, __it); 24144c3eb207Smrg return __it; 24154c3eb207Smrg } 24164c3eb207Smrg 24174c3eb207Smrg constexpr auto 24184c3eb207Smrg end() 24194c3eb207Smrg { return ranges::end(_M_base); } 24204c3eb207Smrg }; 24214c3eb207Smrg 24224c3eb207Smrg template<typename _Range, typename _Pred> 24234c3eb207Smrg drop_while_view(_Range&&, _Pred) 24244c3eb207Smrg -> drop_while_view<views::all_t<_Range>, _Pred>; 24254c3eb207Smrg 24264c3eb207Smrg template<typename _Tp, typename _Pred> 24274c3eb207Smrg inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>> 24284c3eb207Smrg = enable_borrowed_range<_Tp>; 24294c3eb207Smrg 24304c3eb207Smrg namespace views 24314c3eb207Smrg { 24324c3eb207Smrg inline constexpr __adaptor::_RangeAdaptor drop_while 24334c3eb207Smrg = [] <viewable_range _Range, typename _Pred> (_Range&& __r, _Pred&& __p) 24344c3eb207Smrg { 24354c3eb207Smrg return drop_while_view{std::forward<_Range>(__r), 24364c3eb207Smrg std::forward<_Pred>(__p)}; 24374c3eb207Smrg }; 24384c3eb207Smrg } // namespace views 24394c3eb207Smrg 24404c3eb207Smrg template<input_range _Vp> 24414c3eb207Smrg requires view<_Vp> && input_range<range_reference_t<_Vp>> 24424c3eb207Smrg && (is_reference_v<range_reference_t<_Vp>> 24434c3eb207Smrg || view<range_value_t<_Vp>>) 24444c3eb207Smrg class join_view : public view_interface<join_view<_Vp>> 24454c3eb207Smrg { 24464c3eb207Smrg private: 24474c3eb207Smrg using _InnerRange = range_reference_t<_Vp>; 24484c3eb207Smrg 24494c3eb207Smrg template<bool _Const> 24504c3eb207Smrg using _Base = __detail::__maybe_const_t<_Const, _Vp>; 24514c3eb207Smrg 24524c3eb207Smrg template<bool _Const> 24534c3eb207Smrg using _Outer_iter = iterator_t<_Base<_Const>>; 24544c3eb207Smrg 24554c3eb207Smrg template<bool _Const> 24564c3eb207Smrg using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>; 24574c3eb207Smrg 24584c3eb207Smrg template<bool _Const> 24594c3eb207Smrg static constexpr bool _S_ref_is_glvalue 24604c3eb207Smrg = is_reference_v<range_reference_t<_Base<_Const>>>; 24614c3eb207Smrg 24624c3eb207Smrg template<bool _Const> 24634c3eb207Smrg struct __iter_cat 24644c3eb207Smrg { }; 24654c3eb207Smrg 24664c3eb207Smrg template<bool _Const> 24674c3eb207Smrg requires _S_ref_is_glvalue<_Const> 24684c3eb207Smrg && forward_range<_Base<_Const>> 24694c3eb207Smrg && forward_range<range_reference_t<_Base<_Const>>> 24704c3eb207Smrg struct __iter_cat<_Const> 24714c3eb207Smrg { 24724c3eb207Smrg private: 24734c3eb207Smrg static constexpr auto 24744c3eb207Smrg _S_iter_cat() 24754c3eb207Smrg { 24764c3eb207Smrg using _Outer_iter = join_view::_Outer_iter<_Const>; 24774c3eb207Smrg using _Inner_iter = join_view::_Inner_iter<_Const>; 24784c3eb207Smrg using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category; 24794c3eb207Smrg using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category; 24804c3eb207Smrg if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag> 24814c3eb207Smrg && derived_from<_InnerCat, bidirectional_iterator_tag>) 24824c3eb207Smrg return bidirectional_iterator_tag{}; 24834c3eb207Smrg else if constexpr (derived_from<_OuterCat, forward_iterator_tag> 24844c3eb207Smrg && derived_from<_InnerCat, forward_iterator_tag>) 24854c3eb207Smrg return forward_iterator_tag{}; 24864c3eb207Smrg else 24874c3eb207Smrg return input_iterator_tag{}; 24884c3eb207Smrg } 24894c3eb207Smrg public: 24904c3eb207Smrg using iterator_category = decltype(_S_iter_cat()); 24914c3eb207Smrg }; 24924c3eb207Smrg 24934c3eb207Smrg template<bool _Const> 24944c3eb207Smrg struct _Sentinel; 24954c3eb207Smrg 24964c3eb207Smrg template<bool _Const> 24974c3eb207Smrg struct _Iterator : __iter_cat<_Const> 24984c3eb207Smrg { 24994c3eb207Smrg private: 25004c3eb207Smrg using _Parent = __detail::__maybe_const_t<_Const, join_view>; 25014c3eb207Smrg using _Base = join_view::_Base<_Const>; 25024c3eb207Smrg 25034c3eb207Smrg static constexpr bool _S_ref_is_glvalue 25044c3eb207Smrg = join_view::_S_ref_is_glvalue<_Const>; 25054c3eb207Smrg 25064c3eb207Smrg constexpr void 25074c3eb207Smrg _M_satisfy() 25084c3eb207Smrg { 25094c3eb207Smrg auto __update_inner = [this] (range_reference_t<_Base> __x) -> auto& 25104c3eb207Smrg { 25114c3eb207Smrg if constexpr (_S_ref_is_glvalue) 25124c3eb207Smrg return __x; 25134c3eb207Smrg else 25144c3eb207Smrg return (_M_parent->_M_inner = views::all(std::move(__x))); 25154c3eb207Smrg }; 25164c3eb207Smrg 25174c3eb207Smrg for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer) 25184c3eb207Smrg { 25194c3eb207Smrg auto& __inner = __update_inner(*_M_outer); 25204c3eb207Smrg _M_inner = ranges::begin(__inner); 25214c3eb207Smrg if (_M_inner != ranges::end(__inner)) 25224c3eb207Smrg return; 25234c3eb207Smrg } 25244c3eb207Smrg 25254c3eb207Smrg if constexpr (_S_ref_is_glvalue) 25264c3eb207Smrg _M_inner = _Inner_iter(); 25274c3eb207Smrg } 25284c3eb207Smrg 25294c3eb207Smrg static constexpr auto 25304c3eb207Smrg _S_iter_concept() 25314c3eb207Smrg { 25324c3eb207Smrg if constexpr (_S_ref_is_glvalue 25334c3eb207Smrg && bidirectional_range<_Base> 25344c3eb207Smrg && bidirectional_range<range_reference_t<_Base>>) 25354c3eb207Smrg return bidirectional_iterator_tag{}; 25364c3eb207Smrg else if constexpr (_S_ref_is_glvalue 25374c3eb207Smrg && forward_range<_Base> 25384c3eb207Smrg && forward_range<range_reference_t<_Base>>) 25394c3eb207Smrg return forward_iterator_tag{}; 25404c3eb207Smrg else 25414c3eb207Smrg return input_iterator_tag{}; 25424c3eb207Smrg } 25434c3eb207Smrg 25444c3eb207Smrg using _Outer_iter = join_view::_Outer_iter<_Const>; 25454c3eb207Smrg using _Inner_iter = join_view::_Inner_iter<_Const>; 25464c3eb207Smrg 25474c3eb207Smrg _Outer_iter _M_outer = _Outer_iter(); 25484c3eb207Smrg _Inner_iter _M_inner = _Inner_iter(); 25494c3eb207Smrg _Parent* _M_parent = nullptr; 25504c3eb207Smrg 25514c3eb207Smrg public: 25524c3eb207Smrg using iterator_concept = decltype(_S_iter_concept()); 25534c3eb207Smrg // iterator_category defined in __join_view_iter_cat 25544c3eb207Smrg using value_type = range_value_t<range_reference_t<_Base>>; 25554c3eb207Smrg using difference_type 25564c3eb207Smrg = common_type_t<range_difference_t<_Base>, 25574c3eb207Smrg range_difference_t<range_reference_t<_Base>>>; 25584c3eb207Smrg 25594c3eb207Smrg _Iterator() requires (default_initializable<_Outer_iter> 25604c3eb207Smrg && default_initializable<_Inner_iter>) 25614c3eb207Smrg = default; 25624c3eb207Smrg 25634c3eb207Smrg constexpr 25644c3eb207Smrg _Iterator(_Parent* __parent, _Outer_iter __outer) 25654c3eb207Smrg : _M_outer(std::move(__outer)), 25664c3eb207Smrg _M_parent(__parent) 25674c3eb207Smrg { _M_satisfy(); } 25684c3eb207Smrg 25694c3eb207Smrg constexpr 25704c3eb207Smrg _Iterator(_Iterator<!_Const> __i) 25714c3eb207Smrg requires _Const 25724c3eb207Smrg && convertible_to<iterator_t<_Vp>, _Outer_iter> 25734c3eb207Smrg && convertible_to<iterator_t<_InnerRange>, _Inner_iter> 25744c3eb207Smrg : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)), 25754c3eb207Smrg _M_parent(__i._M_parent) 25764c3eb207Smrg { } 25774c3eb207Smrg 25784c3eb207Smrg constexpr decltype(auto) 25794c3eb207Smrg operator*() const 25804c3eb207Smrg { return *_M_inner; } 25814c3eb207Smrg 25824c3eb207Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 25834c3eb207Smrg // 3500. join_view::iterator::operator->() is bogus 25844c3eb207Smrg constexpr _Inner_iter 25854c3eb207Smrg operator->() const 25864c3eb207Smrg requires __detail::__has_arrow<_Inner_iter> 25874c3eb207Smrg && copyable<_Inner_iter> 25884c3eb207Smrg { return _M_inner; } 25894c3eb207Smrg 25904c3eb207Smrg constexpr _Iterator& 25914c3eb207Smrg operator++() 25924c3eb207Smrg { 25934c3eb207Smrg auto&& __inner_range = [this] () -> auto&& { 25944c3eb207Smrg if constexpr (_S_ref_is_glvalue) 25954c3eb207Smrg return *_M_outer; 25964c3eb207Smrg else 25974c3eb207Smrg return _M_parent->_M_inner; 25984c3eb207Smrg }(); 25994c3eb207Smrg if (++_M_inner == ranges::end(__inner_range)) 26004c3eb207Smrg { 26014c3eb207Smrg ++_M_outer; 26024c3eb207Smrg _M_satisfy(); 26034c3eb207Smrg } 26044c3eb207Smrg return *this; 26054c3eb207Smrg } 26064c3eb207Smrg 26074c3eb207Smrg constexpr void 26084c3eb207Smrg operator++(int) 26094c3eb207Smrg { ++*this; } 26104c3eb207Smrg 26114c3eb207Smrg constexpr _Iterator 26124c3eb207Smrg operator++(int) 26134c3eb207Smrg requires _S_ref_is_glvalue && forward_range<_Base> 26144c3eb207Smrg && forward_range<range_reference_t<_Base>> 26154c3eb207Smrg { 26164c3eb207Smrg auto __tmp = *this; 26174c3eb207Smrg ++*this; 26184c3eb207Smrg return __tmp; 26194c3eb207Smrg } 26204c3eb207Smrg 26214c3eb207Smrg constexpr _Iterator& 26224c3eb207Smrg operator--() 26234c3eb207Smrg requires _S_ref_is_glvalue && bidirectional_range<_Base> 26244c3eb207Smrg && bidirectional_range<range_reference_t<_Base>> 26254c3eb207Smrg && common_range<range_reference_t<_Base>> 26264c3eb207Smrg { 26274c3eb207Smrg if (_M_outer == ranges::end(_M_parent->_M_base)) 26284c3eb207Smrg _M_inner = ranges::end(*--_M_outer); 26294c3eb207Smrg while (_M_inner == ranges::begin(*_M_outer)) 26304c3eb207Smrg _M_inner = ranges::end(*--_M_outer); 26314c3eb207Smrg --_M_inner; 26324c3eb207Smrg return *this; 26334c3eb207Smrg } 26344c3eb207Smrg 26354c3eb207Smrg constexpr _Iterator 26364c3eb207Smrg operator--(int) 26374c3eb207Smrg requires _S_ref_is_glvalue && bidirectional_range<_Base> 26384c3eb207Smrg && bidirectional_range<range_reference_t<_Base>> 26394c3eb207Smrg && common_range<range_reference_t<_Base>> 26404c3eb207Smrg { 26414c3eb207Smrg auto __tmp = *this; 26424c3eb207Smrg --*this; 26434c3eb207Smrg return __tmp; 26444c3eb207Smrg } 26454c3eb207Smrg 26464c3eb207Smrg friend constexpr bool 26474c3eb207Smrg operator==(const _Iterator& __x, const _Iterator& __y) 26484c3eb207Smrg requires _S_ref_is_glvalue 26494c3eb207Smrg && equality_comparable<_Outer_iter> 26504c3eb207Smrg && equality_comparable<_Inner_iter> 26514c3eb207Smrg { 26524c3eb207Smrg return (__x._M_outer == __y._M_outer 26534c3eb207Smrg && __x._M_inner == __y._M_inner); 26544c3eb207Smrg } 26554c3eb207Smrg 26564c3eb207Smrg friend constexpr decltype(auto) 26574c3eb207Smrg iter_move(const _Iterator& __i) 26584c3eb207Smrg noexcept(noexcept(ranges::iter_move(__i._M_inner))) 26594c3eb207Smrg { return ranges::iter_move(__i._M_inner); } 26604c3eb207Smrg 26614c3eb207Smrg friend constexpr void 26624c3eb207Smrg iter_swap(const _Iterator& __x, const _Iterator& __y) 26634c3eb207Smrg noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner))) 26644c3eb207Smrg requires indirectly_swappable<_Inner_iter> 26654c3eb207Smrg { return ranges::iter_swap(__x._M_inner, __y._M_inner); } 26664c3eb207Smrg 26674c3eb207Smrg friend _Iterator<!_Const>; 26684c3eb207Smrg template<bool> friend struct _Sentinel; 26694c3eb207Smrg }; 26704c3eb207Smrg 26714c3eb207Smrg template<bool _Const> 26724c3eb207Smrg struct _Sentinel 26734c3eb207Smrg { 26744c3eb207Smrg private: 26754c3eb207Smrg using _Parent = __detail::__maybe_const_t<_Const, join_view>; 26764c3eb207Smrg using _Base = join_view::_Base<_Const>; 26774c3eb207Smrg 26784c3eb207Smrg template<bool _Const2> 26794c3eb207Smrg constexpr bool 26804c3eb207Smrg __equal(const _Iterator<_Const2>& __i) const 26814c3eb207Smrg { return __i._M_outer == _M_end; } 26824c3eb207Smrg 26834c3eb207Smrg sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 26844c3eb207Smrg 26854c3eb207Smrg public: 26864c3eb207Smrg _Sentinel() = default; 26874c3eb207Smrg 26884c3eb207Smrg constexpr explicit 26894c3eb207Smrg _Sentinel(_Parent* __parent) 26904c3eb207Smrg : _M_end(ranges::end(__parent->_M_base)) 26914c3eb207Smrg { } 26924c3eb207Smrg 26934c3eb207Smrg constexpr 26944c3eb207Smrg _Sentinel(_Sentinel<!_Const> __s) 26954c3eb207Smrg requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 26964c3eb207Smrg : _M_end(std::move(__s._M_end)) 26974c3eb207Smrg { } 26984c3eb207Smrg 26994c3eb207Smrg template<bool _Const2> 27004c3eb207Smrg requires sentinel_for<sentinel_t<_Base>, 27014c3eb207Smrg iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>> 27024c3eb207Smrg friend constexpr bool 27034c3eb207Smrg operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y) 27044c3eb207Smrg { return __y.__equal(__x); } 27054c3eb207Smrg 27064c3eb207Smrg friend _Sentinel<!_Const>; 27074c3eb207Smrg }; 27084c3eb207Smrg 27094c3eb207Smrg _Vp _M_base = _Vp(); 27104c3eb207Smrg 27114c3eb207Smrg // XXX: _M_inner is "present only when !is_reference_v<_InnerRange>" 27124c3eb207Smrg [[no_unique_address]] 27134c3eb207Smrg __detail::__maybe_present_t<!is_reference_v<_InnerRange>, 27144c3eb207Smrg views::all_t<_InnerRange>> _M_inner; 27154c3eb207Smrg 27164c3eb207Smrg public: 27174c3eb207Smrg join_view() requires default_initializable<_Vp> = default; 27184c3eb207Smrg 27194c3eb207Smrg constexpr explicit 27204c3eb207Smrg join_view(_Vp __base) 27214c3eb207Smrg : _M_base(std::move(__base)) 27224c3eb207Smrg { } 27234c3eb207Smrg 27244c3eb207Smrg constexpr _Vp 27254c3eb207Smrg base() const& requires copy_constructible<_Vp> 27264c3eb207Smrg { return _M_base; } 27274c3eb207Smrg 27284c3eb207Smrg constexpr _Vp 27294c3eb207Smrg base() && 27304c3eb207Smrg { return std::move(_M_base); } 27314c3eb207Smrg 27324c3eb207Smrg constexpr auto 27334c3eb207Smrg begin() 27344c3eb207Smrg { 27354c3eb207Smrg constexpr bool __use_const 27364c3eb207Smrg = (__detail::__simple_view<_Vp> 27374c3eb207Smrg && is_reference_v<range_reference_t<_Vp>>); 27384c3eb207Smrg return _Iterator<__use_const>{this, ranges::begin(_M_base)}; 27394c3eb207Smrg } 27404c3eb207Smrg 27414c3eb207Smrg constexpr auto 27424c3eb207Smrg begin() const 27434c3eb207Smrg requires input_range<const _Vp> 27444c3eb207Smrg && is_reference_v<range_reference_t<const _Vp>> 27454c3eb207Smrg { 27464c3eb207Smrg return _Iterator<true>{this, ranges::begin(_M_base)}; 27474c3eb207Smrg } 27484c3eb207Smrg 27494c3eb207Smrg constexpr auto 27504c3eb207Smrg end() 27514c3eb207Smrg { 27524c3eb207Smrg if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange> 27534c3eb207Smrg && forward_range<_InnerRange> 27544c3eb207Smrg && common_range<_Vp> && common_range<_InnerRange>) 27554c3eb207Smrg return _Iterator<__detail::__simple_view<_Vp>>{this, 27564c3eb207Smrg ranges::end(_M_base)}; 27574c3eb207Smrg else 27584c3eb207Smrg return _Sentinel<__detail::__simple_view<_Vp>>{this}; 27594c3eb207Smrg } 27604c3eb207Smrg 27614c3eb207Smrg constexpr auto 27624c3eb207Smrg end() const 27634c3eb207Smrg requires input_range<const _Vp> 27644c3eb207Smrg && is_reference_v<range_reference_t<const _Vp>> 27654c3eb207Smrg { 27664c3eb207Smrg if constexpr (forward_range<const _Vp> 27674c3eb207Smrg && is_reference_v<range_reference_t<const _Vp>> 27684c3eb207Smrg && forward_range<range_reference_t<const _Vp>> 27694c3eb207Smrg && common_range<const _Vp> 27704c3eb207Smrg && common_range<range_reference_t<const _Vp>>) 27714c3eb207Smrg return _Iterator<true>{this, ranges::end(_M_base)}; 27724c3eb207Smrg else 27734c3eb207Smrg return _Sentinel<true>{this}; 27744c3eb207Smrg } 27754c3eb207Smrg }; 27764c3eb207Smrg 27774c3eb207Smrg template<typename _Range> 27784c3eb207Smrg explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>; 27794c3eb207Smrg 27804c3eb207Smrg namespace views 27814c3eb207Smrg { 27824c3eb207Smrg inline constexpr __adaptor::_RangeAdaptorClosure join 27834c3eb207Smrg = [] <viewable_range _Range> (_Range&& __r) 27844c3eb207Smrg { 27854c3eb207Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 27864c3eb207Smrg // 3474. Nesting join_views is broken because of CTAD 27874c3eb207Smrg return join_view<views::all_t<_Range>>{std::forward<_Range>(__r)}; 27884c3eb207Smrg }; 27894c3eb207Smrg } // namespace views 27904c3eb207Smrg 27914c3eb207Smrg namespace __detail 27924c3eb207Smrg { 27934c3eb207Smrg template<auto> 27944c3eb207Smrg struct __require_constant; 27954c3eb207Smrg 27964c3eb207Smrg template<typename _Range> 27974c3eb207Smrg concept __tiny_range = sized_range<_Range> 27984c3eb207Smrg && requires 27994c3eb207Smrg { typename __require_constant<remove_reference_t<_Range>::size()>; } 28004c3eb207Smrg && (remove_reference_t<_Range>::size() <= 1); 28014c3eb207Smrg 28024c3eb207Smrg template<typename _Base> 28034c3eb207Smrg struct __split_view_outer_iter_cat 28044c3eb207Smrg { }; 28054c3eb207Smrg 28064c3eb207Smrg template<forward_range _Base> 28074c3eb207Smrg struct __split_view_outer_iter_cat<_Base> 28084c3eb207Smrg { using iterator_category = input_iterator_tag; }; 28094c3eb207Smrg 28104c3eb207Smrg template<typename _Base> 28114c3eb207Smrg struct __split_view_inner_iter_cat 28124c3eb207Smrg { }; 28134c3eb207Smrg 28144c3eb207Smrg template<forward_range _Base> 28154c3eb207Smrg struct __split_view_inner_iter_cat<_Base> 28164c3eb207Smrg { 28174c3eb207Smrg private: 28184c3eb207Smrg static constexpr auto 28194c3eb207Smrg _S_iter_cat() 28204c3eb207Smrg { 28214c3eb207Smrg using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category; 28224c3eb207Smrg if constexpr (derived_from<_Cat, forward_iterator_tag>) 28234c3eb207Smrg return forward_iterator_tag{}; 28244c3eb207Smrg else 28254c3eb207Smrg return _Cat{}; 28264c3eb207Smrg } 28274c3eb207Smrg public: 28284c3eb207Smrg using iterator_category = decltype(_S_iter_cat()); 28294c3eb207Smrg }; 28304c3eb207Smrg } 28314c3eb207Smrg 28324c3eb207Smrg template<input_range _Vp, forward_range _Pattern> 28334c3eb207Smrg requires view<_Vp> && view<_Pattern> 28344c3eb207Smrg && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>, 28354c3eb207Smrg ranges::equal_to> 28364c3eb207Smrg && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>) 28374c3eb207Smrg class split_view : public view_interface<split_view<_Vp, _Pattern>> 28384c3eb207Smrg { 28394c3eb207Smrg private: 28404c3eb207Smrg template<bool _Const> 28414c3eb207Smrg using _Base = __detail::__maybe_const_t<_Const, _Vp>; 28424c3eb207Smrg 28434c3eb207Smrg template<bool _Const> 28444c3eb207Smrg struct _InnerIter; 28454c3eb207Smrg 28464c3eb207Smrg template<bool _Const> 28474c3eb207Smrg struct _OuterIter 28484c3eb207Smrg : __detail::__split_view_outer_iter_cat<_Base<_Const>> 28494c3eb207Smrg { 28504c3eb207Smrg private: 28514c3eb207Smrg using _Parent = __detail::__maybe_const_t<_Const, split_view>; 28524c3eb207Smrg using _Base = split_view::_Base<_Const>; 28534c3eb207Smrg 28544c3eb207Smrg constexpr bool 28554c3eb207Smrg __at_end() const 28564c3eb207Smrg { return __current() == ranges::end(_M_parent->_M_base); } 28574c3eb207Smrg 28584c3eb207Smrg // [range.split.outer] p1 28594c3eb207Smrg // Many of the following specifications refer to the notional member 28604c3eb207Smrg // current of outer-iterator. current is equivalent to current_ if 28614c3eb207Smrg // V models forward_range, and parent_->current_ otherwise. 28624c3eb207Smrg constexpr auto& 28634c3eb207Smrg __current() noexcept 28644c3eb207Smrg { 28654c3eb207Smrg if constexpr (forward_range<_Vp>) 28664c3eb207Smrg return _M_current; 28674c3eb207Smrg else 28684c3eb207Smrg return _M_parent->_M_current; 28694c3eb207Smrg } 28704c3eb207Smrg 28714c3eb207Smrg constexpr auto& 28724c3eb207Smrg __current() const noexcept 28734c3eb207Smrg { 28744c3eb207Smrg if constexpr (forward_range<_Vp>) 28754c3eb207Smrg return _M_current; 28764c3eb207Smrg else 28774c3eb207Smrg return _M_parent->_M_current; 28784c3eb207Smrg } 28794c3eb207Smrg 28804c3eb207Smrg _Parent* _M_parent = nullptr; 28814c3eb207Smrg 28824c3eb207Smrg // XXX: _M_current is present only if "V models forward_range" 28834c3eb207Smrg [[no_unique_address]] 28844c3eb207Smrg __detail::__maybe_present_t<forward_range<_Vp>, 28854c3eb207Smrg iterator_t<_Base>> _M_current; 28864c3eb207Smrg 28874c3eb207Smrg public: 28884c3eb207Smrg using iterator_concept = conditional_t<forward_range<_Base>, 28894c3eb207Smrg forward_iterator_tag, 28904c3eb207Smrg input_iterator_tag>; 28914c3eb207Smrg // iterator_category defined in __split_view_outer_iter_cat 28924c3eb207Smrg using difference_type = range_difference_t<_Base>; 28934c3eb207Smrg 28944c3eb207Smrg struct value_type : view_interface<value_type> 28954c3eb207Smrg { 28964c3eb207Smrg private: 28974c3eb207Smrg _OuterIter _M_i = _OuterIter(); 28984c3eb207Smrg 28994c3eb207Smrg public: 29004c3eb207Smrg value_type() = default; 29014c3eb207Smrg 29024c3eb207Smrg constexpr explicit 29034c3eb207Smrg value_type(_OuterIter __i) 29044c3eb207Smrg : _M_i(std::move(__i)) 29054c3eb207Smrg { } 29064c3eb207Smrg 29074c3eb207Smrg constexpr _InnerIter<_Const> 29084c3eb207Smrg begin() const 29094c3eb207Smrg { return _InnerIter<_Const>{_M_i}; } 29104c3eb207Smrg 29114c3eb207Smrg constexpr default_sentinel_t 29124c3eb207Smrg end() const 29134c3eb207Smrg { return default_sentinel; } 29144c3eb207Smrg }; 29154c3eb207Smrg 29164c3eb207Smrg _OuterIter() = default; 29174c3eb207Smrg 29184c3eb207Smrg constexpr explicit 29194c3eb207Smrg _OuterIter(_Parent* __parent) requires (!forward_range<_Base>) 29204c3eb207Smrg : _M_parent(__parent) 29214c3eb207Smrg { } 29224c3eb207Smrg 29234c3eb207Smrg constexpr 29244c3eb207Smrg _OuterIter(_Parent* __parent, iterator_t<_Base> __current) 29254c3eb207Smrg requires forward_range<_Base> 29264c3eb207Smrg : _M_parent(__parent), 29274c3eb207Smrg _M_current(std::move(__current)) 29284c3eb207Smrg { } 29294c3eb207Smrg 29304c3eb207Smrg constexpr 29314c3eb207Smrg _OuterIter(_OuterIter<!_Const> __i) 29324c3eb207Smrg requires _Const 29334c3eb207Smrg && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> 29344c3eb207Smrg : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)) 29354c3eb207Smrg { } 29364c3eb207Smrg 29374c3eb207Smrg constexpr value_type 29384c3eb207Smrg operator*() const 29394c3eb207Smrg { return value_type{*this}; } 29404c3eb207Smrg 29414c3eb207Smrg constexpr _OuterIter& 29424c3eb207Smrg operator++() 29434c3eb207Smrg { 29444c3eb207Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 29454c3eb207Smrg // 3505. split_view::outer-iterator::operator++ misspecified 29464c3eb207Smrg const auto __end = ranges::end(_M_parent->_M_base); 29474c3eb207Smrg if (__current() == __end) 29484c3eb207Smrg return *this; 29494c3eb207Smrg const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern}; 29504c3eb207Smrg if (__pbegin == __pend) 29514c3eb207Smrg ++__current(); 29524c3eb207Smrg else if constexpr (__detail::__tiny_range<_Pattern>) 29534c3eb207Smrg { 29544c3eb207Smrg __current() = __detail::find(std::move(__current()), __end, 29554c3eb207Smrg *__pbegin); 29564c3eb207Smrg if (__current() != __end) 29574c3eb207Smrg ++__current(); 29584c3eb207Smrg } 29594c3eb207Smrg else 29604c3eb207Smrg do 29614c3eb207Smrg { 29624c3eb207Smrg auto [__b, __p] 29634c3eb207Smrg = __detail::mismatch(__current(), __end, __pbegin, __pend); 29644c3eb207Smrg if (__p == __pend) 29654c3eb207Smrg { 29664c3eb207Smrg __current() = __b; 29674c3eb207Smrg break; 29684c3eb207Smrg } 29694c3eb207Smrg } while (++__current() != __end); 29704c3eb207Smrg return *this; 29714c3eb207Smrg } 29724c3eb207Smrg 29734c3eb207Smrg constexpr decltype(auto) 29744c3eb207Smrg operator++(int) 29754c3eb207Smrg { 29764c3eb207Smrg if constexpr (forward_range<_Base>) 29774c3eb207Smrg { 29784c3eb207Smrg auto __tmp = *this; 29794c3eb207Smrg ++*this; 29804c3eb207Smrg return __tmp; 29814c3eb207Smrg } 29824c3eb207Smrg else 29834c3eb207Smrg ++*this; 29844c3eb207Smrg } 29854c3eb207Smrg 29864c3eb207Smrg friend constexpr bool 29874c3eb207Smrg operator==(const _OuterIter& __x, const _OuterIter& __y) 29884c3eb207Smrg requires forward_range<_Base> 29894c3eb207Smrg { return __x._M_current == __y._M_current; } 29904c3eb207Smrg 29914c3eb207Smrg friend constexpr bool 29924c3eb207Smrg operator==(const _OuterIter& __x, default_sentinel_t) 29934c3eb207Smrg { return __x.__at_end(); }; 29944c3eb207Smrg 29954c3eb207Smrg friend _OuterIter<!_Const>; 29964c3eb207Smrg friend _InnerIter<_Const>; 29974c3eb207Smrg }; 29984c3eb207Smrg 29994c3eb207Smrg template<bool _Const> 30004c3eb207Smrg struct _InnerIter 30014c3eb207Smrg : __detail::__split_view_inner_iter_cat<_Base<_Const>> 30024c3eb207Smrg { 30034c3eb207Smrg private: 30044c3eb207Smrg using _Base = split_view::_Base<_Const>; 30054c3eb207Smrg 30064c3eb207Smrg constexpr bool 30074c3eb207Smrg __at_end() const 30084c3eb207Smrg { 30094c3eb207Smrg auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern}; 30104c3eb207Smrg auto __end = ranges::end(_M_i._M_parent->_M_base); 30114c3eb207Smrg if constexpr (__detail::__tiny_range<_Pattern>) 30124c3eb207Smrg { 30134c3eb207Smrg const auto& __cur = _M_i_current(); 30144c3eb207Smrg if (__cur == __end) 30154c3eb207Smrg return true; 30164c3eb207Smrg if (__pcur == __pend) 30174c3eb207Smrg return _M_incremented; 30184c3eb207Smrg return *__cur == *__pcur; 30194c3eb207Smrg } 30204c3eb207Smrg else 30214c3eb207Smrg { 30224c3eb207Smrg auto __cur = _M_i_current(); 30234c3eb207Smrg if (__cur == __end) 30244c3eb207Smrg return true; 30254c3eb207Smrg if (__pcur == __pend) 30264c3eb207Smrg return _M_incremented; 30274c3eb207Smrg do 30284c3eb207Smrg { 30294c3eb207Smrg if (*__cur != *__pcur) 30304c3eb207Smrg return false; 30314c3eb207Smrg if (++__pcur == __pend) 30324c3eb207Smrg return true; 30334c3eb207Smrg } while (++__cur != __end); 30344c3eb207Smrg return false; 30354c3eb207Smrg } 30364c3eb207Smrg } 30374c3eb207Smrg 30384c3eb207Smrg constexpr auto& 30394c3eb207Smrg _M_i_current() noexcept 30404c3eb207Smrg { return _M_i.__current(); } 30414c3eb207Smrg 30424c3eb207Smrg constexpr auto& 30434c3eb207Smrg _M_i_current() const noexcept 30444c3eb207Smrg { return _M_i.__current(); } 30454c3eb207Smrg 30464c3eb207Smrg _OuterIter<_Const> _M_i = _OuterIter<_Const>(); 30474c3eb207Smrg bool _M_incremented = false; 30484c3eb207Smrg 30494c3eb207Smrg public: 30504c3eb207Smrg using iterator_concept 30514c3eb207Smrg = typename _OuterIter<_Const>::iterator_concept; 30524c3eb207Smrg // iterator_category defined in __split_view_inner_iter_cat 30534c3eb207Smrg using value_type = range_value_t<_Base>; 30544c3eb207Smrg using difference_type = range_difference_t<_Base>; 30554c3eb207Smrg 30564c3eb207Smrg _InnerIter() = default; 30574c3eb207Smrg 30584c3eb207Smrg constexpr explicit 30594c3eb207Smrg _InnerIter(_OuterIter<_Const> __i) 30604c3eb207Smrg : _M_i(std::move(__i)) 30614c3eb207Smrg { } 30624c3eb207Smrg 30634c3eb207Smrg constexpr const iterator_t<_Base>& 30644c3eb207Smrg base() const& noexcept 30654c3eb207Smrg { return _M_i_current(); } 30664c3eb207Smrg 30674c3eb207Smrg constexpr iterator_t<_Base> 30684c3eb207Smrg base() && 30694c3eb207Smrg { return std::move(_M_i_current()); } 30704c3eb207Smrg 30714c3eb207Smrg constexpr decltype(auto) 30724c3eb207Smrg operator*() const 30734c3eb207Smrg { return *_M_i_current(); } 30744c3eb207Smrg 30754c3eb207Smrg constexpr _InnerIter& 30764c3eb207Smrg operator++() 30774c3eb207Smrg { 30784c3eb207Smrg _M_incremented = true; 30794c3eb207Smrg if constexpr (!forward_range<_Base>) 30804c3eb207Smrg if constexpr (_Pattern::size() == 0) 30814c3eb207Smrg return *this; 30824c3eb207Smrg ++_M_i_current(); 30834c3eb207Smrg return *this; 30844c3eb207Smrg } 30854c3eb207Smrg 30864c3eb207Smrg constexpr decltype(auto) 30874c3eb207Smrg operator++(int) 30884c3eb207Smrg { 30894c3eb207Smrg if constexpr (forward_range<_Base>) 30904c3eb207Smrg { 30914c3eb207Smrg auto __tmp = *this; 30924c3eb207Smrg ++*this; 30934c3eb207Smrg return __tmp; 30944c3eb207Smrg } 30954c3eb207Smrg else 30964c3eb207Smrg ++*this; 30974c3eb207Smrg } 30984c3eb207Smrg 30994c3eb207Smrg friend constexpr bool 31004c3eb207Smrg operator==(const _InnerIter& __x, const _InnerIter& __y) 31014c3eb207Smrg requires forward_range<_Base> 31024c3eb207Smrg { return __x._M_i == __y._M_i; } 31034c3eb207Smrg 31044c3eb207Smrg friend constexpr bool 31054c3eb207Smrg operator==(const _InnerIter& __x, default_sentinel_t) 31064c3eb207Smrg { return __x.__at_end(); } 31074c3eb207Smrg 31084c3eb207Smrg friend constexpr decltype(auto) 31094c3eb207Smrg iter_move(const _InnerIter& __i) 31104c3eb207Smrg noexcept(noexcept(ranges::iter_move(__i._M_i_current()))) 31114c3eb207Smrg { return ranges::iter_move(__i._M_i_current()); } 31124c3eb207Smrg 31134c3eb207Smrg friend constexpr void 31144c3eb207Smrg iter_swap(const _InnerIter& __x, const _InnerIter& __y) 31154c3eb207Smrg noexcept(noexcept(ranges::iter_swap(__x._M_i_current(), 31164c3eb207Smrg __y._M_i_current()))) 31174c3eb207Smrg requires indirectly_swappable<iterator_t<_Base>> 31184c3eb207Smrg { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); } 31194c3eb207Smrg }; 31204c3eb207Smrg 31214c3eb207Smrg _Vp _M_base = _Vp(); 31224c3eb207Smrg _Pattern _M_pattern = _Pattern(); 31234c3eb207Smrg 31244c3eb207Smrg // XXX: _M_current is "present only if !forward_range<V>" 31254c3eb207Smrg [[no_unique_address]] 31264c3eb207Smrg __detail::__maybe_present_t<!forward_range<_Vp>, iterator_t<_Vp>> 31274c3eb207Smrg _M_current; 31284c3eb207Smrg 31294c3eb207Smrg 31304c3eb207Smrg public: 31314c3eb207Smrg split_view() requires (default_initializable<_Vp> 31324c3eb207Smrg && default_initializable<_Pattern> 31334c3eb207Smrg && default_initializable<iterator_t<_Vp>>) 31344c3eb207Smrg = default; 31354c3eb207Smrg 31364c3eb207Smrg constexpr 31374c3eb207Smrg split_view(_Vp __base, _Pattern __pattern) 31384c3eb207Smrg : _M_base(std::move(__base)), _M_pattern(std::move(__pattern)) 31394c3eb207Smrg { } 31404c3eb207Smrg 31414c3eb207Smrg template<input_range _Range> 31424c3eb207Smrg requires constructible_from<_Vp, views::all_t<_Range>> 31434c3eb207Smrg && constructible_from<_Pattern, single_view<range_value_t<_Range>>> 31444c3eb207Smrg constexpr 31454c3eb207Smrg split_view(_Range&& __r, range_value_t<_Range> __e) 31464c3eb207Smrg : _M_base(views::all(std::forward<_Range>(__r))), 31474c3eb207Smrg _M_pattern(std::move(__e)) 31484c3eb207Smrg { } 31494c3eb207Smrg 31504c3eb207Smrg constexpr _Vp 31514c3eb207Smrg base() const& requires copy_constructible<_Vp> 31524c3eb207Smrg { return _M_base; } 31534c3eb207Smrg 31544c3eb207Smrg constexpr _Vp 31554c3eb207Smrg base() && 31564c3eb207Smrg { return std::move(_M_base); } 31574c3eb207Smrg 31584c3eb207Smrg constexpr auto 31594c3eb207Smrg begin() 31604c3eb207Smrg { 31614c3eb207Smrg if constexpr (forward_range<_Vp>) 31624c3eb207Smrg return _OuterIter<__detail::__simple_view<_Vp>>{ 31634c3eb207Smrg this, ranges::begin(_M_base)}; 31644c3eb207Smrg else 31654c3eb207Smrg { 31664c3eb207Smrg _M_current = ranges::begin(_M_base); 31674c3eb207Smrg return _OuterIter<false>{this}; 31684c3eb207Smrg } 31694c3eb207Smrg } 31704c3eb207Smrg 31714c3eb207Smrg constexpr auto 31724c3eb207Smrg begin() const requires forward_range<_Vp> && forward_range<const _Vp> 31734c3eb207Smrg { 31744c3eb207Smrg return _OuterIter<true>{this, ranges::begin(_M_base)}; 31754c3eb207Smrg } 31764c3eb207Smrg 31774c3eb207Smrg constexpr auto 31784c3eb207Smrg end() requires forward_range<_Vp> && common_range<_Vp> 31794c3eb207Smrg { 31804c3eb207Smrg return _OuterIter<__detail::__simple_view<_Vp>>{ 31814c3eb207Smrg this, ranges::end(_M_base)}; 31824c3eb207Smrg } 31834c3eb207Smrg 31844c3eb207Smrg constexpr auto 31854c3eb207Smrg end() const 31864c3eb207Smrg { 31874c3eb207Smrg if constexpr (forward_range<_Vp> 31884c3eb207Smrg && forward_range<const _Vp> 31894c3eb207Smrg && common_range<const _Vp>) 31904c3eb207Smrg return _OuterIter<true>{this, ranges::end(_M_base)}; 31914c3eb207Smrg else 31924c3eb207Smrg return default_sentinel; 31934c3eb207Smrg } 31944c3eb207Smrg }; 31954c3eb207Smrg 31964c3eb207Smrg template<typename _Range, typename _Pred> 31974c3eb207Smrg split_view(_Range&&, _Pred&&) 31984c3eb207Smrg -> split_view<views::all_t<_Range>, views::all_t<_Pred>>; 31994c3eb207Smrg 32004c3eb207Smrg template<input_range _Range> 32014c3eb207Smrg split_view(_Range&&, range_value_t<_Range>) 32024c3eb207Smrg -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>; 32034c3eb207Smrg 32044c3eb207Smrg namespace views 32054c3eb207Smrg { 32064c3eb207Smrg inline constexpr __adaptor::_RangeAdaptor split 32074c3eb207Smrg = [] <viewable_range _Range, typename _Fp> (_Range&& __r, _Fp&& __f) 32084c3eb207Smrg { 32094c3eb207Smrg return split_view{std::forward<_Range>(__r), std::forward<_Fp>(__f)}; 32104c3eb207Smrg }; 32114c3eb207Smrg } // namespace views 32124c3eb207Smrg 32134c3eb207Smrg namespace views 32144c3eb207Smrg { 32154c3eb207Smrg struct _Counted 32164c3eb207Smrg { 32174c3eb207Smrg template<input_or_output_iterator _Iter> 32184c3eb207Smrg constexpr auto 32194c3eb207Smrg operator()(_Iter __i, iter_difference_t<_Iter> __n) const 32204c3eb207Smrg { 32214c3eb207Smrg if constexpr (random_access_iterator<_Iter>) 32224c3eb207Smrg return subrange{__i, __i + __n}; 32234c3eb207Smrg else 32244c3eb207Smrg return subrange{counted_iterator{std::move(__i), __n}, 32254c3eb207Smrg default_sentinel}; 32264c3eb207Smrg } 32274c3eb207Smrg }; 32284c3eb207Smrg 32294c3eb207Smrg inline constexpr _Counted counted{}; 32304c3eb207Smrg } // namespace views 32314c3eb207Smrg 32324c3eb207Smrg template<view _Vp> 32334c3eb207Smrg requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>> 32344c3eb207Smrg class common_view : public view_interface<common_view<_Vp>> 32354c3eb207Smrg { 32364c3eb207Smrg private: 32374c3eb207Smrg _Vp _M_base = _Vp(); 32384c3eb207Smrg 32394c3eb207Smrg public: 32404c3eb207Smrg common_view() requires default_initializable<_Vp> = default; 32414c3eb207Smrg 32424c3eb207Smrg constexpr explicit 32434c3eb207Smrg common_view(_Vp __r) 32444c3eb207Smrg : _M_base(std::move(__r)) 32454c3eb207Smrg { } 32464c3eb207Smrg 32474c3eb207Smrg /* XXX: LWG 3280 didn't remove this constructor, but I think it should? 32484c3eb207Smrg template<viewable_range _Range> 32494c3eb207Smrg requires (!common_range<_Range>) 32504c3eb207Smrg && constructible_from<_Vp, views::all_t<_Range>> 32514c3eb207Smrg constexpr explicit 32524c3eb207Smrg common_view(_Range&& __r) 32534c3eb207Smrg : _M_base(views::all(std::forward<_Range>(__r))) 32544c3eb207Smrg { } 32554c3eb207Smrg */ 32564c3eb207Smrg 32574c3eb207Smrg constexpr _Vp 32584c3eb207Smrg base() const& requires copy_constructible<_Vp> 32594c3eb207Smrg { return _M_base; } 32604c3eb207Smrg 32614c3eb207Smrg constexpr _Vp 32624c3eb207Smrg base() && 32634c3eb207Smrg { return std::move(_M_base); } 32644c3eb207Smrg 32654c3eb207Smrg constexpr auto 32664c3eb207Smrg begin() 32674c3eb207Smrg { 32684c3eb207Smrg if constexpr (random_access_range<_Vp> && sized_range<_Vp>) 32694c3eb207Smrg return ranges::begin(_M_base); 32704c3eb207Smrg else 32714c3eb207Smrg return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>> 32724c3eb207Smrg (ranges::begin(_M_base)); 32734c3eb207Smrg } 32744c3eb207Smrg 32754c3eb207Smrg constexpr auto 32764c3eb207Smrg begin() const requires range<const _Vp> 32774c3eb207Smrg { 32784c3eb207Smrg if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>) 32794c3eb207Smrg return ranges::begin(_M_base); 32804c3eb207Smrg else 32814c3eb207Smrg return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>> 32824c3eb207Smrg (ranges::begin(_M_base)); 32834c3eb207Smrg } 32844c3eb207Smrg 32854c3eb207Smrg constexpr auto 32864c3eb207Smrg end() 32874c3eb207Smrg { 32884c3eb207Smrg if constexpr (random_access_range<_Vp> && sized_range<_Vp>) 32894c3eb207Smrg return ranges::begin(_M_base) + ranges::size(_M_base); 32904c3eb207Smrg else 32914c3eb207Smrg return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>> 32924c3eb207Smrg (ranges::end(_M_base)); 32934c3eb207Smrg } 32944c3eb207Smrg 32954c3eb207Smrg constexpr auto 32964c3eb207Smrg end() const requires range<const _Vp> 32974c3eb207Smrg { 32984c3eb207Smrg if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>) 32994c3eb207Smrg return ranges::begin(_M_base) + ranges::size(_M_base); 33004c3eb207Smrg else 33014c3eb207Smrg return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>> 33024c3eb207Smrg (ranges::end(_M_base)); 33034c3eb207Smrg } 33044c3eb207Smrg 33054c3eb207Smrg constexpr auto 33064c3eb207Smrg size() requires sized_range<_Vp> 33074c3eb207Smrg { return ranges::size(_M_base); } 33084c3eb207Smrg 33094c3eb207Smrg constexpr auto 33104c3eb207Smrg size() const requires sized_range<const _Vp> 33114c3eb207Smrg { return ranges::size(_M_base); } 33124c3eb207Smrg }; 33134c3eb207Smrg 33144c3eb207Smrg template<typename _Range> 33154c3eb207Smrg common_view(_Range&&) -> common_view<views::all_t<_Range>>; 33164c3eb207Smrg 33174c3eb207Smrg template<typename _Tp> 33184c3eb207Smrg inline constexpr bool enable_borrowed_range<common_view<_Tp>> 33194c3eb207Smrg = enable_borrowed_range<_Tp>; 33204c3eb207Smrg 33214c3eb207Smrg namespace views 33224c3eb207Smrg { 33234c3eb207Smrg inline constexpr __adaptor::_RangeAdaptorClosure common 33244c3eb207Smrg = [] <viewable_range _Range> (_Range&& __r) 33254c3eb207Smrg { 33264c3eb207Smrg if constexpr (common_range<_Range> 33274c3eb207Smrg && requires { views::all(std::forward<_Range>(__r)); }) 33284c3eb207Smrg return views::all(std::forward<_Range>(__r)); 33294c3eb207Smrg else 33304c3eb207Smrg return common_view{std::forward<_Range>(__r)}; 33314c3eb207Smrg }; 33324c3eb207Smrg 33334c3eb207Smrg } // namespace views 33344c3eb207Smrg 33354c3eb207Smrg template<view _Vp> 33364c3eb207Smrg requires bidirectional_range<_Vp> 33374c3eb207Smrg class reverse_view : public view_interface<reverse_view<_Vp>> 33384c3eb207Smrg { 33394c3eb207Smrg private: 33404c3eb207Smrg _Vp _M_base = _Vp(); 33414c3eb207Smrg 33424c3eb207Smrg static constexpr bool _S_needs_cached_begin 33434c3eb207Smrg = !common_range<_Vp> && !random_access_range<_Vp>; 33444c3eb207Smrg [[no_unique_address]] 33454c3eb207Smrg __detail::__maybe_present_t<_S_needs_cached_begin, 33464c3eb207Smrg __detail::_CachedPosition<_Vp>> 33474c3eb207Smrg _M_cached_begin; 33484c3eb207Smrg 33494c3eb207Smrg public: 33504c3eb207Smrg reverse_view() requires default_initializable<_Vp> = default; 33514c3eb207Smrg 33524c3eb207Smrg constexpr explicit 33534c3eb207Smrg reverse_view(_Vp __r) 33544c3eb207Smrg : _M_base(std::move(__r)) 33554c3eb207Smrg { } 33564c3eb207Smrg 33574c3eb207Smrg constexpr _Vp 33584c3eb207Smrg base() const& requires copy_constructible<_Vp> 33594c3eb207Smrg { return _M_base; } 33604c3eb207Smrg 33614c3eb207Smrg constexpr _Vp 33624c3eb207Smrg base() && 33634c3eb207Smrg { return std::move(_M_base); } 33644c3eb207Smrg 33654c3eb207Smrg constexpr reverse_iterator<iterator_t<_Vp>> 33664c3eb207Smrg begin() 33674c3eb207Smrg { 33684c3eb207Smrg if constexpr (_S_needs_cached_begin) 33694c3eb207Smrg if (_M_cached_begin._M_has_value()) 33704c3eb207Smrg return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base)); 33714c3eb207Smrg 33724c3eb207Smrg auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base)); 33734c3eb207Smrg if constexpr (_S_needs_cached_begin) 33744c3eb207Smrg _M_cached_begin._M_set(_M_base, __it); 33754c3eb207Smrg return std::make_reverse_iterator(std::move(__it)); 33764c3eb207Smrg } 33774c3eb207Smrg 33784c3eb207Smrg constexpr auto 33794c3eb207Smrg begin() requires common_range<_Vp> 33804c3eb207Smrg { return std::make_reverse_iterator(ranges::end(_M_base)); } 33814c3eb207Smrg 33824c3eb207Smrg constexpr auto 33834c3eb207Smrg begin() const requires common_range<const _Vp> 33844c3eb207Smrg { return std::make_reverse_iterator(ranges::end(_M_base)); } 33854c3eb207Smrg 33864c3eb207Smrg constexpr reverse_iterator<iterator_t<_Vp>> 33874c3eb207Smrg end() 33884c3eb207Smrg { return std::make_reverse_iterator(ranges::begin(_M_base)); } 33894c3eb207Smrg 33904c3eb207Smrg constexpr auto 33914c3eb207Smrg end() const requires common_range<const _Vp> 33924c3eb207Smrg { return std::make_reverse_iterator(ranges::begin(_M_base)); } 33934c3eb207Smrg 33944c3eb207Smrg constexpr auto 33954c3eb207Smrg size() requires sized_range<_Vp> 33964c3eb207Smrg { return ranges::size(_M_base); } 33974c3eb207Smrg 33984c3eb207Smrg constexpr auto 33994c3eb207Smrg size() const requires sized_range<const _Vp> 34004c3eb207Smrg { return ranges::size(_M_base); } 34014c3eb207Smrg }; 34024c3eb207Smrg 34034c3eb207Smrg template<typename _Range> 34044c3eb207Smrg reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>; 34054c3eb207Smrg 34064c3eb207Smrg template<typename _Tp> 34074c3eb207Smrg inline constexpr bool enable_borrowed_range<reverse_view<_Tp>> 34084c3eb207Smrg = enable_borrowed_range<_Tp>; 34094c3eb207Smrg 34104c3eb207Smrg namespace views 34114c3eb207Smrg { 34124c3eb207Smrg namespace __detail 34134c3eb207Smrg { 34144c3eb207Smrg template<typename> 34154c3eb207Smrg inline constexpr bool __is_reversible_subrange = false; 34164c3eb207Smrg 34174c3eb207Smrg template<typename _Iter, subrange_kind _Kind> 34184c3eb207Smrg inline constexpr bool 34194c3eb207Smrg __is_reversible_subrange<subrange<reverse_iterator<_Iter>, 34204c3eb207Smrg reverse_iterator<_Iter>, 34214c3eb207Smrg _Kind>> = true; 34224c3eb207Smrg 34234c3eb207Smrg template<typename> 34244c3eb207Smrg inline constexpr bool __is_reverse_view = false; 34254c3eb207Smrg 34264c3eb207Smrg template<typename _Vp> 34274c3eb207Smrg inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true; 34284c3eb207Smrg } 34294c3eb207Smrg 34304c3eb207Smrg inline constexpr __adaptor::_RangeAdaptorClosure reverse 34314c3eb207Smrg = [] <viewable_range _Range> (_Range&& __r) 34324c3eb207Smrg { 34334c3eb207Smrg using _Tp = remove_cvref_t<_Range>; 34344c3eb207Smrg if constexpr (__detail::__is_reverse_view<_Tp>) 34354c3eb207Smrg return std::forward<_Range>(__r).base(); 34364c3eb207Smrg else if constexpr (__detail::__is_reversible_subrange<_Tp>) 34374c3eb207Smrg { 34384c3eb207Smrg using _Iter = decltype(ranges::begin(__r).base()); 34394c3eb207Smrg if constexpr (sized_range<_Tp>) 34404c3eb207Smrg return subrange<_Iter, _Iter, subrange_kind::sized> 34414c3eb207Smrg (__r.end().base(), __r.begin().base(), __r.size()); 34424c3eb207Smrg else 34434c3eb207Smrg return subrange<_Iter, _Iter, subrange_kind::unsized> 34444c3eb207Smrg (__r.end().base(), __r.begin().base()); 34454c3eb207Smrg } 34464c3eb207Smrg else 34474c3eb207Smrg return reverse_view{std::forward<_Range>(__r)}; 34484c3eb207Smrg }; 34494c3eb207Smrg } // namespace views 34504c3eb207Smrg 34514c3eb207Smrg namespace __detail 34524c3eb207Smrg { 34534c3eb207Smrg template<typename _Tp, size_t _Nm> 34544c3eb207Smrg concept __has_tuple_element = requires(_Tp __t) 34554c3eb207Smrg { 34564c3eb207Smrg typename tuple_size<_Tp>::type; 34574c3eb207Smrg requires _Nm < tuple_size_v<_Tp>; 34584c3eb207Smrg typename tuple_element_t<_Nm, _Tp>; 34594c3eb207Smrg { std::get<_Nm>(__t) } 34604c3eb207Smrg -> convertible_to<const tuple_element_t<_Nm, _Tp>&>; 34614c3eb207Smrg }; 34624c3eb207Smrg 34634c3eb207Smrg template<typename _Tp, size_t _Nm> 34644c3eb207Smrg concept __returnable_element 34654c3eb207Smrg = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>; 34664c3eb207Smrg } 34674c3eb207Smrg 34684c3eb207Smrg template<input_range _Vp, size_t _Nm> 34694c3eb207Smrg requires view<_Vp> 34704c3eb207Smrg && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm> 34714c3eb207Smrg && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>, 34724c3eb207Smrg _Nm> 34734c3eb207Smrg && __detail::__returnable_element<range_reference_t<_Vp>, _Nm> 34744c3eb207Smrg class elements_view : public view_interface<elements_view<_Vp, _Nm>> 34754c3eb207Smrg { 34764c3eb207Smrg public: 34774c3eb207Smrg elements_view() requires default_initializable<_Vp> = default; 34784c3eb207Smrg 34794c3eb207Smrg constexpr explicit 34804c3eb207Smrg elements_view(_Vp base) 34814c3eb207Smrg : _M_base(std::move(base)) 34824c3eb207Smrg { } 34834c3eb207Smrg 34844c3eb207Smrg constexpr _Vp 34854c3eb207Smrg base() const& requires copy_constructible<_Vp> 34864c3eb207Smrg { return _M_base; } 34874c3eb207Smrg 34884c3eb207Smrg constexpr _Vp 34894c3eb207Smrg base() && 34904c3eb207Smrg { return std::move(_M_base); } 34914c3eb207Smrg 34924c3eb207Smrg constexpr auto 34934c3eb207Smrg begin() requires (!__detail::__simple_view<_Vp>) 34944c3eb207Smrg { return _Iterator<false>(ranges::begin(_M_base)); } 34954c3eb207Smrg 34964c3eb207Smrg constexpr auto 34974c3eb207Smrg begin() const requires range<const _Vp> 34984c3eb207Smrg { return _Iterator<true>(ranges::begin(_M_base)); } 34994c3eb207Smrg 35004c3eb207Smrg constexpr auto 35014c3eb207Smrg end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>) 35024c3eb207Smrg { return _Sentinel<false>{ranges::end(_M_base)}; } 35034c3eb207Smrg 35044c3eb207Smrg constexpr auto 35054c3eb207Smrg end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>) 35064c3eb207Smrg { return _Iterator<false>{ranges::end(_M_base)}; } 35074c3eb207Smrg 35084c3eb207Smrg constexpr auto 35094c3eb207Smrg end() const requires range<const _Vp> 35104c3eb207Smrg { return _Sentinel<true>{ranges::end(_M_base)}; } 35114c3eb207Smrg 35124c3eb207Smrg constexpr auto 35134c3eb207Smrg end() const requires common_range<const _Vp> 35144c3eb207Smrg { return _Iterator<true>{ranges::end(_M_base)}; } 35154c3eb207Smrg 35164c3eb207Smrg constexpr auto 35174c3eb207Smrg size() requires sized_range<_Vp> 35184c3eb207Smrg { return ranges::size(_M_base); } 35194c3eb207Smrg 35204c3eb207Smrg constexpr auto 35214c3eb207Smrg size() const requires sized_range<const _Vp> 35224c3eb207Smrg { return ranges::size(_M_base); } 35234c3eb207Smrg 35244c3eb207Smrg private: 35254c3eb207Smrg template<bool _Const> 35264c3eb207Smrg using _Base = __detail::__maybe_const_t<_Const, _Vp>; 35274c3eb207Smrg 35284c3eb207Smrg template<bool _Const> 35294c3eb207Smrg struct __iter_cat 35304c3eb207Smrg { }; 35314c3eb207Smrg 35324c3eb207Smrg template<bool _Const> 35334c3eb207Smrg requires forward_range<_Base<_Const>> 35344c3eb207Smrg struct __iter_cat<_Const> 35354c3eb207Smrg { 35364c3eb207Smrg private: 35374c3eb207Smrg static auto _S_iter_cat() 35384c3eb207Smrg { 35394c3eb207Smrg using _Base = elements_view::_Base<_Const>; 35404c3eb207Smrg using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category; 35414c3eb207Smrg using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>()))); 35424c3eb207Smrg if constexpr (!is_lvalue_reference_v<_Res>) 35434c3eb207Smrg return input_iterator_tag{}; 35444c3eb207Smrg else if constexpr (derived_from<_Cat, random_access_iterator_tag>) 35454c3eb207Smrg return random_access_iterator_tag{}; 35464c3eb207Smrg else 35474c3eb207Smrg return _Cat{}; 35484c3eb207Smrg } 35494c3eb207Smrg public: 35504c3eb207Smrg using iterator_category = decltype(_S_iter_cat()); 35514c3eb207Smrg }; 35524c3eb207Smrg 35534c3eb207Smrg template<bool _Const> 35544c3eb207Smrg struct _Sentinel; 35554c3eb207Smrg 35564c3eb207Smrg template<bool _Const> 35574c3eb207Smrg struct _Iterator : __iter_cat<_Const> 35584c3eb207Smrg { 35594c3eb207Smrg private: 35604c3eb207Smrg using _Base = elements_view::_Base<_Const>; 35614c3eb207Smrg 35624c3eb207Smrg iterator_t<_Base> _M_current = iterator_t<_Base>(); 35634c3eb207Smrg 35644c3eb207Smrg static constexpr decltype(auto) 35654c3eb207Smrg _S_get_element(const iterator_t<_Base>& __i) 35664c3eb207Smrg { 35674c3eb207Smrg if constexpr (is_reference_v<range_reference_t<_Base>>) 35684c3eb207Smrg return std::get<_Nm>(*__i); 35694c3eb207Smrg else 35704c3eb207Smrg { 35714c3eb207Smrg using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>; 35724c3eb207Smrg return static_cast<_Et>(std::get<_Nm>(*__i)); 35734c3eb207Smrg } 35744c3eb207Smrg } 35754c3eb207Smrg 35764c3eb207Smrg static auto 35774c3eb207Smrg _S_iter_concept() 35784c3eb207Smrg { 35794c3eb207Smrg if constexpr (random_access_range<_Base>) 35804c3eb207Smrg return random_access_iterator_tag{}; 35814c3eb207Smrg else if constexpr (bidirectional_range<_Base>) 35824c3eb207Smrg return bidirectional_iterator_tag{}; 35834c3eb207Smrg else if constexpr (forward_range<_Base>) 35844c3eb207Smrg return forward_iterator_tag{}; 35854c3eb207Smrg else 35864c3eb207Smrg return input_iterator_tag{}; 35874c3eb207Smrg } 35884c3eb207Smrg 35894c3eb207Smrg friend _Iterator<!_Const>; 35904c3eb207Smrg 35914c3eb207Smrg public: 35924c3eb207Smrg using iterator_concept = decltype(_S_iter_concept()); 35934c3eb207Smrg // iterator_category defined in elements_view::__iter_cat 35944c3eb207Smrg using value_type 35954c3eb207Smrg = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>; 35964c3eb207Smrg using difference_type = range_difference_t<_Base>; 35974c3eb207Smrg 35984c3eb207Smrg _Iterator() requires default_initializable<iterator_t<_Base>> = default; 35994c3eb207Smrg 36004c3eb207Smrg constexpr explicit 36014c3eb207Smrg _Iterator(iterator_t<_Base> current) 36024c3eb207Smrg : _M_current(std::move(current)) 36034c3eb207Smrg { } 36044c3eb207Smrg 36054c3eb207Smrg constexpr 36064c3eb207Smrg _Iterator(_Iterator<!_Const> i) 36074c3eb207Smrg requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> 36084c3eb207Smrg : _M_current(std::move(i._M_current)) 36094c3eb207Smrg { } 36104c3eb207Smrg 36114c3eb207Smrg constexpr const iterator_t<_Base>& 36124c3eb207Smrg base() const& noexcept 36134c3eb207Smrg { return _M_current; } 36144c3eb207Smrg 36154c3eb207Smrg constexpr iterator_t<_Base> 36164c3eb207Smrg base() && 36174c3eb207Smrg { return std::move(_M_current); } 36184c3eb207Smrg 36194c3eb207Smrg constexpr decltype(auto) 36204c3eb207Smrg operator*() const 36214c3eb207Smrg { return _S_get_element(_M_current); } 36224c3eb207Smrg 36234c3eb207Smrg constexpr _Iterator& 36244c3eb207Smrg operator++() 36254c3eb207Smrg { 36264c3eb207Smrg ++_M_current; 36274c3eb207Smrg return *this; 36284c3eb207Smrg } 36294c3eb207Smrg 36304c3eb207Smrg constexpr void 36314c3eb207Smrg operator++(int) 36324c3eb207Smrg { ++_M_current; } 36334c3eb207Smrg 36344c3eb207Smrg constexpr _Iterator 36354c3eb207Smrg operator++(int) requires forward_range<_Base> 36364c3eb207Smrg { 36374c3eb207Smrg auto __tmp = *this; 36384c3eb207Smrg ++_M_current; 36394c3eb207Smrg return __tmp; 36404c3eb207Smrg } 36414c3eb207Smrg 36424c3eb207Smrg constexpr _Iterator& 36434c3eb207Smrg operator--() requires bidirectional_range<_Base> 36444c3eb207Smrg { 36454c3eb207Smrg --_M_current; 36464c3eb207Smrg return *this; 36474c3eb207Smrg } 36484c3eb207Smrg 36494c3eb207Smrg constexpr _Iterator 36504c3eb207Smrg operator--(int) requires bidirectional_range<_Base> 36514c3eb207Smrg { 36524c3eb207Smrg auto __tmp = *this; 36534c3eb207Smrg --_M_current; 36544c3eb207Smrg return __tmp; 36554c3eb207Smrg } 36564c3eb207Smrg 36574c3eb207Smrg constexpr _Iterator& 36584c3eb207Smrg operator+=(difference_type __n) 36594c3eb207Smrg requires random_access_range<_Base> 36604c3eb207Smrg { 36614c3eb207Smrg _M_current += __n; 36624c3eb207Smrg return *this; 36634c3eb207Smrg } 36644c3eb207Smrg 36654c3eb207Smrg constexpr _Iterator& 36664c3eb207Smrg operator-=(difference_type __n) 36674c3eb207Smrg requires random_access_range<_Base> 36684c3eb207Smrg { 36694c3eb207Smrg _M_current -= __n; 36704c3eb207Smrg return *this; 36714c3eb207Smrg } 36724c3eb207Smrg 36734c3eb207Smrg constexpr decltype(auto) 36744c3eb207Smrg operator[](difference_type __n) const 36754c3eb207Smrg requires random_access_range<_Base> 36764c3eb207Smrg { return _S_get_element(_M_current + __n); } 36774c3eb207Smrg 36784c3eb207Smrg friend constexpr bool 36794c3eb207Smrg operator==(const _Iterator& __x, const _Iterator& __y) 36804c3eb207Smrg requires equality_comparable<iterator_t<_Base>> 36814c3eb207Smrg { return __x._M_current == __y._M_current; } 36824c3eb207Smrg 36834c3eb207Smrg friend constexpr bool 36844c3eb207Smrg operator<(const _Iterator& __x, const _Iterator& __y) 36854c3eb207Smrg requires random_access_range<_Base> 36864c3eb207Smrg { return __x._M_current < __y._M_current; } 36874c3eb207Smrg 36884c3eb207Smrg friend constexpr bool 36894c3eb207Smrg operator>(const _Iterator& __x, const _Iterator& __y) 36904c3eb207Smrg requires random_access_range<_Base> 36914c3eb207Smrg { return __y._M_current < __x._M_current; } 36924c3eb207Smrg 36934c3eb207Smrg friend constexpr bool 36944c3eb207Smrg operator<=(const _Iterator& __x, const _Iterator& __y) 36954c3eb207Smrg requires random_access_range<_Base> 36964c3eb207Smrg { return !(__y._M_current > __x._M_current); } 36974c3eb207Smrg 36984c3eb207Smrg friend constexpr bool 36994c3eb207Smrg operator>=(const _Iterator& __x, const _Iterator& __y) 37004c3eb207Smrg requires random_access_range<_Base> 37014c3eb207Smrg { return !(__x._M_current > __y._M_current); } 37024c3eb207Smrg 37034c3eb207Smrg#ifdef __cpp_lib_three_way_comparison 37044c3eb207Smrg friend constexpr auto 37054c3eb207Smrg operator<=>(const _Iterator& __x, const _Iterator& __y) 37064c3eb207Smrg requires random_access_range<_Base> 37074c3eb207Smrg && three_way_comparable<iterator_t<_Base>> 37084c3eb207Smrg { return __x._M_current <=> __y._M_current; } 37094c3eb207Smrg#endif 37104c3eb207Smrg 37114c3eb207Smrg friend constexpr _Iterator 37124c3eb207Smrg operator+(const _Iterator& __x, difference_type __y) 37134c3eb207Smrg requires random_access_range<_Base> 37144c3eb207Smrg { return _Iterator{__x} += __y; } 37154c3eb207Smrg 37164c3eb207Smrg friend constexpr _Iterator 37174c3eb207Smrg operator+(difference_type __x, const _Iterator& __y) 37184c3eb207Smrg requires random_access_range<_Base> 37194c3eb207Smrg { return __y + __x; } 37204c3eb207Smrg 37214c3eb207Smrg friend constexpr _Iterator 37224c3eb207Smrg operator-(const _Iterator& __x, difference_type __y) 37234c3eb207Smrg requires random_access_range<_Base> 37244c3eb207Smrg { return _Iterator{__x} -= __y; } 37254c3eb207Smrg 37264c3eb207Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 37274c3eb207Smrg // 3483. transform_view::iterator's difference is overconstrained 37284c3eb207Smrg friend constexpr difference_type 37294c3eb207Smrg operator-(const _Iterator& __x, const _Iterator& __y) 37304c3eb207Smrg requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> 37314c3eb207Smrg { return __x._M_current - __y._M_current; } 37324c3eb207Smrg 37334c3eb207Smrg template <bool> friend struct _Sentinel; 37344c3eb207Smrg }; 37354c3eb207Smrg 37364c3eb207Smrg template<bool _Const> 37374c3eb207Smrg struct _Sentinel 37384c3eb207Smrg { 37394c3eb207Smrg private: 37404c3eb207Smrg template<bool _Const2> 37414c3eb207Smrg constexpr bool 37424c3eb207Smrg _M_equal(const _Iterator<_Const2>& __x) const 37434c3eb207Smrg { return __x._M_current == _M_end; } 37444c3eb207Smrg 37454c3eb207Smrg template<bool _Const2> 37464c3eb207Smrg constexpr auto 37474c3eb207Smrg _M_distance_from(const _Iterator<_Const2>& __i) const 37484c3eb207Smrg { return _M_end - __i._M_current; } 37494c3eb207Smrg 37504c3eb207Smrg using _Base = elements_view::_Base<_Const>; 37514c3eb207Smrg sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 37524c3eb207Smrg 37534c3eb207Smrg public: 37544c3eb207Smrg _Sentinel() = default; 37554c3eb207Smrg 37564c3eb207Smrg constexpr explicit 37574c3eb207Smrg _Sentinel(sentinel_t<_Base> __end) 37584c3eb207Smrg : _M_end(std::move(__end)) 37594c3eb207Smrg { } 37604c3eb207Smrg 37614c3eb207Smrg constexpr 37624c3eb207Smrg _Sentinel(_Sentinel<!_Const> __other) 37634c3eb207Smrg requires _Const 37644c3eb207Smrg && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 37654c3eb207Smrg : _M_end(std::move(__other._M_end)) 37664c3eb207Smrg { } 37674c3eb207Smrg 37684c3eb207Smrg constexpr sentinel_t<_Base> 37694c3eb207Smrg base() const 37704c3eb207Smrg { return _M_end; } 37714c3eb207Smrg 37724c3eb207Smrg template<bool _Const2> 37734c3eb207Smrg requires sentinel_for<sentinel_t<_Base>, 37744c3eb207Smrg iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>> 37754c3eb207Smrg friend constexpr bool 37764c3eb207Smrg operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y) 37774c3eb207Smrg { return __y._M_equal(__x); } 37784c3eb207Smrg 37794c3eb207Smrg template<bool _Const2, 37804c3eb207Smrg typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>> 37814c3eb207Smrg requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 37824c3eb207Smrg friend constexpr range_difference_t<_Base2> 37834c3eb207Smrg operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y) 37844c3eb207Smrg { return -__y._M_distance_from(__x); } 37854c3eb207Smrg 37864c3eb207Smrg template<bool _Const2, 37874c3eb207Smrg typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>> 37884c3eb207Smrg requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 37894c3eb207Smrg friend constexpr range_difference_t<_Base2> 37904c3eb207Smrg operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y) 37914c3eb207Smrg { return __x._M_distance_from(__y); } 37924c3eb207Smrg 37934c3eb207Smrg friend _Sentinel<!_Const>; 37944c3eb207Smrg }; 37954c3eb207Smrg 37964c3eb207Smrg _Vp _M_base = _Vp(); 37974c3eb207Smrg }; 37984c3eb207Smrg 37994c3eb207Smrg template<typename _Tp, size_t _Nm> 38004c3eb207Smrg inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>> 38014c3eb207Smrg = enable_borrowed_range<_Tp>; 38024c3eb207Smrg 38034c3eb207Smrg template<typename _Range> 38044c3eb207Smrg using keys_view = elements_view<views::all_t<_Range>, 0>; 38054c3eb207Smrg 38064c3eb207Smrg template<typename _Range> 38074c3eb207Smrg using values_view = elements_view<views::all_t<_Range>, 1>; 38084c3eb207Smrg 38094c3eb207Smrg namespace views 38104c3eb207Smrg { 38114c3eb207Smrg template<size_t _Nm> 38124c3eb207Smrg inline constexpr __adaptor::_RangeAdaptorClosure elements 38134c3eb207Smrg = [] <viewable_range _Range> (_Range&& __r) 38144c3eb207Smrg { 38154c3eb207Smrg using _El = elements_view<views::all_t<_Range>, _Nm>; 38164c3eb207Smrg return _El{std::forward<_Range>(__r)}; 38174c3eb207Smrg }; 38184c3eb207Smrg 38194c3eb207Smrg inline constexpr __adaptor::_RangeAdaptorClosure keys = elements<0>; 38204c3eb207Smrg inline constexpr __adaptor::_RangeAdaptorClosure values = elements<1>; 38214c3eb207Smrg } // namespace views 38224c3eb207Smrg 38234c3eb207Smrg} // namespace ranges 38244c3eb207Smrg 38254c3eb207Smrg namespace views = ranges::views; 38264c3eb207Smrg 38274c3eb207Smrg template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind> 38284c3eb207Smrg struct tuple_size<ranges::subrange<_Iter, _Sent, _Kind>> 38294c3eb207Smrg : integral_constant<size_t, 2> 38304c3eb207Smrg { }; 38314c3eb207Smrg 38324c3eb207Smrg template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind> 38334c3eb207Smrg struct tuple_element<0, ranges::subrange<_Iter, _Sent, _Kind>> 38344c3eb207Smrg { using type = _Iter; }; 38354c3eb207Smrg 38364c3eb207Smrg template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind> 38374c3eb207Smrg struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>> 38384c3eb207Smrg { using type = _Sent; }; 38394c3eb207Smrg 38404c3eb207Smrg template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind> 38414c3eb207Smrg struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>> 38424c3eb207Smrg { using type = _Iter; }; 38434c3eb207Smrg 38444c3eb207Smrg template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind> 38454c3eb207Smrg struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>> 38464c3eb207Smrg { using type = _Sent; }; 38474c3eb207Smrg 38484c3eb207Smrg_GLIBCXX_END_NAMESPACE_VERSION 38494c3eb207Smrg} // namespace 38504c3eb207Smrg#endif // library concepts 38514c3eb207Smrg#endif // C++2a 38524c3eb207Smrg#endif /* _GLIBCXX_RANGES */ 3853