xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/std/ranges (revision 4ac76180e904e771b9d522c7e57296d371f06499)
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