// <ranges> -*- C++ -*-

// Copyright (C) 2019-2026 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file include/ranges
 *  This is a Standard C++ Library header.
 *  @ingroup concepts
 */

#ifndef _GLIBCXX_RANGES
#define _GLIBCXX_RANGES 1

#if __cplusplus > 201703L

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <concepts>

#if __cpp_lib_concepts

#include <compare>
#include <initializer_list>
#include <iterator>
#include <optional>
#include <span>
#include <string_view>
#include <tuple>
#if __cplusplus > 202002L
#include <utility>
#include <variant>
#endif
#include <bits/binders.h>
#include <bits/ranges_util.h>
#include <bits/refwrap.h>

#define __glibcxx_want_algorithm_default_value_type
#define __glibcxx_want_ranges
#define __glibcxx_want_ranges_as_const
#define __glibcxx_want_ranges_as_rvalue
#define __glibcxx_want_ranges_cache_latest
#define __glibcxx_want_ranges_cartesian_product
#define __glibcxx_want_ranges_concat
#define __glibcxx_want_ranges_chunk
#define __glibcxx_want_ranges_chunk_by
#define __glibcxx_want_ranges_enumerate
#define __glibcxx_want_ranges_filter
#define __glibcxx_want_ranges_indices
#define __glibcxx_want_ranges_join_with
#define __glibcxx_want_ranges_repeat
#define __glibcxx_want_ranges_slide
#define __glibcxx_want_ranges_stride
#define __glibcxx_want_ranges_to_container
#define __glibcxx_want_ranges_as_input
#define __glibcxx_want_ranges_zip
#include <bits/version.h>

#ifdef __glibcxx_generator  // C++ >= 23 && __glibcxx_coroutine
# include <bits/elements_of.h>
#endif

/**
 * @defgroup ranges Ranges
 *
 * Components for dealing with ranges of elements.
 */

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges
{
  // [range.access] customization point objects
  // [range.req] range and view concepts
  // [range.dangling] dangling iterator handling
  // Defined in <bits/ranges_base.h>

  // [view.interface] View interface
  // [range.subrange] Sub-ranges
  // Defined in <bits/ranges_util.h>

  // C++20 24.6 [range.factories] Range factories

  /// A view that contains no elements.
  template<typename _Tp> requires is_object_v<_Tp>
    class empty_view
    : public view_interface<empty_view<_Tp>>
    {
    public:
      static constexpr _Tp* begin() noexcept { return nullptr; }
      static constexpr _Tp* end() noexcept { return nullptr; }
      static constexpr _Tp* data() noexcept { return nullptr; }
      static constexpr size_t size() noexcept { return 0; }
      static constexpr bool empty() noexcept { return true; }
    };

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;

  namespace __detail
  {
#if __cpp_lib_ranges >= 202207L // C++ >= 23
    // P2494R2 Relaxing range adaptors to allow for move only types
    template<typename _Tp>
      concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
#else
    template<typename _Tp>
      concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
#endif

    template<__boxable _Tp>
      struct __box : std::optional<_Tp>
      {
	using std::optional<_Tp>::optional;

	constexpr
	__box()
	noexcept(is_nothrow_default_constructible_v<_Tp>)
	requires default_initializable<_Tp>
	: std::optional<_Tp>{std::in_place}
	{ }

	__box(const __box&) = default;
	__box(__box&&) = default;

	using std::optional<_Tp>::operator=;

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 3477. Simplify constraints for semiregular-box
	// 3572. copyable-box should be fully constexpr
	constexpr __box&
	operator=(const __box& __that)
	noexcept(is_nothrow_copy_constructible_v<_Tp>)
	requires (!copyable<_Tp>) && copy_constructible<_Tp>
	{
	  if (this != std::__addressof(__that))
	    {
	      if ((bool)__that)
		this->emplace(*__that);
	      else
		this->reset();
	    }
	  return *this;
	}

	constexpr __box&
	operator=(__box&& __that)
	noexcept(is_nothrow_move_constructible_v<_Tp>)
	requires (!movable<_Tp>)
	{
	  if (this != std::__addressof(__that))
	    {
	      if ((bool)__that)
		this->emplace(std::move(*__that));
	      else
		this->reset();
	    }
	  return *this;
	}
      };

    template<typename _Tp>
      concept __boxable_copyable
	= copy_constructible<_Tp>
	    && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
				    && is_nothrow_copy_constructible_v<_Tp>));
    template<typename _Tp>
      concept __boxable_movable
	= (!copy_constructible<_Tp>)
	    && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);

    // For types which are already copyable (or since C++23, movable)
    // this specialization of the box wrapper stores the object directly
    // without going through std::optional.  It provides just the subset of
    // the primary template's API that we currently use.
    template<__boxable _Tp>
      requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
      struct __box<_Tp>
      {
      private:
	[[no_unique_address]] _Tp _M_value = _Tp();

      public:
	__box() requires default_initializable<_Tp> = default;

	constexpr explicit
	__box(const _Tp& __t)
	noexcept(is_nothrow_copy_constructible_v<_Tp>)
	requires copy_constructible<_Tp>
	: _M_value(__t)
	{ }

	constexpr explicit
	__box(_Tp&& __t)
	noexcept(is_nothrow_move_constructible_v<_Tp>)
	: _M_value(std::move(__t))
	{ }

	template<typename... _Args>
	  requires constructible_from<_Tp, _Args...>
	  constexpr explicit
	  __box(in_place_t, _Args&&... __args)
	  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
	  : _M_value(std::forward<_Args>(__args)...)
	  { }

	__box(const __box&) = default;
	__box(__box&&) = default;
	__box& operator=(const __box&) requires copyable<_Tp> = default;
	__box& operator=(__box&&) requires movable<_Tp> = default;

	// When _Tp is nothrow_copy_constructible but not copy_assignable,
	// copy assignment is implemented via destroy-then-copy-construct.
	constexpr __box&
	operator=(const __box& __that) noexcept
	requires (!copyable<_Tp>) && copy_constructible<_Tp>
	{
	  static_assert(is_nothrow_copy_constructible_v<_Tp>);
	  if (this != std::__addressof(__that))
	    {
	      _M_value.~_Tp();
	      std::construct_at(std::__addressof(_M_value), *__that);
	    }
	  return *this;
	}

	// Likewise for move assignment.
	constexpr __box&
	operator=(__box&& __that) noexcept
	requires (!movable<_Tp>)
	{
	  static_assert(is_nothrow_move_constructible_v<_Tp>);
	  if (this != std::__addressof(__that))
	    {
	      _M_value.~_Tp();
	      std::construct_at(std::__addressof(_M_value), std::move(*__that));
	    }
	  return *this;
	}

	constexpr bool
	has_value() const noexcept
	{ return true; };

	constexpr _Tp&
	operator*() & noexcept
	{ return _M_value; }

	constexpr const _Tp&
	operator*() const & noexcept
	{ return _M_value; }

	constexpr _Tp&&
	operator*() && noexcept
	{ return std::move(_M_value); }

	constexpr const _Tp&&
	operator*() const && noexcept
	{ return std::move(_M_value); }

	constexpr _Tp*
	operator->() noexcept
	{ return std::__addressof(_M_value); }

	constexpr const _Tp*
	operator->() const noexcept
	{ return std::__addressof(_M_value); }
      };

      namespace __func_handle
      {
	template<typename _Fn>
	  struct _Inplace
	  {
	    _Inplace() = default;

	    constexpr explicit
	    _Inplace(_Fn __func) noexcept
	    : _M_fn(__func)
	    { }

	    template<typename... _Iters>
	      constexpr decltype(auto)
	      _M_call_deref(const _Iters&... __iters) const
	      noexcept(noexcept(_M_fn(*__iters...)))
	      { return _M_fn(*__iters...); }

	    template<typename _DistType, typename... _Iters>
	      constexpr decltype(auto)
	      _M_call_subscript(const _DistType __n, const _Iters&... __iters) const
	      noexcept(noexcept(_M_fn(__iters[iter_difference_t<_Iters>(__n)]...)))
	      { return _M_fn(__iters[iter_difference_t<_Iters>(__n)]...); }

	  private:
	    [[no_unique_address]] _Fn _M_fn = _Fn();
	  };

	template<typename _Fn>
	  struct _InplaceMemPtr
	  {
	    _InplaceMemPtr() = default;

	    constexpr explicit
	    _InplaceMemPtr(_Fn __func) noexcept
	    : _M_ptr(__func)
	    {}

	    template<typename... _Iters>
	    constexpr decltype(auto)
	      _M_call_deref(const _Iters&... __iters) const
	      noexcept(noexcept(std::__invoke(_M_ptr, *__iters...)))
	      { return std::__invoke(_M_ptr, *__iters...); }

	    template<typename _DistType, typename... _Iters>
	      constexpr decltype(auto)
	      _M_call_subscript(const _DistType __n, const _Iters&... __iters) const
	      noexcept(noexcept(std::__invoke(_M_ptr, __iters[iter_difference_t<_Iters>(__n)]...)))
	      { return std::__invoke(_M_ptr, __iters[iter_difference_t<_Iters>(__n)]...); }

	  private:
	    _Fn _M_ptr = nullptr;
	  };

	template<typename _Fn>
	  struct _ViaPointer
	  {
	    _ViaPointer() = default;

	    constexpr explicit
	    _ViaPointer(_Fn& __func) noexcept
	    : _M_ptr(std::addressof(__func))
	    { }

	    template<typename _Un>
	      requires (!is_const_v<_Un>) && is_same_v<const _Un, _Fn>
	      constexpr
	      _ViaPointer(_ViaPointer<_Un> __other) noexcept
	      : _M_ptr(__other._M_ptr)
	      { }

	    template<typename... _Iters>
	      constexpr decltype(auto)
	      _M_call_deref(const _Iters&... __iters) const
	      noexcept(noexcept((*_M_ptr)(*__iters...)))
	      { return (*_M_ptr)(*__iters...); }

	    template<typename _DistType, typename... _Iters>
	      constexpr decltype(auto)
	      _M_call_subscript(const _DistType __n, const _Iters&... __iters) const
	      noexcept(noexcept((*_M_ptr)(__iters[iter_difference_t<_Iters>(__n)]...)))
	      { return (*_M_ptr)(__iters[iter_difference_t<_Iters>(__n)]...); }

	  private:
	    _Fn* _M_ptr = nullptr;

	    template<typename>
	      friend struct _ViaPointer;
	  };

	template<typename _Fn>
	  struct _StaticCall
	  {
	    _StaticCall() = default;

	    constexpr explicit
	    _StaticCall(const _Fn&) noexcept
	    {}

	    template<typename... _Iters>
	     static constexpr decltype(auto)
	      _M_call_deref(const _Iters&... __iters)
	      noexcept(noexcept(_Fn::operator()(*__iters...)))
	      { return _Fn::operator()(*__iters...); }

	    template<typename _DistType, typename... _Iters>
	      static constexpr decltype(auto)
	      _M_call_subscript(_DistType __n, const _Iters&... __iters)
	      noexcept(noexcept(_Fn::operator()(__iters[iter_difference_t<_Iters>(__n)]...)))
	      { return _Fn::operator()(__iters[iter_difference_t<_Iters>(__n)]...); }
	  };

	  template<typename _Fn, typename... _Iters>
	    consteval auto
	    __select()
	    {
	      using _Fd = remove_cv_t<_Fn>;
	      if constexpr (is_member_pointer_v<_Fd>)
		return __func_handle::_InplaceMemPtr<_Fd>();
	      else if constexpr (is_function_v<remove_pointer_t<_Fd>>)
		return __func_handle::_Inplace<_Fd>();
	      else if constexpr (__is_std_op_wrapper<_Fd>)
	       return __func_handle::_Inplace<_Fd>();
	     else if constexpr (requires (const _Iters&... __iters)
				{ _Fd::operator()(*__iters...); })
	       return __func_handle::_StaticCall<_Fd>();
	     else
	       return __func_handle::_ViaPointer<_Fn>();
	   };
      } // __func_handle

      template<typename _Fn, typename... _Iters>
	using __func_handle_t = decltype(__func_handle::__select<_Fn, _Iters...>());
  } // namespace __detail

  /// A view that contains exactly one element.
#if __cpp_lib_ranges >= 202207L // C++ >= 23
  template<move_constructible _Tp>
#else
  template<copy_constructible _Tp>
#endif
    requires is_object_v<_Tp>
    class single_view : public view_interface<single_view<_Tp>>
    {
    public:
      single_view() requires default_initializable<_Tp> = default;

      constexpr explicit
      single_view(const _Tp& __t)
      noexcept(is_nothrow_copy_constructible_v<_Tp>)
      requires copy_constructible<_Tp>
      : _M_value(__t)
      { }

      constexpr explicit
      single_view(_Tp&& __t)
      noexcept(is_nothrow_move_constructible_v<_Tp>)
      : _M_value(std::move(__t))
      { }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3428. single_view's in place constructor should be explicit
      template<typename... _Args>
	requires constructible_from<_Tp, _Args...>
	constexpr explicit
	single_view(in_place_t, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
	: _M_value{in_place, std::forward<_Args>(__args)...}
	{ }

      constexpr _Tp*
      begin() noexcept
      { return data(); }

      constexpr const _Tp*
      begin() const noexcept
      { return data(); }

      constexpr _Tp*
      end() noexcept
      { return data() + 1; }

      constexpr const _Tp*
      end() const noexcept
      { return data() + 1; }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 4035. single_view should provide empty
      static constexpr bool
      empty() noexcept
      { return false; }

      static constexpr size_t
      size() noexcept
      { return 1; }

      constexpr _Tp*
      data() noexcept
      { return _M_value.operator->(); }

      constexpr const _Tp*
      data() const noexcept
      { return _M_value.operator->(); }

    private:
      [[no_unique_address]] __detail::__box<_Tp> _M_value;
    };

  template<typename _Tp>
    single_view(_Tp) -> single_view<_Tp>;

  namespace __detail
  {
    template<typename _Wp>
      constexpr auto __to_signed_like(_Wp __w) noexcept
      {
	if constexpr (!integral<_Wp>)
	  return iter_difference_t<_Wp>();
	else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
	  return iter_difference_t<_Wp>(__w);
	else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
	  return ptrdiff_t(__w);
	else if constexpr (sizeof(long long) > sizeof(_Wp))
	  return (long long)(__w);
#ifdef __SIZEOF_INT128__
	else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
	  return __int128(__w);
#endif
	else
	  return __max_diff_type(__w);
      }

    template<typename _Wp>
      using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));

    template<typename _It>
      concept __decrementable = incrementable<_It>
	&& requires(_It __i)
	{
	    { --__i } -> same_as<_It&>;
	    { __i-- } -> same_as<_It>;
	};

    template<typename _It>
      concept __advanceable = __decrementable<_It> && totally_ordered<_It>
	&& requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
	{
	  { __i += __n } -> same_as<_It&>;
	  { __i -= __n } -> same_as<_It&>;
	  _It(__j + __n);
	  _It(__n + __j);
	  _It(__j - __n);
	  { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
	};

    template<typename _Winc>
      struct __iota_view_iter_cat
      { };

    template<incrementable _Winc>
      struct __iota_view_iter_cat<_Winc>
      { using iterator_category = input_iterator_tag; };
  } // namespace __detail

  template<weakly_incrementable _Winc,
	   semiregular _Bound = unreachable_sentinel_t>
    requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
      && copyable<_Winc>
    class iota_view : public view_interface<iota_view<_Winc, _Bound>>
    {
    private:
      struct _Sentinel;

      struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
      {
      private:
	static auto
	_S_iter_concept()
	{
	  using namespace __detail;
	  if constexpr (__advanceable<_Winc>)
	    return random_access_iterator_tag{};
	  else if constexpr (__decrementable<_Winc>)
	    return bidirectional_iterator_tag{};
	  else if constexpr (incrementable<_Winc>)
	    return forward_iterator_tag{};
	  else
	    return input_iterator_tag{};
	}

      public:
	using iterator_concept = decltype(_S_iter_concept());
	// iterator_category defined in __iota_view_iter_cat
	using value_type = _Winc;
	using difference_type = __detail::__iota_diff_t<_Winc>;

	_Iterator() requires default_initializable<_Winc> = default;

	constexpr explicit
	_Iterator(_Winc __value)
	: _M_value(__value) { }

	constexpr _Winc
	operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
	{ return _M_value; }

	constexpr _Iterator&
	operator++()
	{
	  ++_M_value;
	  return *this;
	}

	constexpr void
	operator++(int)
	{ ++*this; }

	constexpr _Iterator
	operator++(int) requires incrementable<_Winc>
	{
	  auto __tmp = *this;
	  ++*this;
	  return __tmp;
	}

	constexpr _Iterator&
	operator--() requires __detail::__decrementable<_Winc>
	{
	  --_M_value;
	  return *this;
	}

	constexpr _Iterator
	operator--(int) requires __detail::__decrementable<_Winc>
	{
	  auto __tmp = *this;
	  --*this;
	  return __tmp;
	}

	constexpr _Iterator&
	operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
	{
	  using __detail::__is_integer_like;
	  using __detail::__is_signed_integer_like;
	  if constexpr (__is_integer_like<_Winc>
	      && !__is_signed_integer_like<_Winc>)
	    {
	      if (__n >= difference_type(0))
		_M_value += static_cast<_Winc>(__n);
	      else
		_M_value -= static_cast<_Winc>(-__n);
	    }
	  else
	    _M_value += __n;
	  return *this;
	}

	constexpr _Iterator&
	operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
	{
	  using __detail::__is_integer_like;
	  using __detail::__is_signed_integer_like;
	  if constexpr (__is_integer_like<_Winc>
	      && !__is_signed_integer_like<_Winc>)
	    {
	      if (__n >= difference_type(0))
		_M_value -= static_cast<_Winc>(__n);
	      else
		_M_value += static_cast<_Winc>(-__n);
	    }
	  else
	    _M_value -= __n;
	  return *this;
	}

	constexpr _Winc
	operator[](difference_type __n) const
	requires __detail::__advanceable<_Winc>
	{ return _Winc(_M_value + __n); }

	friend constexpr bool
	operator==(const _Iterator& __x, const _Iterator& __y)
	requires equality_comparable<_Winc>
	{ return __x._M_value == __y._M_value; }

	friend constexpr bool
	operator<(const _Iterator& __x, const _Iterator& __y)
	requires totally_ordered<_Winc>
	{ return __x._M_value < __y._M_value; }

	friend constexpr bool
	operator>(const _Iterator& __x, const _Iterator& __y)
	  requires totally_ordered<_Winc>
	{ return __y < __x; }

	friend constexpr bool
	operator<=(const _Iterator& __x, const _Iterator& __y)
	  requires totally_ordered<_Winc>
	{ return !(__y < __x); }

	friend constexpr bool
	operator>=(const _Iterator& __x, const _Iterator& __y)
	  requires totally_ordered<_Winc>
	{ return !(__x < __y); }

#ifdef __cpp_lib_three_way_comparison
	friend constexpr auto
	operator<=>(const _Iterator& __x, const _Iterator& __y)
	  requires totally_ordered<_Winc> && three_way_comparable<_Winc>
	{ return __x._M_value <=> __y._M_value; }
#endif

	friend constexpr _Iterator
	operator+(_Iterator __i, difference_type __n)
	  requires __detail::__advanceable<_Winc>
	{
	  __i += __n;
	  return __i;
	}

	friend constexpr _Iterator
	operator+(difference_type __n, _Iterator __i)
	  requires __detail::__advanceable<_Winc>
	{ return __i += __n; }

	friend constexpr _Iterator
	operator-(_Iterator __i, difference_type __n)
	  requires __detail::__advanceable<_Winc>
	{
	  __i -= __n;
	  return __i;
	}

	friend constexpr difference_type
	operator-(const _Iterator& __x, const _Iterator& __y)
	  requires __detail::__advanceable<_Winc>
	{
	  using __detail::__is_integer_like;
	  using __detail::__is_signed_integer_like;
	  using _Dt = difference_type;
	  if constexpr (__is_integer_like<_Winc>)
	    {
	      if constexpr (__is_signed_integer_like<_Winc>)
		return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
	      else
		return (__y._M_value > __x._M_value)
		  ? _Dt(-_Dt(__y._M_value - __x._M_value))
		  : _Dt(__x._M_value - __y._M_value);
	    }
	  else
	    return __x._M_value - __y._M_value;
	}

      private:
	_Winc _M_value = _Winc();

	friend iota_view;
        friend _Sentinel;
      };

      struct _Sentinel
      {
      private:
	_Bound _M_bound = _Bound();

      public:
	_Sentinel() = default;

	constexpr explicit
	_Sentinel(_Bound __bound)
	: _M_bound(__bound) { }

	friend constexpr bool
	operator==(const _Iterator& __x, const _Sentinel& __y)
	{ return __x._M_value == __y._M_bound; }

	friend constexpr iter_difference_t<_Winc>
	operator-(const _Iterator& __x, const _Sentinel& __y)
	  requires sized_sentinel_for<_Bound, _Winc>
	{ return -(__y._M_bound - __x._M_value); }

	friend constexpr iter_difference_t<_Winc>
	operator-(const _Sentinel& __x, const _Iterator& __y)
	  requires sized_sentinel_for<_Bound, _Winc>
	{ return __x._M_bound - __y._M_value; }

	friend iota_view;
      };

      _Winc _M_value = _Winc();
      [[no_unique_address]] _Bound _M_bound = _Bound();

    public:
      iota_view() requires default_initializable<_Winc> = default;

      constexpr explicit
      iota_view(_Winc __value)
      : _M_value(__value)
      { }

      constexpr explicit
      iota_view(type_identity_t<_Winc> __value,
		type_identity_t<_Bound> __bound)
      : _M_value(__value), _M_bound(__bound)
      {
	if constexpr (totally_ordered_with<_Winc, _Bound>)
	  __glibcxx_assert( bool(__value <= __bound) );
      }

      constexpr explicit
      iota_view(_Iterator __first, _Iterator __last)
	requires same_as<_Winc, _Bound>
	: iota_view(__first._M_value, __last._M_value)
      { }

      constexpr explicit
      iota_view(_Iterator __first, unreachable_sentinel_t __last)
	requires same_as<_Bound, unreachable_sentinel_t>
	: iota_view(__first._M_value, __last)
      { }

      constexpr explicit
      iota_view(_Iterator __first, _Sentinel __last)
	requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
	: iota_view(__first._M_value, __last._M_bound)
      { }

      constexpr _Iterator
      begin() const { return _Iterator{_M_value}; }

      constexpr auto
      end() const
      {
	if constexpr (same_as<_Bound, unreachable_sentinel_t>)
	  return unreachable_sentinel;
	else
	  return _Sentinel{_M_bound};
      }

      constexpr _Iterator
      end() const requires same_as<_Winc, _Bound>
      { return _Iterator{_M_bound}; }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 4001. iota_view should provide empty
      constexpr bool
      empty() const
      { return _M_value == _M_bound; }

      constexpr auto
      size() const
      requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
      || (integral<_Winc> && integral<_Bound>)
      || sized_sentinel_for<_Bound, _Winc>
      {
	using __detail::__is_integer_like;
	using __detail::__to_unsigned_like;
	if constexpr (integral<_Winc> && integral<_Bound>)
	  {
	    using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
	    return _Up(_M_bound) - _Up(_M_value);
	  }
	else if constexpr (__is_integer_like<_Winc>)
	  return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
	else
	  return __to_unsigned_like(_M_bound - _M_value);
      }
    };

  template<typename _Winc, typename _Bound>
    requires (!__detail::__is_integer_like<_Winc>
	|| !__detail::__is_integer_like<_Bound>
	|| (__detail::__is_signed_integer_like<_Winc>
	    == __detail::__is_signed_integer_like<_Bound>))
    iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;

  template<typename _Winc, typename _Bound>
    inline constexpr bool
      enable_borrowed_range<iota_view<_Winc, _Bound>> = true;

namespace views
{
  template<typename _Tp>
    inline constexpr empty_view<_Tp> empty{};

  namespace __detail
  {
    template<typename _Tp>
      concept __can_single_view
	= requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
  } // namespace __detail

  struct _Single
  {
    template<__detail::__can_single_view _Tp>
      constexpr auto
      operator() [[nodiscard]] (_Tp&& __e) const
      noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
      { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
  };

  inline constexpr _Single single{};

  namespace __detail
  {
    template<typename... _Args>
      concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); };
  } // namespace __detail

  struct _Iota
  {
    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 4096. views::iota(views::iota(0)) should be rejected
    template<__detail::__can_iota_view _Tp>
      constexpr iota_view<decay_t<_Tp>>
      operator() [[nodiscard]] (_Tp&& __e) const
      { return iota_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }

    template<typename _Tp, typename _Up>
      requires __detail::__can_iota_view<_Tp, _Up>
      constexpr auto
      operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const
      { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
  };

  inline constexpr _Iota iota{};

#ifdef __cpp_lib_ranges_indices // C++ >= 26
  struct _Indices
  {
    template<ranges::__detail::__is_integer_like _Tp>
      requires __detail::__can_iota_view<_Tp>
      [[nodiscard]] constexpr auto
      operator() (_Tp __e) const noexcept
      { return iota(_Tp{}, __e); }
  };

  inline constexpr _Indices indices{};
#endif // __cpp_lib_ranges_indices
} // namespace views

#if _GLIBCXX_HOSTED
  namespace __detail
  {
    template<typename _Val, typename _CharT, typename _Traits>
      concept __stream_extractable
	= requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
  } // namespace __detail

  template<movable _Val, typename _CharT,
	   typename _Traits = char_traits<_CharT>>
    requires default_initializable<_Val>
      && __detail::__stream_extractable<_Val, _CharT, _Traits>
    class basic_istream_view
    : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
    {
    public:
      constexpr explicit
      basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
	: _M_stream(std::__addressof(__stream))
      { }

      constexpr auto
      begin()
      {
	*_M_stream >> _M_object;
	return _Iterator{this};
      }

      constexpr default_sentinel_t
      end() const noexcept
      { return default_sentinel; }

    private:
      basic_istream<_CharT, _Traits>* _M_stream;
      _Val _M_object = _Val();

      struct _Iterator
      {
      public:
	using iterator_concept = input_iterator_tag;
	using difference_type = ptrdiff_t;
	using value_type = _Val;

	constexpr explicit
	_Iterator(basic_istream_view* __parent) noexcept
	  : _M_parent(__parent)
	{ }

	_Iterator(const _Iterator&) = delete;
	_Iterator(_Iterator&&) = default;
	_Iterator& operator=(const _Iterator&) = delete;
	_Iterator& operator=(_Iterator&&) = default;

	_Iterator&
	operator++()
	{
	  *_M_parent->_M_stream >> _M_parent->_M_object;
	  return *this;
	}

	void
	operator++(int)
	{ ++*this; }

	_Val&
	operator*() const
	{ return _M_parent->_M_object; }

	friend bool
	operator==(const _Iterator& __x, default_sentinel_t)
	{ return !*__x._M_parent->_M_stream; }

      private:
	basic_istream_view* _M_parent;
      };

      friend _Iterator;
    };

  template<typename _Val>
    using istream_view = basic_istream_view<_Val, char>;

  template<typename _Val>
    using wistream_view = basic_istream_view<_Val, wchar_t>;

namespace views
{
  namespace __detail
  {
    template<typename _Tp, typename _Up>
    concept __can_istream_view = requires (_Up __e) {
      basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
    };
  } // namespace __detail

  template<typename _Tp>
    struct _Istream
    {
      template<typename _CharT, typename _Traits>
	constexpr auto
	operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
	requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
	{ return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
    };

  template<typename _Tp>
    inline constexpr _Istream<_Tp> istream;
}
#endif // HOSTED

  // C++20 24.7 [range.adaptors] Range adaptors

namespace __detail
{
  template<typename _Tp, int _Disc>
    struct _Absent { };

  // Alias for a type that is conditionally present
  // (and is an empty type otherwise).
  // Data members using this alias should use [[no_unique_address]] so that
  // they take no space when not needed.
  // The optional template parameter _Disc is for discriminating two otherwise
  // equivalent absent types so that even they can overlap.
  template<bool _Present, typename _Tp, int _Disc = 0>
    using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;

  // Alias for a type that is conditionally const.
  template<bool _Const, typename _Tp>
    using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;

} // namespace __detail

// Shorthand for __detail::__maybe_const_t.
using __detail::__maybe_const_t;

namespace views::__adaptor
{
  // True if the range adaptor _Adaptor can be applied with _Args.
  template<typename _Adaptor, typename... _Args>
    concept __adaptor_invocable
      = requires { std::declval<_Adaptor>()(declval<_Args>()...); };

  // True if the range adaptor non-closure _Adaptor can be partially applied
  // with _Args.
  template<typename _Adaptor, typename... _Args>
    concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
      && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
      && (constructible_from<decay_t<_Args>, _Args> && ...);

  template<typename _Adaptor, typename... _Args>
    struct _Partial;

  template<typename _Lhs, typename _Rhs>
    struct _Pipe;

  // The base class of every range adaptor closure.
  //
  // The derived class should define the optional static data member
  // _S_has_simple_call_op to true if the behavior of this adaptor is
  // independent of the constness/value category of the adaptor object.
  template<typename _Derived>
    struct _RangeAdaptorClosure;

  template<typename _Tp, typename _Up>
    requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
    void __is_range_adaptor_closure_fn
      (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined

  template<typename _Tp>
    concept __is_range_adaptor_closure
      = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-reference"
  // range | adaptor is equivalent to adaptor(range).
  template<typename _Self, typename _Range>
    requires __is_range_adaptor_closure<_Self>
      && __adaptor_invocable<_Self, _Range>
    constexpr auto
    operator|(_Range&& __r, _Self&& __self)
    { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }

  // Compose the adaptors __lhs and __rhs into a pipeline, returning
  // another range adaptor closure object.
  template<typename _Lhs, typename _Rhs>
    requires __is_range_adaptor_closure<_Lhs>
      && __is_range_adaptor_closure<_Rhs>
    constexpr auto
    operator|(_Lhs&& __lhs, _Rhs&& __rhs)
    {
      return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
						 std::forward<_Rhs>(__rhs)};
    }
#pragma GCC diagnostic pop

  template<typename _Derived>
    struct _RangeAdaptorClosure
    {
      // In non-modules compilation ADL finds these operators either way and
      // the friend declarations are redundant.  But with the std module these
      // friend declarations enable ADL to find these operators without having
      // to export them.
      template<typename _Self, typename _Range>
	requires __is_range_adaptor_closure<_Self>
	  && __adaptor_invocable<_Self, _Range>
	friend constexpr auto
	operator|(_Range&& __r, _Self&& __self);

      template<typename _Lhs, typename _Rhs>
	requires __is_range_adaptor_closure<_Lhs>
	  && __is_range_adaptor_closure<_Rhs>
	friend constexpr auto
	operator|(_Lhs&& __lhs, _Rhs&& __rhs);
    };

  // The base class of every range adaptor non-closure.
  //
  // The static data member _Derived::_S_arity must contain the total number of
  // arguments that the adaptor takes, and the class _Derived must introduce
  // _RangeAdaptor::operator() into the class scope via a using-declaration.
  //
  // The optional static data member _Derived::_S_has_simple_extra_args should
  // be defined to true if the behavior of this adaptor is independent of the
  // constness/value category of the extra arguments.  This data member could
  // also be defined as a variable template parameterized by the types of the
  // extra arguments.
  template<typename _Derived>
    struct _RangeAdaptor
    {
      // Partially apply the arguments __args to the range adaptor _Derived,
      // returning a range adaptor closure object.
      template<typename... _Args>
	requires __adaptor_partial_app_viable<_Derived, _Args...>
	constexpr auto
	operator()(_Args&&... __args) const
	{
	  return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
	}
    };

  // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
  // one that's not overloaded according to constness or value category of the
  // _Adaptor object.
  template<typename _Adaptor>
    concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;

  // True if the behavior of the range adaptor non-closure _Adaptor is
  // independent of the value category of its extra arguments _Args.
  template<typename _Adaptor, typename... _Args>
    concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
      || _Adaptor::template _S_has_simple_extra_args<_Args...>;

  // A range adaptor closure that represents partial application of
  // the range adaptor _Adaptor with arguments _Args.
  template<typename _Adaptor, typename... _Args>
    struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
    {
      using _Binder = _Bind_back_t<_Adaptor, _Args...>;
      [[no_unique_address]] _Binder _M_binder;

      // First parameter is to ensure this constructor is never used
      // instead of the copy/move constructor.
      template<typename... _Ts>
	constexpr
	_Partial(int, _Ts&&... __args)
	  : _M_binder(0, _Adaptor(), std::forward<_Ts>(__args)...)
	{ }

      // Invoke _Adaptor with arguments __r, _M_args... according to the
      // value category of this _Partial object.
#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wc++23-extensions" // deducing this
      template<typename _Self, typename _Range>
	requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
	constexpr auto
	operator()(this _Self&& __self, _Range&& __r)
	{
	  return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
				  std::forward<_Range>(__r));
	}
# pragma GCC diagnostic pop
#else
      template<typename _Range>
	requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
	constexpr auto
	operator()(_Range&& __r) const &
	{ return _Binder::_S_call(_M_binder, std::forward<_Range>(__r)); }

      template<typename _Range>
	requires __adaptor_invocable<_Adaptor, _Range, _Args...>
	constexpr auto
	operator()(_Range&& __r) &&
	{ return _Binder::_S_call(std::move(_M_binder), std::forward<_Range>(__r)); }

      template<typename _Range>
	constexpr auto
	operator()(_Range&& __r) const && = delete;
#endif
    };

  // Partial specialization of the primary template for the case where the extra
  // arguments of the adaptor can always be safely and efficiently forwarded by
  // const reference.  This lets us get away with a single operator() overload,
  // which makes overload resolution failure diagnostics more concise.
  template<typename _Adaptor, typename... _Args>
    requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
      && (is_trivially_copy_constructible_v<_Args> && ...)
    struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
    {
      using _Binder = _Bind_back_t<_Adaptor, _Args...>;
      [[no_unique_address]] _Binder _M_binder;

      template<typename... _Ts>
	constexpr
	_Partial(int, _Ts&&... __args)
	  : _M_binder(0, _Adaptor(), std::forward<_Ts>(__args)...)
	{ }

      // Invoke _Adaptor with arguments __r, const _M_args&... regardless
      // of the value category of this _Partial object.
      template<typename _Range>
	requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
	constexpr auto
	operator()(_Range&& __r) const
	{ return _Binder::_S_call(_M_binder, std::forward<_Range>(__r)); }

      static constexpr bool _S_has_simple_call_op = true;
    };

  template<typename _Lhs, typename _Rhs, typename _Range>
    concept __pipe_invocable
      = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };

  // A range adaptor closure that represents composition of the range
  // adaptor closures _Lhs and _Rhs.
  template<typename _Lhs, typename _Rhs>
    struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
    {
      [[no_unique_address]] _Lhs _M_lhs;
      [[no_unique_address]] _Rhs _M_rhs;

      template<typename _Tp, typename _Up>
	constexpr
	_Pipe(_Tp&& __lhs, _Up&& __rhs)
	  : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
	{ }

      // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
      // range adaptor closure object.
#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wc++23-extensions" // deducing this
      template<typename _Self, typename _Range>
	requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
	constexpr auto
	operator()(this _Self&& __self, _Range&& __r)
	{
	  return (__like_t<_Self, _Pipe>(__self)._M_rhs
		  (__like_t<_Self, _Pipe>(__self)._M_lhs
		   (std::forward<_Range>(__r))));
	}
# pragma GCC diagnostic pop
#else
      template<typename _Range>
	requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
	constexpr auto
	operator()(_Range&& __r) const &
	{ return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }

      template<typename _Range>
	requires __pipe_invocable<_Lhs, _Rhs, _Range>
	constexpr auto
	operator()(_Range&& __r) &&
	{ return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }

      template<typename _Range>
	constexpr auto
	operator()(_Range&& __r) const && = delete;
#endif
    };

  // A partial specialization of the above primary template for the case where
  // both adaptor operands have a simple operator().  This in turn lets us
  // implement composition using a single simple operator(), which makes
  // overload resolution failure diagnostics more concise.
  template<typename _Lhs, typename _Rhs>
    requires __closure_has_simple_call_op<_Lhs>
      && __closure_has_simple_call_op<_Rhs>
    struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
    {
      [[no_unique_address]] _Lhs _M_lhs;
      [[no_unique_address]] _Rhs _M_rhs;

      template<typename _Tp, typename _Up>
	constexpr
	_Pipe(_Tp&& __lhs, _Up&& __rhs)
	  : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
	{ }

      template<typename _Range>
	requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
	constexpr auto
	operator()(_Range&& __r) const
	{ return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }

      static constexpr bool _S_has_simple_call_op = true;
    };
} // namespace views::__adaptor

#if __cpp_lib_ranges >= 202202L
  // P2387R3 Pipe support for user-defined range adaptors
  template<typename _Derived>
    requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
    class range_adaptor_closure
    : public views::__adaptor::_RangeAdaptorClosure<_Derived>
    { };
#endif

  template<range _Range> requires is_object_v<_Range>
    class ref_view : public view_interface<ref_view<_Range>>
    {
    private:
      _Range* _M_r;

      static void _S_fun(_Range&); // not defined
      static void _S_fun(_Range&&) = delete;

    public:
      template<__detail::__different_from<ref_view> _Tp>
	requires convertible_to<_Tp, _Range&>
	  && requires { _S_fun(declval<_Tp>()); }
	constexpr
	ref_view(_Tp&& __t)
	noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
	  : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
	{ }

      constexpr _Range&
      base() const
      { return *_M_r; }

      constexpr iterator_t<_Range>
      begin() const
      { return ranges::begin(*_M_r); }

      constexpr sentinel_t<_Range>
      end() const
      { return ranges::end(*_M_r); }

      constexpr bool
      empty() const requires requires { ranges::empty(*_M_r); }
      { return ranges::empty(*_M_r); }

      constexpr auto
      size() const requires sized_range<_Range>
      { return ranges::size(*_M_r); }

      constexpr auto
      data() const requires contiguous_range<_Range>
      { return ranges::data(*_M_r); }
    };

  template<typename _Range>
    ref_view(_Range&) -> ref_view<_Range>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;

  template<range _Range>
    requires movable<_Range>
      && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
    class owning_view : public view_interface<owning_view<_Range>>
    {
    private:
      _Range _M_r = _Range();

    public:
      owning_view() requires default_initializable<_Range> = default;

      constexpr
      owning_view(_Range&& __t)
      noexcept(is_nothrow_move_constructible_v<_Range>)
	: _M_r(std::move(__t))
      { }

      owning_view(owning_view&&) = default;
      owning_view& operator=(owning_view&&) = default;

      constexpr _Range&
      base() & noexcept
      { return _M_r; }

      constexpr const _Range&
      base() const& noexcept
      { return _M_r; }

      constexpr _Range&&
      base() && noexcept
      { return std::move(_M_r); }

      constexpr const _Range&&
      base() const&& noexcept
      { return std::move(_M_r); }

      constexpr iterator_t<_Range>
      begin()
      { return ranges::begin(_M_r); }

      constexpr sentinel_t<_Range>
      end()
      { return ranges::end(_M_r); }

      constexpr auto
      begin() const requires range<const _Range>
      { return ranges::begin(_M_r); }

      constexpr auto
      end() const requires range<const _Range>
      { return ranges::end(_M_r); }

      constexpr bool
      empty() requires requires { ranges::empty(_M_r); }
      { return ranges::empty(_M_r); }

      constexpr bool
      empty() const requires requires { ranges::empty(_M_r); }
      { return ranges::empty(_M_r); }

      constexpr auto
      size() requires sized_range<_Range>
      { return ranges::size(_M_r); }

      constexpr auto
      size() const requires sized_range<const _Range>
      { return ranges::size(_M_r); }

      constexpr auto
      data() requires contiguous_range<_Range>
      { return ranges::data(_M_r); }

      constexpr auto
      data() const requires contiguous_range<const _Range>
      { return ranges::data(_M_r); }
    };

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range>
	concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };

      template<typename _Range>
	concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
    } // namespace __detail

    struct _All : __adaptor::_RangeAdaptorClosure<_All>
    {
      template<typename _Range>
	static constexpr bool
	_S_noexcept()
	{
	  if constexpr (view<decay_t<_Range>>)
	    return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
	  else if constexpr (__detail::__can_ref_view<_Range>)
	    return true;
	  else
	    return noexcept(owning_view{std::declval<_Range>()});
	}

      template<viewable_range _Range>
	requires view<decay_t<_Range>>
	  || __detail::__can_ref_view<_Range>
	  || __detail::__can_owning_view<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	noexcept(_S_noexcept<_Range>())
	{
	  if constexpr (view<decay_t<_Range>>)
	    return std::forward<_Range>(__r);
	  else if constexpr (__detail::__can_ref_view<_Range>)
	    return ref_view{std::forward<_Range>(__r)};
	  else
	    return owning_view{std::forward<_Range>(__r)};
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _All all;

    template<viewable_range _Range>
      using all_t = decltype(all(std::declval<_Range>()));
  } // namespace views

  namespace __detail
  {
    template<typename _Tp>
      struct __non_propagating_cache
      {
	// When _Tp is not an object type (e.g. is a reference type), we make
	// __non_propagating_cache<_Tp> empty rather than ill-formed so that
	// users can easily conditionally declare data members with this type
	// (such as join_view::_M_inner).
      };

    template<typename _Tp>
      requires is_object_v<_Tp>
      struct __non_propagating_cache<_Tp>
      : protected _Optional_base<_Tp>
      {
	__non_propagating_cache() = default;

	constexpr
	__non_propagating_cache(const __non_propagating_cache&) noexcept
	{ }

	constexpr
	__non_propagating_cache(__non_propagating_cache&& __other) noexcept
	{ __other._M_reset(); }

	constexpr __non_propagating_cache&
	operator=(const __non_propagating_cache& __other) noexcept
	{
	  if (std::__addressof(__other) != this)
	    this->_M_reset();
	  return *this;
	}

	constexpr __non_propagating_cache&
	operator=(__non_propagating_cache&& __other) noexcept
	{
	  this->_M_reset();
	  __other._M_reset();
	  return *this;
	}

	constexpr __non_propagating_cache&
	operator=(_Tp __val)
	{
	  this->_M_reset();
	  this->_M_payload._M_construct(std::move(__val));
	  return *this;
	}

	constexpr explicit
	operator bool() const noexcept
	{ return this->_M_is_engaged(); }

	constexpr _Tp&
	operator*() noexcept
	{ return this->_M_get(); }

	constexpr const _Tp&
	operator*() const noexcept
	{ return this->_M_get(); }

	template<typename _Iter>
	  constexpr _Tp&
	  _M_emplace_deref(const _Iter& __i)
	  {
	    this->_M_reset();
	    auto __f = [] (auto& __x) { return *__x; };
	    this->_M_payload._M_apply(_Optional_func{__f}, __i);
	    return this->_M_get();
	  }

	using _Optional_base<_Tp>::_M_reset;
      };

    template<range _Range>
      struct _CachedPosition
      {
	constexpr bool
	_M_has_value() const
	{ return false; }

	constexpr iterator_t<_Range>
	_M_get(const _Range&) const
	{
	  __glibcxx_assert(false);
	  __builtin_unreachable();
	}

	constexpr void
	_M_set(const _Range&, const iterator_t<_Range>&) const
	{ }
      };

    template<forward_range _Range>
      struct _CachedPosition<_Range>
	: protected __non_propagating_cache<iterator_t<_Range>>
      {
	constexpr bool
	_M_has_value() const
	{ return this->_M_is_engaged(); }

	constexpr iterator_t<_Range>
	_M_get(const _Range&) const
	{
	  __glibcxx_assert(_M_has_value());
	  return **this;
	}

	constexpr void
	_M_set(const _Range&, const iterator_t<_Range>& __it)
	{
	  __glibcxx_assert(!_M_has_value());
	  std::construct_at(std::__addressof(this->_M_payload._M_payload),
			    in_place, __it);
	  this->_M_payload._M_engaged = true;
	}
      };

    template<random_access_range _Range>
      struct _CachedPosition<_Range>
      {
      private:
	range_difference_t<_Range> _M_offset = -1;

      public:
	_CachedPosition() = default;

	constexpr
	_CachedPosition(const _CachedPosition&) = default;

	constexpr
	_CachedPosition(_CachedPosition&& __other) noexcept
	{ *this = std::move(__other); }

	constexpr _CachedPosition&
	operator=(const _CachedPosition&) = default;

	constexpr _CachedPosition&
	operator=(_CachedPosition&& __other) noexcept
	{
	  // Propagate the cached offset, but invalidate the source.
	  _M_offset = __other._M_offset;
	  __other._M_offset = -1;
	  return *this;
	}

	constexpr bool
	_M_has_value() const
	{ return _M_offset >= 0; }

	constexpr iterator_t<_Range>
	_M_get(_Range& __r) const
	{
	  __glibcxx_assert(_M_has_value());
	  return ranges::begin(__r) + _M_offset;
	}

	constexpr void
	_M_set(_Range& __r, const iterator_t<_Range>& __it)
	{
	  __glibcxx_assert(!_M_has_value());
	  _M_offset = __it - ranges::begin(__r);
	}
      };
  } // namespace __detail

  namespace __detail
  {
    template<typename _Base>
      struct __filter_view_iter_cat
      { };

    template<forward_range _Base>
      struct __filter_view_iter_cat<_Base>
      {
      private:
	static auto
	_S_iter_cat()
	{
	  using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
	  if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
	    return bidirectional_iterator_tag{};
	  else if constexpr (derived_from<_Cat, forward_iterator_tag>)
	    return forward_iterator_tag{};
	  else
	    return _Cat{};
	}
      public:
	using iterator_category = decltype(_S_iter_cat());
      };
  } // namespace __detail

  template<input_range _Vp,
	   indirect_unary_predicate<iterator_t<_Vp>> _Pred>
    requires view<_Vp> && is_object_v<_Pred>
    class filter_view : public view_interface<filter_view<_Vp, _Pred>>
    {
    private:
      template<bool _Const>
      struct _Sentinel;

      template<bool _Const>
      struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
      {
      private:
	static constexpr auto
	_S_iter_concept()
	{
	  if constexpr (_Const)
	    return input_iterator_tag{};
	  else if constexpr (bidirectional_range<_Vp>)
	    return bidirectional_iterator_tag{};
	  else if constexpr (forward_range<_Vp>)
	    return forward_iterator_tag{};
	  else
	    return input_iterator_tag{};
	}

	friend filter_view;
	friend _Iterator<!_Const>;

	using _Parent = __maybe_const_t<_Const, filter_view>;
	using _Base = __maybe_const_t<_Const, _Vp>;
	using _Base_iter = iterator_t<_Base>;

	_Base_iter _M_current = _Base_iter();
	_Parent* _M_parent = nullptr;

      public:
	using iterator_concept = decltype(_S_iter_concept());
	// iterator_category defined in __filter_view_iter_cat
	using value_type = range_value_t<_Base>;
	using difference_type = range_difference_t<_Base>;

	_Iterator() requires default_initializable<_Base_iter> = default;

	constexpr
	_Iterator(_Parent* __parent, _Base_iter __current)
	  : _M_current(std::move(__current)),
	    _M_parent(__parent)
	{ }

	constexpr
	_Iterator(_Iterator<!_Const> __i)
	  requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
	  : _M_current(std::move(__i._M_current)),
	    _M_parent(std::move(__i._M_parent))
	{ }

	constexpr const _Base_iter&
	base() const & noexcept
	{ return _M_current; }

	constexpr _Base_iter
	base() &&
	{ return std::move(_M_current); }

	constexpr range_reference_t<_Base>
	operator*() const
	{ return *_M_current; }

	constexpr _Base_iter
	operator->() const
	  requires __detail::__has_arrow<_Base_iter>
	    && copyable<_Base_iter>
	{ return _M_current; }

	constexpr _Iterator&
	operator++()
	{
	  _M_current = ranges::find_if(std::move(++_M_current),
				       ranges::end(_M_parent->_M_base),
				       std::ref(*_M_parent->_M_pred));
	  return *this;
	}

	constexpr void
	operator++(int)
	{ ++*this; }

	constexpr _Iterator
	operator++(int) requires forward_range<_Base>
	{
	  auto __tmp = *this;
	  ++*this;
	  return __tmp;
	}

	constexpr _Iterator&
	operator--() requires bidirectional_range<_Base>
	{
	  do
	    --_M_current;
	  while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
	  return *this;
	}

	constexpr _Iterator
	operator--(int) requires bidirectional_range<_Base>
	{
	  auto __tmp = *this;
	  --*this;
	  return __tmp;
	}

	friend constexpr bool
	operator==(const _Iterator& __x, const _Iterator& __y)
	  requires equality_comparable<_Base_iter>
	{ return __x._M_current == __y._M_current; }

	friend constexpr range_rvalue_reference_t<_Base>
	iter_move(const _Iterator& __i)
	  noexcept(noexcept(ranges::iter_move(__i._M_current)))
	{ return ranges::iter_move(__i._M_current); }

	friend constexpr void
	iter_swap(const _Iterator& __x, const _Iterator& __y)
	  noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
	  requires indirectly_swappable<_Base_iter>
	{ ranges::iter_swap(__x._M_current, __y._M_current); }
      };

      template<bool _Const>
      struct _Sentinel
      {
      private:
	using _Parent = __maybe_const_t<_Const, filter_view>;
	using _Base = __maybe_const_t<_Const, _Vp>;
	sentinel_t<_Base> _M_end = sentinel_t<_Base>();

	friend _Sentinel<!_Const>;

      public:
	_Sentinel() = default;

	constexpr explicit
	_Sentinel(_Parent* __parent)
	  : _M_end(ranges::end(__parent->_M_base))
	{ }

	constexpr
	_Sentinel(_Sentinel<!_Const> __i)
	  requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	  : _M_end(std::move(__i._M_end))
	{ }

	constexpr sentinel_t<_Base>
	base() const
	{ return _M_end; }

	template<bool _Const2>
	  requires sentinel_for<sentinel_t<_Base>,
		     iterator_t<__maybe_const_t<_Const2, _Vp>>>
	  friend constexpr bool
	  operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	  { return __x._M_current == __y._M_end; }
      };

      _Vp _M_base = _Vp();
      [[no_unique_address]] __detail::__box<_Pred> _M_pred;
      [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;

    public:
      filter_view() requires (default_initializable<_Vp>
			      && default_initializable<_Pred>)
	= default;

      constexpr explicit
      filter_view(_Vp __base, _Pred __pred)
	: _M_base(std::move(__base)), _M_pred(std::move(__pred))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr const _Pred&
      pred() const
      { return *_M_pred; }

      constexpr _Iterator<false>
      begin()
      {
	if (_M_cached_begin._M_has_value())
	  return {this, _M_cached_begin._M_get(_M_base)};

	__glibcxx_assert(_M_pred.has_value());
	auto __it = ranges::find_if(ranges::begin(_M_base),
				    ranges::end(_M_base),
				    std::ref(*_M_pred));
	_M_cached_begin._M_set(_M_base, __it);
	return {this, std::move(__it)};
      }

      constexpr _Iterator<true>
      begin() const
	requires (input_range<const _Vp> && !forward_range<const _Vp>
		  && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>)
      {
	__glibcxx_assert(_M_pred.has_value());
	auto __it = ranges::find_if(ranges::begin(_M_base),
				    ranges::end(_M_base),
				    std::ref(*_M_pred));
	return {this, std::move(__it)};
      }

      constexpr auto
      end()
      {
	if constexpr (common_range<_Vp>)
	  return _Iterator<false>{this, ranges::end(_M_base)};
	else
	  return _Sentinel<false>{this};
      }

      constexpr _Sentinel<true>
      end() const
	requires (input_range<const _Vp> && !forward_range<const _Vp>
		  && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>)
      { return _Sentinel<true>{this}; }
    };

  template<typename _Range, typename _Pred>
    filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pred>
	concept __can_filter_view
	  = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
    } // namespace __detail

    struct _Filter : __adaptor::_RangeAdaptor<_Filter>
    {
      template<viewable_range _Range, typename _Pred>
	requires __detail::__can_filter_view<_Range, _Pred>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
	{
	  return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
	}

      using _RangeAdaptor<_Filter>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _Filter filter;
  } // namespace views

#if __cpp_lib_ranges >= 202207L // C++ >= 23
  template<input_range _Vp, move_constructible _Fp>
#else
  template<input_range _Vp, copy_constructible _Fp>
#endif
    requires view<_Vp> && is_object_v<_Fp>
      && regular_invocable<_Fp&, range_reference_t<_Vp>>
      && std::__detail::__can_reference<invoke_result_t<_Fp&,
							range_reference_t<_Vp>>>
    class transform_view : public view_interface<transform_view<_Vp, _Fp>>
    {
    private:
      template<bool _Const>
	using _Base = __detail::__maybe_const_t<_Const, _Vp>;

      template<bool _Const>
	struct __iter_cat
	{ };

      template<bool _Const>
	requires forward_range<_Base<_Const>>
	struct __iter_cat<_Const>
	{
	private:
	  static auto
	  _S_iter_cat()
	  {
	    // _GLIBCXX_RESOLVE_LIB_DEFECTS
	    // 3564. transform_view::iterator<true>::value_type and
	    // iterator_category should use const F&
	    using _Base = transform_view::_Base<_Const>;
	    using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
					 range_reference_t<_Base>>;
	    // _GLIBCXX_RESOLVE_LIB_DEFECTS
	    // 3798. Rvalue reference and iterator_category
	    if constexpr (is_reference_v<_Res>)
	      {
		using _Cat
		  = typename iterator_traits<iterator_t<_Base>>::iterator_category;
		if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
		  return random_access_iterator_tag{};
		else
		  return _Cat{};
	      }
	    else
	      return input_iterator_tag{};
	  }
	public:
	  using iterator_category = decltype(_S_iter_cat());
	};

      template<bool _Const>
	struct _Sentinel;

      template<bool _Const>
	struct _Iterator : __iter_cat<_Const>
	{
	private:
	  using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
	  using _Base = transform_view::_Base<_Const>;
	  using _Base_iter = iterator_t<_Base>;
	  using _Func_handle = __detail::__func_handle_t<
				 __detail::__maybe_const_t<_Const, _Fp>,
				 _Base_iter>;

	  static auto
	  _S_iter_concept()
	  {
	    if constexpr (random_access_range<_Base>)
	      return random_access_iterator_tag{};
	    else if constexpr (bidirectional_range<_Base>)
	      return bidirectional_iterator_tag{};
	    else if constexpr (forward_range<_Base>)
	      return forward_iterator_tag{};
	    else
	      return input_iterator_tag{};
	  }

	  _Base_iter _M_current = _Base_iter();
	  [[no_unique_address]] _Func_handle _M_fun;

	public:
	  using iterator_concept = decltype(_S_iter_concept());
	  // iterator_category defined in __transform_view_iter_cat
	  using value_type
	    = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
					     range_reference_t<_Base>>>;
	  using difference_type = range_difference_t<_Base>;

	  _Iterator() requires default_initializable<_Base_iter> = default;

	  constexpr
	  _Iterator(_Func_handle __fun, _Base_iter __current)
	    : _M_current(std::move(__current)), _M_fun(__fun)
	  { }

	  constexpr
	  _Iterator(_Parent* __parent, _Base_iter __current)
	    : _M_current(std::move(__current)), _M_fun(*__parent->_M_fun)
	  {}

	  constexpr
	  _Iterator(_Iterator<!_Const> __i)
	    requires _Const
	      && convertible_to<iterator_t<_Vp>, _Base_iter>
	    : _M_current(std::move(__i._M_current)), _M_fun(__i._M_fun)
	  { }

	  constexpr const _Base_iter&
	  base() const & noexcept
	  { return _M_current; }

	  constexpr _Base_iter
	  base() &&
	  { return std::move(_M_current); }

	  constexpr decltype(auto)
	  operator*() const
	    noexcept(noexcept(_M_fun._M_call_deref(_M_current)))
	  { return _M_fun._M_call_deref(_M_current); }

	  constexpr _Iterator&
	  operator++()
	  {
	    ++_M_current;
	    return *this;
	  }

	  constexpr void
	  operator++(int)
	  { ++_M_current; }

	  constexpr _Iterator
	  operator++(int) requires forward_range<_Base>
	  {
	    auto __tmp = *this;
	    ++*this;
	    return __tmp;
	  }

	  constexpr _Iterator&
	  operator--() requires bidirectional_range<_Base>
	  {
	    --_M_current;
	    return *this;
	  }

	  constexpr _Iterator
	  operator--(int) requires bidirectional_range<_Base>
	  {
	    auto __tmp = *this;
	    --*this;
	    return __tmp;
	  }

	  constexpr _Iterator&
	  operator+=(difference_type __n) requires random_access_range<_Base>
	  {
	    _M_current += __n;
	    return *this;
	  }

	  constexpr _Iterator&
	  operator-=(difference_type __n) requires random_access_range<_Base>
	  {
	    _M_current -= __n;
	    return *this;
	  }

	  constexpr decltype(auto)
	  operator[](difference_type __n) const
	    requires random_access_range<_Base>
	  { return _M_fun._M_call_subscript(__n, _M_current); }

	  friend constexpr bool
	  operator==(const _Iterator& __x, const _Iterator& __y)
	    requires equality_comparable<_Base_iter>
	  { return __x._M_current == __y._M_current; }

	  friend constexpr bool
	  operator<(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return __x._M_current < __y._M_current; }

	  friend constexpr bool
	  operator>(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return __y < __x; }

	  friend constexpr bool
	  operator<=(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return !(__y < __x); }

	  friend constexpr bool
	  operator>=(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return !(__x < __y); }

#ifdef __cpp_lib_three_way_comparison
	  friend constexpr auto
	  operator<=>(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	      && three_way_comparable<_Base_iter>
	  { return __x._M_current <=> __y._M_current; }
#endif

	  friend constexpr _Iterator
	  operator+(_Iterator __i, difference_type __n)
	    requires random_access_range<_Base>
	  { return {__i._M_fun, __i._M_current + __n}; }

	  friend constexpr _Iterator
	  operator+(difference_type __n, _Iterator __i)
	    requires random_access_range<_Base>
	  { return {__i._M_fun, __i._M_current + __n}; }

	  friend constexpr _Iterator
	  operator-(_Iterator __i, difference_type __n)
	    requires random_access_range<_Base>
	  { return {__i._M_fun, __i._M_current - __n}; }

	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3483. transform_view::iterator's difference is overconstrained
	  friend constexpr difference_type
	  operator-(const _Iterator& __x, const _Iterator& __y)
	    requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
	  { return __x._M_current - __y._M_current; }

	  friend constexpr decltype(auto)
	  iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
	  {
	    if constexpr (is_lvalue_reference_v<decltype(*__i)>)
	      return std::move(*__i);
	    else
	      return *__i;
	  }

	  friend _Iterator<!_Const>;
	  template<bool> friend struct _Sentinel;
	};

      template<bool _Const>
	struct _Sentinel
	{
	private:
	  using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
	  using _Base = transform_view::_Base<_Const>;

	  sentinel_t<_Base> _M_end = sentinel_t<_Base>();

	public:
	  _Sentinel() = default;

	  constexpr explicit
	  _Sentinel(sentinel_t<_Base> __end)
	    : _M_end(__end)
	  { }

	  constexpr
	  _Sentinel(_Sentinel<!_Const> __i)
	    requires _Const
	      && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	    : _M_end(std::move(__i._M_end))
	  { }

	  constexpr sentinel_t<_Base>
	  base() const
	  { return _M_end; }

	  template<bool _Const2>
	    requires sentinel_for<sentinel_t<_Base>,
		       iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
	    friend constexpr bool
	    operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	    { return __x._M_current == __y._M_end; }

	  template<bool _Const2,
		   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
	    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	    friend constexpr range_difference_t<_Base2>
	    operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	    { return -(__y._M_end - __x._M_current); }

	  template<bool _Const2,
		   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
	    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	    friend constexpr range_difference_t<_Base2>
	    operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
	    { return __y._M_end - __x._M_current; }

	  friend _Sentinel<!_Const>;
	};

      _Vp _M_base = _Vp();
      [[no_unique_address]] __detail::__box<_Fp> _M_fun;

    public:
      transform_view() requires (default_initializable<_Vp>
				 && default_initializable<_Fp>)
	= default;

      constexpr explicit
      transform_view(_Vp __base, _Fp __fun)
	: _M_base(std::move(__base)), _M_fun(std::move(__fun))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base ; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr _Iterator<false>
      begin()
      { return _Iterator<false>{this, ranges::begin(_M_base)}; }

      constexpr _Iterator<true>
      begin() const
	requires range<const _Vp>
	  && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
      { return _Iterator<true>{this, ranges::begin(_M_base)}; }

      constexpr _Sentinel<false>
      end()
      { return _Sentinel<false>{ranges::end(_M_base)}; }

      constexpr _Iterator<false>
      end() requires common_range<_Vp>
      { return _Iterator<false>{this, ranges::end(_M_base)}; }

      constexpr _Sentinel<true>
      end() const
	requires range<const _Vp>
	  && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
      { return _Sentinel<true>{ranges::end(_M_base)}; }

      constexpr _Iterator<true>
      end() const
	requires common_range<const _Vp>
	  && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
      { return _Iterator<true>{this, ranges::end(_M_base)}; }

      constexpr auto
      size() requires sized_range<_Vp>
      { return ranges::size(_M_base); }

      constexpr auto
      size() const requires sized_range<const _Vp>
      { return ranges::size(_M_base); }
    };

  template<typename _Range, typename _Fp>
    transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Fp>
	concept __can_transform_view
	  = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
    } // namespace __detail

    struct _Transform : __adaptor::_RangeAdaptor<_Transform>
    {
      template<viewable_range _Range, typename _Fp>
	requires __detail::__can_transform_view<_Range, _Fp>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
	{
	  return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
	}

      using _RangeAdaptor<_Transform>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _Transform transform;
  } // namespace views

  template<view _Vp>
    class take_view : public view_interface<take_view<_Vp>>
    {
    private:
      template<bool _Const>
	using _CI = counted_iterator<
	  iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;

      template<bool _Const>
	struct _Sentinel
	{
	private:
	  using _Base = __detail::__maybe_const_t<_Const, _Vp>;
	  sentinel_t<_Base> _M_end = sentinel_t<_Base>();

	public:
	  _Sentinel() = default;

	  constexpr explicit
	  _Sentinel(sentinel_t<_Base> __end)
	    : _M_end(__end)
	  { }

	  constexpr
	  _Sentinel(_Sentinel<!_Const> __s)
	    requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	    : _M_end(std::move(__s._M_end))
	  { }

	  constexpr sentinel_t<_Base>
	  base() const
	  { return _M_end; }

	  friend constexpr bool
	  operator==(const _CI<_Const>& __y, const _Sentinel& __x)
	  { return __y.count() == 0 || __y.base() == __x._M_end; }

	  template<bool _OtherConst = !_Const,
		   typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
	    requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	  friend constexpr bool
	  operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
	  { return __y.count() == 0 || __y.base() == __x._M_end; }

	  friend _Sentinel<!_Const>;
	};

      _Vp _M_base = _Vp();
      range_difference_t<_Vp> _M_count = 0;

    public:
      take_view() requires default_initializable<_Vp> = default;

      constexpr explicit
      take_view(_Vp __base, range_difference_t<_Vp> __count)
	: _M_base(std::move(__base)), _M_count(std::move(__count))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr auto
      begin() requires (!__detail::__simple_view<_Vp>)
      {
	if constexpr (sized_range<_Vp>)
	  {
	    if constexpr (random_access_range<_Vp>)
	      return ranges::begin(_M_base);
	    else
	      {
		auto __sz = size();
		return counted_iterator(ranges::begin(_M_base), __sz);
	      }
	  }
	else
	  return counted_iterator(ranges::begin(_M_base), _M_count);
      }

      constexpr auto
      begin() const requires range<const _Vp>
      {
	if constexpr (sized_range<const _Vp>)
	  {
	    if constexpr (random_access_range<const _Vp>)
	      return ranges::begin(_M_base);
	    else
	      {
		auto __sz = size();
		return counted_iterator(ranges::begin(_M_base), __sz);
	      }
	  }
	else
	  return counted_iterator(ranges::begin(_M_base), _M_count);
      }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp>)
      {
	if constexpr (sized_range<_Vp>)
	  {
	    if constexpr (random_access_range<_Vp>)
	      return ranges::begin(_M_base) + size();
	    else
	      return default_sentinel;
	  }
	else
	  return _Sentinel<false>{ranges::end(_M_base)};
      }

      constexpr auto
      end() const requires range<const _Vp>
      {
	if constexpr (sized_range<const _Vp>)
	  {
	    if constexpr (random_access_range<const _Vp>)
	      return ranges::begin(_M_base) + size();
	    else
	      return default_sentinel;
	  }
	else
	  return _Sentinel<true>{ranges::end(_M_base)};
      }

      constexpr auto
      size() requires sized_range<_Vp>
      {
	auto __n = ranges::size(_M_base);
	return std::min(__n, static_cast<decltype(__n)>(_M_count));
      }

      constexpr auto
      size() const requires sized_range<const _Vp>
      {
	auto __n = ranges::size(_M_base);
	return std::min(__n, static_cast<decltype(__n)>(_M_count));
      }
    };

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 3447. Deduction guides for take_view and drop_view have different
  // constraints
  template<typename _Range>
    take_view(_Range&&, range_difference_t<_Range>)
      -> take_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<take_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range>
	inline constexpr bool __is_empty_view = false;

      template<typename _Tp>
	inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;

      template<typename _Range>
	inline constexpr bool __is_basic_string_view = false;

      template<typename _CharT, typename _Traits>
	inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
	  = true;

      using ranges::__detail::__is_subrange;

      template<typename _Range>
	inline constexpr bool __is_iota_view = false;

      template<typename _Winc, typename _Bound>
	inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;

      template<typename _Range>
	inline constexpr bool __is_repeat_view = false;

      template<typename _Range>
	constexpr auto
	__take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later

      template<typename _Range, typename _Dp>
	concept __can_take_view
	  = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
    } // namespace __detail

    struct _Take : __adaptor::_RangeAdaptor<_Take>
    {
      template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
	requires __detail::__can_take_view<_Range, _Dp>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
	{
	  using _Tp = remove_cvref_t<_Range>;
	  if constexpr (__detail::__is_empty_view<_Tp>)
	    return _Tp();
#ifdef __cpp_lib_optional_range_support // >= C++26
	  else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
	    return __n ? std::forward<_Range>(__r) : _Tp();
#endif
	  else if constexpr (random_access_range<_Tp>
			     && sized_range<_Tp>
			     && (std::__detail::__is_span<_Tp>
				 || __detail::__is_basic_string_view<_Tp>
				 || __detail::__is_subrange<_Tp>
				 || __detail::__is_iota_view<_Tp>))
	    {
	      __n = std::min<_Dp>(ranges::distance(__r), __n);
	      auto __begin = ranges::begin(__r);
	      auto __end = __begin + __n;
	      if constexpr (std::__detail::__is_span<_Tp>)
		return span<typename _Tp::element_type>(__begin, __end);
	      else if constexpr (__detail::__is_basic_string_view<_Tp>)
		return _Tp(__begin, __end);
	      else if constexpr (__detail::__is_subrange<_Tp>)
		return subrange<iterator_t<_Tp>>(__begin, __end);
	      else
		return iota_view(*__begin, *__end);
	    }
	  else if constexpr (__detail::__is_repeat_view<_Tp>)
	    return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
	  else
	    return take_view(std::forward<_Range>(__r), __n);
	}

      using _RangeAdaptor<_Take>::operator();
      static constexpr int _S_arity = 2;
      // The count argument of views::take is not always simple -- it can be
      // e.g. a move-only class that's implicitly convertible to the difference
      // type.  But an integer-like count argument is surely simple.
      template<typename _Tp>
	static constexpr bool _S_has_simple_extra_args
	  = ranges::__detail::__is_integer_like<_Tp>;
    };

    inline constexpr _Take take;
  } // namespace views

  template<view _Vp, typename _Pred>
    requires input_range<_Vp> && is_object_v<_Pred>
      && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
    class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
    {
      template<bool _Const>
	struct _Sentinel
	{
	private:
	  using _Base = __detail::__maybe_const_t<_Const, _Vp>;

	  sentinel_t<_Base> _M_end = sentinel_t<_Base>();
	  const _Pred* _M_pred = nullptr;

	public:
	  _Sentinel() = default;

	  constexpr explicit
	  _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
	    : _M_end(__end), _M_pred(__pred)
	  { }

	  constexpr
	  _Sentinel(_Sentinel<!_Const> __s)
	    requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	    : _M_end(__s._M_end), _M_pred(__s._M_pred)
	  { }

	  constexpr sentinel_t<_Base>
	  base() const { return _M_end; }

	  friend constexpr bool
	  operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
	  { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }

	  template<bool _OtherConst = !_Const,
		   typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
	    requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	  friend constexpr bool
	  operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
	  { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }

	  friend _Sentinel<!_Const>;
	};

      _Vp _M_base = _Vp();
      [[no_unique_address]] __detail::__box<_Pred> _M_pred;

    public:
      take_while_view() requires (default_initializable<_Vp>
				  && default_initializable<_Pred>)
	= default;

      constexpr explicit
      take_while_view(_Vp __base, _Pred __pred)
	: _M_base(std::move(__base)), _M_pred(std::move(__pred))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr const _Pred&
      pred() const
      { return *_M_pred; }

      constexpr auto
      begin() requires (!__detail::__simple_view<_Vp>)
      { return ranges::begin(_M_base); }

      constexpr auto
      begin() const requires range<const _Vp>
	&& indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
      { return ranges::begin(_M_base); }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp>)
      { return _Sentinel<false>(ranges::end(_M_base),
				std::__addressof(*_M_pred)); }

      constexpr auto
      end() const requires range<const _Vp>
	&& indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
      { return _Sentinel<true>(ranges::end(_M_base),
			       std::__addressof(*_M_pred)); }
    };

  template<typename _Range, typename _Pred>
    take_while_view(_Range&&, _Pred)
      -> take_while_view<views::all_t<_Range>, _Pred>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pred>
	concept __can_take_while_view
	  = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
    } // namespace __detail

    struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
    {
      template<viewable_range _Range, typename _Pred>
	requires __detail::__can_take_while_view<_Range, _Pred>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
	{
	  return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
	}

      using _RangeAdaptor<_TakeWhile>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _TakeWhile take_while;
  } // namespace views

  template<view _Vp>
    class drop_view : public view_interface<drop_view<_Vp>>
    {
    private:
      _Vp _M_base = _Vp();
      range_difference_t<_Vp> _M_count = 0;

      // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
      // both random_access_range and sized_range. Otherwise, cache its result.
      static constexpr bool _S_needs_cached_begin
	= !(random_access_range<const _Vp> && sized_range<const _Vp>);
      [[no_unique_address]]
	__detail::__maybe_present_t<_S_needs_cached_begin,
				    __detail::_CachedPosition<_Vp>>
				      _M_cached_begin;

    public:
      drop_view() requires default_initializable<_Vp> = default;

      constexpr explicit
      drop_view(_Vp __base, range_difference_t<_Vp> __count)
	: _M_base(std::move(__base)), _M_count(__count)
      { __glibcxx_assert(__count >= 0); }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      // This overload is disabled for simple views with constant-time begin().
      constexpr auto
      begin()
	requires (!(__detail::__simple_view<_Vp>
		    && random_access_range<const _Vp>
		    && sized_range<const _Vp>))
      {
	if constexpr (_S_needs_cached_begin)
	  if (_M_cached_begin._M_has_value())
	    return _M_cached_begin._M_get(_M_base);

	auto __it = ranges::next(ranges::begin(_M_base),
				 _M_count, ranges::end(_M_base));
	if constexpr (_S_needs_cached_begin)
	  _M_cached_begin._M_set(_M_base, __it);
	return __it;
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3482. drop_view's const begin should additionally require sized_range
      constexpr auto
      begin() const
	requires random_access_range<const _Vp> && sized_range<const _Vp>
      {
	return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
						    _M_count);
      }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp>)
      { return ranges::end(_M_base); }

      constexpr auto
      end() const requires range<const _Vp>
      { return ranges::end(_M_base); }

      constexpr auto
      size() requires sized_range<_Vp>
      {
	const auto __s = ranges::size(_M_base);
	const auto __c = static_cast<decltype(__s)>(_M_count);
	return __s < __c ? 0 : __s - __c;
      }

      constexpr auto
      size() const requires sized_range<const _Vp>
      {
	const auto __s = ranges::size(_M_base);
	const auto __c = static_cast<decltype(__s)>(_M_count);
	return __s < __c ? 0 : __s - __c;
      }
    };

  template<typename _Range>
    drop_view(_Range&&, range_difference_t<_Range>)
      -> drop_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range>
	constexpr auto
	__drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later

      template<typename _Range, typename _Dp>
	concept __can_drop_view
	  = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
    } // namespace __detail

    struct _Drop : __adaptor::_RangeAdaptor<_Drop>
    {
      template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
	requires __detail::__can_drop_view<_Range, _Dp>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
	{
	  using _Tp = remove_cvref_t<_Range>;
	  if constexpr (__detail::__is_empty_view<_Tp>)
	    return _Tp();
#ifdef __cpp_lib_optional_range_support // >= C++26
	  else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
	    return __n ? _Tp() : std::forward<_Range>(__r);
#endif
	  else if constexpr (random_access_range<_Tp>
			     && sized_range<_Tp>
			     && (std::__detail::__is_span<_Tp>
				 || __detail::__is_basic_string_view<_Tp>
				 || __detail::__is_iota_view<_Tp>
				 || __detail::__is_subrange<_Tp>))
	    {
	      __n = std::min<_Dp>(ranges::distance(__r), __n);
	      auto __begin = ranges::begin(__r) + __n;
	      auto __end = ranges::end(__r);
	      if constexpr (std::__detail::__is_span<_Tp>)
		return span<typename _Tp::element_type>(__begin, __end);
	      else if constexpr (__detail::__is_subrange<_Tp>)
		{
		  if constexpr (_Tp::_S_store_size)
		    {
		      using ranges::__detail::__to_unsigned_like;
		      auto __m = ranges::distance(__r) - __n;
		      return _Tp(__begin, __end, __to_unsigned_like(__m));
		    }
		  else
		    return _Tp(__begin, __end);
		}
	      else
		return _Tp(__begin, __end);
	    }
	  else if constexpr (__detail::__is_repeat_view<_Tp>)
	    return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
	  else
	    return drop_view(std::forward<_Range>(__r), __n);
	}

      using _RangeAdaptor<_Drop>::operator();
      static constexpr int _S_arity = 2;
      template<typename _Tp>
	static constexpr bool _S_has_simple_extra_args
	  = _Take::_S_has_simple_extra_args<_Tp>;
    };

    inline constexpr _Drop drop;
  } // namespace views

  template<view _Vp, typename _Pred>
    requires input_range<_Vp> && is_object_v<_Pred>
      && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
    class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
    {
    private:
      _Vp _M_base = _Vp();
      [[no_unique_address]] __detail::__box<_Pred> _M_pred;
      [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;

    public:
      drop_while_view() requires (default_initializable<_Vp>
				  && default_initializable<_Pred>)
	= default;

      constexpr explicit
      drop_while_view(_Vp __base, _Pred __pred)
	: _M_base(std::move(__base)), _M_pred(std::move(__pred))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr const _Pred&
      pred() const
      { return *_M_pred; }

      constexpr auto
      begin()
      {
	if (_M_cached_begin._M_has_value())
	  return _M_cached_begin._M_get(_M_base);

	__glibcxx_assert(_M_pred.has_value());
	auto __it = ranges::find_if_not(ranges::begin(_M_base),
					ranges::end(_M_base),
					std::cref(*_M_pred));
	_M_cached_begin._M_set(_M_base, __it);
	return __it;
      }

      constexpr auto
      end()
      { return ranges::end(_M_base); }
    };

  template<typename _Range, typename _Pred>
    drop_while_view(_Range&&, _Pred)
      -> drop_while_view<views::all_t<_Range>, _Pred>;

  template<typename _Tp, typename _Pred>
    inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pred>
	concept __can_drop_while_view
	  = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
    } // namespace __detail

    struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
    {
      template<viewable_range _Range, typename _Pred>
	requires __detail::__can_drop_while_view<_Range, _Pred>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
	{
	  return drop_while_view(std::forward<_Range>(__r),
				 std::forward<_Pred>(__p));
	}

      using _RangeAdaptor<_DropWhile>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _DropWhile drop_while;
  } // namespace views

  namespace __detail
  {
    template<typename _Tp>
      constexpr _Tp&
      __as_lvalue(_Tp&& __t)
      { return static_cast<_Tp&>(__t); }
  } // namespace __detail

  template<input_range _Vp>
    requires view<_Vp> && input_range<range_reference_t<_Vp>>
    class join_view : public view_interface<join_view<_Vp>>
    {
    private:
      using _InnerRange = range_reference_t<_Vp>;

      template<bool _Const>
	using _Base = __detail::__maybe_const_t<_Const, _Vp>;

      template<bool _Const>
	using _Outer_iter = iterator_t<_Base<_Const>>;

      template<bool _Const>
	using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;

      template<bool _Const>
	static constexpr bool _S_ref_is_glvalue
	  = is_reference_v<range_reference_t<_Base<_Const>>>;

      template<bool _Const>
	struct __iter_cat
	{ };

      template<bool _Const>
	requires _S_ref_is_glvalue<_Const>
	  && forward_range<_Base<_Const>>
	  && forward_range<range_reference_t<_Base<_Const>>>
	struct __iter_cat<_Const>
	{
	private:
	  static constexpr auto
	  _S_iter_cat()
	  {
	    using _Outer_iter = join_view::_Outer_iter<_Const>;
	    using _Inner_iter = join_view::_Inner_iter<_Const>;
	    using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
	    using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
	    if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
			  && derived_from<_InnerCat, bidirectional_iterator_tag>
			  && common_range<range_reference_t<_Base<_Const>>>)
	      return bidirectional_iterator_tag{};
	    else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
			       && derived_from<_InnerCat, forward_iterator_tag>)
	      return forward_iterator_tag{};
	    else
	      return input_iterator_tag{};
	  }
	public:
	  using iterator_category = decltype(_S_iter_cat());
	};

      template<bool _Const>
	struct _Sentinel;

      template<bool _Const>
	struct _Iterator : __iter_cat<_Const>
	{
	private:
	  using _Parent = __detail::__maybe_const_t<_Const, join_view>;
	  using _Base = join_view::_Base<_Const>;

	  friend join_view;

	  static constexpr bool _S_ref_is_glvalue
	    = join_view::_S_ref_is_glvalue<_Const>;

	  constexpr void
	  _M_satisfy()
	  {
	    auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
	      if constexpr (_S_ref_is_glvalue)
		return *__x;
	      else
		return _M_parent->_M_inner._M_emplace_deref(__x);
	    };

	    _Outer_iter& __outer = _M_get_outer();
	    for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
	      {
		auto&& __inner = __update_inner(__outer);
		_M_inner = ranges::begin(__inner);
		if (_M_inner != ranges::end(__inner))
		  return;
	      }

	    if constexpr (_S_ref_is_glvalue)
	      {
		if constexpr (forward_iterator<_Inner_iter>)
		  _M_inner = _Inner_iter();
		else
		  _M_inner.reset();
	      }
	  }

	  static constexpr auto
	  _S_iter_concept()
	  {
	    if constexpr (_S_ref_is_glvalue
			  && bidirectional_range<_Base>
			  && bidirectional_range<range_reference_t<_Base>>
			  && common_range<range_reference_t<_Base>>)
	      return bidirectional_iterator_tag{};
	    else if constexpr (_S_ref_is_glvalue
			       && forward_range<_Base>
			       && forward_range<range_reference_t<_Base>>)
	      return forward_iterator_tag{};
	    else
	      return input_iterator_tag{};
	  }

	  using _Outer_iter = join_view::_Outer_iter<_Const>;
	  using _Inner_iter = join_view::_Inner_iter<_Const>;

	  constexpr _Outer_iter&
	  _M_get_outer()
	  {
	    if constexpr (forward_range<_Base>)
	      return _M_outer;
	    else
	      return *_M_parent->_M_outer;
	  }

	  constexpr const _Outer_iter&
	  _M_get_outer() const
	  {
	    if constexpr (forward_range<_Base>)
	      return _M_outer;
	    else
	      return *_M_parent->_M_outer;
	  }

	  constexpr _Inner_iter&
	  _M_get_inner() noexcept
	  {
	    if constexpr (forward_iterator<_Inner_iter>)
	      return _M_inner;
	    else
	      return *_M_inner;
	  }

	  constexpr const _Inner_iter&
	  _M_get_inner() const noexcept
	  {
	    if constexpr (forward_iterator<_Inner_iter>)
	      return _M_inner;
	    else
	      return *_M_inner;
	  }

	  constexpr
	  _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base>
	    : _M_outer(std::move(__outer)), _M_parent(__parent)
	  { _M_satisfy(); }

	  constexpr explicit
	  _Iterator(_Parent* __parent) requires (!forward_range<_Base>)
	    : _M_parent(__parent)
	  { _M_satisfy(); }

	  [[no_unique_address]]
	    __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer
	      = decltype(_M_outer)();
	  __conditional_t<forward_iterator<_Inner_iter>,
			  _Inner_iter, optional<_Inner_iter>> _M_inner
	    = decltype(_M_inner)();
	  _Parent* _M_parent = nullptr;

	public:
	  using iterator_concept = decltype(_S_iter_concept());
	  // iterator_category defined in __join_view_iter_cat
	  using value_type = range_value_t<range_reference_t<_Base>>;
	  using difference_type
	    = common_type_t<range_difference_t<_Base>,
			    range_difference_t<range_reference_t<_Base>>>;

	  _Iterator() = default;

	  constexpr
	  _Iterator(_Iterator<!_Const> __i)
	    requires _Const
	      && convertible_to<iterator_t<_Vp>, _Outer_iter>
	      && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
	    : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
	      _M_parent(__i._M_parent)
	  { }

	  constexpr decltype(auto)
	  operator*() const
	  { return *_M_get_inner(); }

	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3500. join_view::iterator::operator->() is bogus
	  constexpr _Inner_iter
	  operator->() const
	    requires __detail::__has_arrow<_Inner_iter>
	      && copyable<_Inner_iter>
	  { return _M_get_inner(); }

	  constexpr _Iterator&
	  operator++()
	  {
	    auto&& __inner_range = [this] () -> auto&& {
	      if constexpr (_S_ref_is_glvalue)
		return *_M_get_outer();
	      else
		return *_M_parent->_M_inner;
	    }();
	    if (++_M_get_inner() == ranges::end(__inner_range))
	      {
		++_M_get_outer();
		_M_satisfy();
	      }
	    return *this;
	  }

	  constexpr void
	  operator++(int)
	  { ++*this; }

	  constexpr _Iterator
	  operator++(int)
	    requires _S_ref_is_glvalue && forward_range<_Base>
	      && forward_range<range_reference_t<_Base>>
	  {
	    auto __tmp = *this;
	    ++*this;
	    return __tmp;
	  }

	  constexpr _Iterator&
	  operator--()
	    requires _S_ref_is_glvalue && bidirectional_range<_Base>
	      && bidirectional_range<range_reference_t<_Base>>
	      && common_range<range_reference_t<_Base>>
	  {
	    if (_M_outer == ranges::end(_M_parent->_M_base))
	      _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
	    while (_M_get_inner() == ranges::begin(__detail::__as_lvalue(*_M_outer)))
	      _M_get_inner() = ranges::end(__detail::__as_lvalue(*--_M_outer));
	    --_M_get_inner();
	    return *this;
	  }

	  constexpr _Iterator
	  operator--(int)
	    requires _S_ref_is_glvalue && bidirectional_range<_Base>
	      && bidirectional_range<range_reference_t<_Base>>
	      && common_range<range_reference_t<_Base>>
	  {
	    auto __tmp = *this;
	    --*this;
	    return __tmp;
	  }

	  friend constexpr bool
	  operator==(const _Iterator& __x, const _Iterator& __y)
	    requires _S_ref_is_glvalue
	      && forward_range<_Base>
	      && equality_comparable<_Inner_iter>
	  {
	    return (__x._M_outer == __y._M_outer
		    && __x._M_inner == __y._M_inner);
	  }

	  friend constexpr decltype(auto)
	  iter_move(const _Iterator& __i)
	  noexcept(noexcept(ranges::iter_move(__i._M_get_inner())))
	  { return ranges::iter_move(__i._M_get_inner()); }

	  friend constexpr void
	  iter_swap(const _Iterator& __x, const _Iterator& __y)
	    noexcept(noexcept(ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner())))
	    requires indirectly_swappable<_Inner_iter>
	  { return ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner()); }

	  friend _Iterator<!_Const>;
	  template<bool> friend struct _Sentinel;
	};

      template<bool _Const>
	struct _Sentinel
	{
	private:
	  using _Parent = __detail::__maybe_const_t<_Const, join_view>;
	  using _Base = join_view::_Base<_Const>;

	  sentinel_t<_Base> _M_end = sentinel_t<_Base>();

	public:
	  _Sentinel() = default;

	  constexpr explicit
	  _Sentinel(_Parent* __parent)
	    : _M_end(ranges::end(__parent->_M_base))
	  { }

	  constexpr
	  _Sentinel(_Sentinel<!_Const> __s)
	    requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	    : _M_end(std::move(__s._M_end))
	  { }

	  template<bool _Const2>
	    requires sentinel_for<sentinel_t<_Base>,
		       iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
	    friend constexpr bool
	    operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	    { return __x._M_get_outer() == __y._M_end; }

	  friend _Sentinel<!_Const>;
	};

      _Vp _M_base = _Vp();
      [[no_unique_address]]
	__detail::__maybe_present_t<!forward_range<_Vp>,
	  __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
      [[no_unique_address]]
	__detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;

    public:
      join_view() requires default_initializable<_Vp> = default;

      constexpr explicit
      join_view(_Vp __base)
	: _M_base(std::move(__base))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr auto
      begin()
      {
	if constexpr (forward_range<_Vp>)
	  {
	    constexpr bool __use_const
	      = (__detail::__simple_view<_Vp>
		 && is_reference_v<range_reference_t<_Vp>>);
	    return _Iterator<__use_const>{this, ranges::begin(_M_base)};
	  }
	else
	  {
	    _M_outer = ranges::begin(_M_base);
	    return _Iterator<false>{this};
	  }
      }

      constexpr auto
      begin() const
	requires forward_range<const _Vp>
	  && is_reference_v<range_reference_t<const _Vp>>
	  && input_range<range_reference_t<const _Vp>>
      {
	return _Iterator<true>{this, ranges::begin(_M_base)};
      }

      constexpr auto
      end()
      {
	if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
		      && forward_range<_InnerRange>
		      && common_range<_Vp> && common_range<_InnerRange>)
	  return _Iterator<__detail::__simple_view<_Vp>>{this,
							 ranges::end(_M_base)};
	else
	  return _Sentinel<__detail::__simple_view<_Vp>>{this};
      }

      constexpr auto
      end() const
	requires forward_range<const _Vp>
	  && is_reference_v<range_reference_t<const _Vp>>
	  && input_range<range_reference_t<const _Vp>>
      {
	if constexpr (is_reference_v<range_reference_t<const _Vp>>
		      && forward_range<range_reference_t<const _Vp>>
		      && common_range<const _Vp>
		      && common_range<range_reference_t<const _Vp>>)
	  return _Iterator<true>{this, ranges::end(_M_base)};
	else
	  return _Sentinel<true>{this};
      }
    };

  template<typename _Range>
    explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range>
	concept __can_join_view
	  = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
    } // namespace __detail

    struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
    {
      template<viewable_range _Range>
	requires __detail::__can_join_view<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	{
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3474. Nesting join_views is broken because of CTAD
	  return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _Join join;
  } // namespace views

  namespace __detail
  {
    template<auto>
      struct __require_constant;

    template<typename _Range>
      concept __tiny_range = sized_range<_Range>
	&& requires
	   { typename __require_constant<remove_reference_t<_Range>::size()>; }
	&& (remove_reference_t<_Range>::size() <= 1);

    template<typename _Base>
      struct __lazy_split_view_outer_iter_cat
      { };

    template<forward_range _Base>
      struct __lazy_split_view_outer_iter_cat<_Base>
      { using iterator_category = input_iterator_tag; };

    template<typename _Base>
      struct __lazy_split_view_inner_iter_cat
      { };

    template<forward_range _Base>
      struct __lazy_split_view_inner_iter_cat<_Base>
      {
      private:
	static constexpr auto
	_S_iter_cat()
	{
	  using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
	  if constexpr (derived_from<_Cat, forward_iterator_tag>)
	    return forward_iterator_tag{};
	  else
	    return _Cat{};
	}
      public:
	using iterator_category = decltype(_S_iter_cat());
      };
  }

  template<input_range _Vp, forward_range _Pattern>
    requires view<_Vp> && view<_Pattern>
      && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
			       ranges::equal_to>
      && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
    class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
    {
    private:
      template<bool _Const>
	using _Base = __detail::__maybe_const_t<_Const, _Vp>;

      template<bool _Const>
	struct _InnerIter;

      template<bool _Const>
	struct _OuterIter
	  : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
	{
	private:
	  using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
	  using _Base = lazy_split_view::_Base<_Const>;

	  // [range.lazy.split.outer] p1
	  //  Many of the following specifications refer to the notional member
	  //  current of outer-iterator.  current is equivalent to current_ if
	  //  V models forward_range, and parent_->current_ otherwise.
	  constexpr auto&
	  __current() noexcept
	  {
	    if constexpr (forward_range<_Vp>)
	      return _M_current;
	    else
	      return *_M_parent->_M_current;
	  }

	  constexpr auto&
	  __current() const noexcept
	  {
	    if constexpr (forward_range<_Vp>)
	      return _M_current;
	    else
	      return *_M_parent->_M_current;
	  }

	  _Parent* _M_parent = nullptr;

	  [[no_unique_address]]
	    __detail::__maybe_present_t<forward_range<_Vp>,
					iterator_t<_Base>> _M_current
	      = decltype(_M_current)();
	  bool _M_trailing_empty = false;

	public:
	  using iterator_concept = __conditional_t<forward_range<_Base>,
						   forward_iterator_tag,
						   input_iterator_tag>;
	  // iterator_category defined in __lazy_split_view_outer_iter_cat
	  using difference_type = range_difference_t<_Base>;

	  struct value_type : view_interface<value_type>
	  {
	  private:
	    _OuterIter _M_i = _OuterIter();

	    // _GLIBCXX_RESOLVE_LIB_DEFECTS
	    // 4013. lazy_split_view::outer-iterator::value_type should not
	    // provide default constructor
	    constexpr explicit
	    value_type(_OuterIter __i)
	      : _M_i(std::move(__i))
	    { }

	    friend _OuterIter;

	  public:
	    constexpr _InnerIter<_Const>
	    begin() const
	    { return _InnerIter<_Const>{_M_i}; }

	    constexpr default_sentinel_t
	    end() const noexcept
	    { return default_sentinel; }
	  };

	  _OuterIter() = default;

	  constexpr explicit
	  _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
	    : _M_parent(__parent)
	  { }

	  constexpr
	  _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
	    requires forward_range<_Base>
	    : _M_parent(__parent),
	      _M_current(std::move(__current))
	  { }

	  constexpr
	  _OuterIter(_OuterIter<!_Const> __i)
	    requires _Const
	      && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
	    : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
	      _M_trailing_empty(__i._M_trailing_empty)
	  { }

	  constexpr value_type
	  operator*() const
	  { return value_type{*this}; }

	  constexpr _OuterIter&
	  operator++()
	  {
	    // _GLIBCXX_RESOLVE_LIB_DEFECTS
	    // 3505. lazy_split_view::outer-iterator::operator++ misspecified
	    const auto __end = ranges::end(_M_parent->_M_base);
	    if (__current() == __end)
	      {
		_M_trailing_empty = false;
		return *this;
	      }
	    const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
	    if (__pbegin == __pend)
	      ++__current();
	    else if constexpr (__detail::__tiny_range<_Pattern>)
	      {
		__current() = ranges::find(std::move(__current()), __end,
					   *__pbegin);
		if (__current() != __end)
		  {
		    ++__current();
		    if (__current() == __end)
		      _M_trailing_empty = true;
		  }
	      }
	    else
	      do
		{
		  auto [__b, __p]
		    = ranges::mismatch(__current(), __end, __pbegin, __pend);
		  if (__p == __pend)
		    {
		      __current() = __b;
		      if (__current() == __end)
			_M_trailing_empty = true;
		      break;
		    }
		} while (++__current() != __end);
	    return *this;
	  }

	  constexpr decltype(auto)
	  operator++(int)
	  {
	    if constexpr (forward_range<_Base>)
	      {
		auto __tmp = *this;
		++*this;
		return __tmp;
	      }
	    else
	      ++*this;
	  }

	  friend constexpr bool
	  operator==(const _OuterIter& __x, const _OuterIter& __y)
	    requires forward_range<_Base>
	  {
	    return __x._M_current == __y._M_current
	      && __x._M_trailing_empty == __y._M_trailing_empty;
	  }

	  friend constexpr bool
	  operator==(const _OuterIter& __x, default_sentinel_t)
	  {
	    return __x.__current() == ranges::end(__x._M_parent->_M_base)
	      && !__x._M_trailing_empty;
	  }

	  friend _OuterIter<!_Const>;
	  friend _InnerIter<_Const>;
	};

      template<bool _Const>
	struct _InnerIter
	  : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
	{
	private:
	  using _Base = lazy_split_view::_Base<_Const>;

	  constexpr bool
	  __at_end() const
	  {
	    auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
	    auto __end = ranges::end(_M_i._M_parent->_M_base);
	    if constexpr (__detail::__tiny_range<_Pattern>)
	      {
		const auto& __cur = _M_i_current();
		if (__cur == __end)
		  return true;
		if (__pcur == __pend)
		  return _M_incremented;
		return *__cur == *__pcur;
	      }
	    else
	      {
		auto __cur = _M_i_current();
		if (__cur == __end)
		  return true;
		if (__pcur == __pend)
		  return _M_incremented;
		do
		  {
		    if (*__cur != *__pcur)
		      return false;
		    if (++__pcur == __pend)
		      return true;
		  } while (++__cur != __end);
		return false;
	      }
	  }

	  constexpr auto&
	  _M_i_current() noexcept
	  { return _M_i.__current(); }

	  constexpr auto&
	  _M_i_current() const noexcept
	  { return _M_i.__current(); }

	  _OuterIter<_Const> _M_i = _OuterIter<_Const>();
	  bool _M_incremented = false;

	public:
	  using iterator_concept
	    = typename _OuterIter<_Const>::iterator_concept;
	  // iterator_category defined in __lazy_split_view_inner_iter_cat
	  using value_type = range_value_t<_Base>;
	  using difference_type = range_difference_t<_Base>;

	  _InnerIter() = default;

	  constexpr explicit
	  _InnerIter(_OuterIter<_Const> __i)
	    : _M_i(std::move(__i))
	  { }

	  constexpr const iterator_t<_Base>&
	  base() const& noexcept
	  { return _M_i_current(); }

	  constexpr iterator_t<_Base>
	  base() && requires forward_range<_Vp>
	  { return std::move(_M_i_current()); }

	  constexpr decltype(auto)
	  operator*() const
	  { return *_M_i_current(); }

	  constexpr _InnerIter&
	  operator++()
	  {
	    _M_incremented = true;
	    if constexpr (!forward_range<_Base>)
	      if constexpr (_Pattern::size() == 0)
		return *this;
	    ++_M_i_current();
	    return *this;
	  }

	  constexpr decltype(auto)
	  operator++(int)
	  {
	    if constexpr (forward_range<_Base>)
	      {
		auto __tmp = *this;
		++*this;
		return __tmp;
	      }
	    else
	      ++*this;
	  }

	  friend constexpr bool
	  operator==(const _InnerIter& __x, const _InnerIter& __y)
	    requires forward_range<_Base>
	  { return __x._M_i == __y._M_i; }

	  friend constexpr bool
	  operator==(const _InnerIter& __x, default_sentinel_t)
	  { return __x.__at_end(); }

	  friend constexpr decltype(auto)
	  iter_move(const _InnerIter& __i)
	    noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
	  { return ranges::iter_move(__i._M_i_current()); }

	  friend constexpr void
	  iter_swap(const _InnerIter& __x, const _InnerIter& __y)
	    noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
						__y._M_i_current())))
	    requires indirectly_swappable<iterator_t<_Base>>
	  { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
	};

      _Vp _M_base = _Vp();
      _Pattern _M_pattern = _Pattern();
      [[no_unique_address]]
	__detail::__maybe_present_t<!forward_range<_Vp>,
	  __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;


    public:
      lazy_split_view() requires (default_initializable<_Vp>
				  && default_initializable<_Pattern>)
	= default;

      constexpr explicit
      lazy_split_view(_Vp __base, _Pattern __pattern)
	: _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
      { }

      template<input_range _Range>
	requires constructible_from<_Vp, views::all_t<_Range>>
	  && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
	constexpr explicit
	lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
	  : _M_base(views::all(std::forward<_Range>(__r))),
	    _M_pattern(views::single(std::move(__e)))
	{ }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr auto
      begin()
      {
	if constexpr (forward_range<_Vp>)
	  {
	    constexpr bool __simple
	      = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
	    return _OuterIter<__simple>{this, ranges::begin(_M_base)};
	  }
	else
	  {
	    _M_current = ranges::begin(_M_base);
	    return _OuterIter<false>{this};
	  }
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3599. The const overload of lazy_split_view::begin should be
      // constrained by const Pattern
      constexpr auto
      begin() const requires forward_range<_Vp> && forward_range<const _Vp>
	&& forward_range<const _Pattern>
      {
	return _OuterIter<true>{this, ranges::begin(_M_base)};
      }

      constexpr auto
      end() requires forward_range<_Vp> && common_range<_Vp>
      {
	constexpr bool __simple
	  = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
	return _OuterIter<__simple>{this, ranges::end(_M_base)};
      }

      constexpr auto
      end() const
      {
	if constexpr (forward_range<_Vp>
		      && forward_range<const _Vp>
		      && common_range<const _Vp>
		      && forward_range<const _Pattern>)
	  return _OuterIter<true>{this, ranges::end(_M_base)};
	else
	  return default_sentinel;
      }
    };

  template<typename _Range, typename _Pattern>
    lazy_split_view(_Range&&, _Pattern&&)
      -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;

  template<input_range _Range>
    lazy_split_view(_Range&&, range_value_t<_Range>)
      -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pattern>
	concept __can_lazy_split_view
	  = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
    } // namespace __detail

    struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
    {
      template<viewable_range _Range, typename _Pattern>
	requires __detail::__can_lazy_split_view<_Range, _Pattern>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
	{
	  return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
	}

      using _RangeAdaptor<_LazySplit>::operator();
      static constexpr int _S_arity = 2;
      // The pattern argument of views::lazy_split is not always simple -- it can be
      // a non-view range, the value category of which affects whether the call
      // is well-formed.  But a scalar or a view pattern argument is surely
      // simple.
      template<typename _Pattern>
	static constexpr bool _S_has_simple_extra_args
	  = is_scalar_v<_Pattern> || (view<_Pattern>
				      && copy_constructible<_Pattern>);
    };

    inline constexpr _LazySplit lazy_split;
  } // namespace views

  template<forward_range _Vp, forward_range _Pattern>
    requires view<_Vp> && view<_Pattern>
      && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
			       ranges::equal_to>
  class split_view : public view_interface<split_view<_Vp, _Pattern>>
  {
  private:
    _Vp _M_base = _Vp();
    _Pattern _M_pattern = _Pattern();
    __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;

    struct _Iterator;
    struct _Sentinel;

  public:
    split_view() requires (default_initializable<_Vp>
			   && default_initializable<_Pattern>)
      = default;

    constexpr explicit
    split_view(_Vp __base, _Pattern __pattern)
      : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
    { }

    template<forward_range _Range>
      requires constructible_from<_Vp, views::all_t<_Range>>
	&& constructible_from<_Pattern, single_view<range_value_t<_Range>>>
    constexpr explicit
    split_view(_Range&& __r, range_value_t<_Range> __e)
      : _M_base(views::all(std::forward<_Range>(__r))),
	_M_pattern(views::single(std::move(__e)))
    { }

    constexpr _Vp
    base() const& requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr _Iterator
    begin()
    {
      if (!_M_cached_begin)
	_M_cached_begin = _M_find_next(ranges::begin(_M_base));
      return {this, ranges::begin(_M_base), *_M_cached_begin};
    }

    constexpr auto
    end()
    {
      if constexpr (common_range<_Vp>)
	return _Iterator{this, ranges::end(_M_base), {}};
      else
	return _Sentinel{this};
    }

    constexpr subrange<iterator_t<_Vp>>
    _M_find_next(iterator_t<_Vp> __it)
    {
      auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
      if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
	{
	  ++__b;
	  ++__e;
	}
      return {__b, __e};
    }

  private:
    struct _Iterator
    {
    private:
      split_view* _M_parent = nullptr;
      iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
      subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
      bool _M_trailing_empty = false;

      friend struct _Sentinel;

    public:
      using iterator_concept = forward_iterator_tag;
      using iterator_category = input_iterator_tag;
      using value_type = subrange<iterator_t<_Vp>>;
      using difference_type = range_difference_t<_Vp>;

      _Iterator() = default;

      constexpr
      _Iterator(split_view* __parent,
		iterator_t<_Vp> __current,
		subrange<iterator_t<_Vp>> __next)
	: _M_parent(__parent),
	  _M_cur(std::move(__current)),
	  _M_next(std::move(__next))
      { }

      constexpr iterator_t<_Vp>
      base() const
      { return _M_cur; }

      constexpr value_type
      operator*() const
      { return {_M_cur, _M_next.begin()}; }

      constexpr _Iterator&
      operator++()
      {
	_M_cur = _M_next.begin();
	if (_M_cur != ranges::end(_M_parent->_M_base))
	  {
	    _M_cur = _M_next.end();
	    if (_M_cur == ranges::end(_M_parent->_M_base))
	      {
		_M_trailing_empty = true;
		_M_next = {_M_cur, _M_cur};
	      }
	    else
	      _M_next = _M_parent->_M_find_next(_M_cur);
	  }
	else
	  _M_trailing_empty = false;
	return *this;
      }

      constexpr _Iterator
      operator++(int)
      {
	auto __tmp = *this;
	++*this;
	return __tmp;
      }

      friend constexpr bool
      operator==(const _Iterator& __x, const _Iterator& __y)
      {
	return __x._M_cur == __y._M_cur
	  && __x._M_trailing_empty == __y._M_trailing_empty;
      }
    };

    struct _Sentinel
    {
    private:
      sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();

    public:
      _Sentinel() = default;

      constexpr explicit
      _Sentinel(split_view* __parent)
	: _M_end(ranges::end(__parent->_M_base))
      { }

      friend constexpr bool
      operator==(const _Iterator& __x, const _Sentinel& __y)
      { return __x._M_cur == __y._M_end && !__x._M_trailing_empty; }
    };
  };

  template<typename _Range, typename _Pattern>
    split_view(_Range&&, _Pattern&&)
      -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;

  template<forward_range _Range>
    split_view(_Range&&, range_value_t<_Range>)
      -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pattern>
	concept __can_split_view
	  = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
    } // namespace __detail

    struct _Split : __adaptor::_RangeAdaptor<_Split>
    {
      template<viewable_range _Range, typename _Pattern>
	requires __detail::__can_split_view<_Range, _Pattern>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
	{
	  return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
	}

      using _RangeAdaptor<_Split>::operator();
      static constexpr int _S_arity = 2;
      template<typename _Pattern>
	static constexpr bool _S_has_simple_extra_args
	  = _LazySplit::_S_has_simple_extra_args<_Pattern>;
    };

    inline constexpr _Split split;
  } // namespace views

  namespace views
  {
    struct _Counted
    {
      template<input_or_output_iterator _Iter>
      constexpr auto
      operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
      {
	if constexpr (contiguous_iterator<_Iter>)
	  return span(std::to_address(__i), __n);
	else if constexpr (random_access_iterator<_Iter>)
	  return subrange(__i, __i + __n);
	else
	  return subrange(counted_iterator(std::move(__i), __n),
			  default_sentinel);
      }
    };

    inline constexpr _Counted counted{};
  } // namespace views

  template<view _Vp>
    requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
    class common_view : public view_interface<common_view<_Vp>>
    {
    private:
      _Vp _M_base = _Vp();

    public:
      common_view() requires default_initializable<_Vp> = default;

      constexpr explicit
      common_view(_Vp __r)
	: _M_base(std::move(__r))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 4012. common_view::begin/end are missing the simple-view check
      constexpr auto
      begin() requires (!__detail::__simple_view<_Vp>)
      {
	if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
	  return ranges::begin(_M_base);
	else
	  return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
		  (ranges::begin(_M_base));
      }

      constexpr auto
      begin() const requires range<const _Vp>
      {
	if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
	  return ranges::begin(_M_base);
	else
	  return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
		  (ranges::begin(_M_base));
      }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp>)
      {
	if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
	  return ranges::begin(_M_base) + ranges::size(_M_base);
	else
	  return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
		  (ranges::end(_M_base));
      }

      constexpr auto
      end() const requires range<const _Vp>
      {
	if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
	  return ranges::begin(_M_base) + ranges::size(_M_base);
	else
	  return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
		  (ranges::end(_M_base));
      }

      constexpr auto
      size() requires sized_range<_Vp>
      { return ranges::size(_M_base); }

      constexpr auto
      size() const requires sized_range<const _Vp>
      { return ranges::size(_M_base); }
    };

  template<typename _Range>
    common_view(_Range&&) -> common_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<common_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range>
	concept __already_common = common_range<_Range>
	  && requires { views::all(std::declval<_Range>()); };

      template<typename _Range>
	concept __can_common_view
	  = requires { common_view{std::declval<_Range>()}; };
    } // namespace __detail

    struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
    {
      template<viewable_range _Range>
	requires __detail::__already_common<_Range>
	  || __detail::__can_common_view<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	{
	  if constexpr (__detail::__already_common<_Range>)
	    return views::all(std::forward<_Range>(__r));
	  else
	    return common_view{std::forward<_Range>(__r)};
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _Common common;
  } // namespace views

  template<view _Vp>
    requires bidirectional_range<_Vp>
    class reverse_view : public view_interface<reverse_view<_Vp>>
    {
    private:
      static constexpr bool _S_needs_cached_begin
	= !common_range<_Vp> && !(random_access_range<_Vp>
				  && sized_sentinel_for<sentinel_t<_Vp>,
							iterator_t<_Vp>>);

      _Vp _M_base = _Vp();
      [[no_unique_address]]
	__detail::__maybe_present_t<_S_needs_cached_begin,
				    __detail::_CachedPosition<_Vp>>
				      _M_cached_begin;

    public:
      reverse_view() requires default_initializable<_Vp> = default;

      constexpr explicit
      reverse_view(_Vp __r)
	: _M_base(std::move(__r))
	{ }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr reverse_iterator<iterator_t<_Vp>>
      begin()
      {
	if constexpr (_S_needs_cached_begin)
	  if (_M_cached_begin._M_has_value())
	    return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));

	auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
	if constexpr (_S_needs_cached_begin)
	  _M_cached_begin._M_set(_M_base, __it);
	return std::make_reverse_iterator(std::move(__it));
      }

      constexpr auto
      begin() requires common_range<_Vp>
      { return std::make_reverse_iterator(ranges::end(_M_base)); }

      constexpr auto
      begin() const requires common_range<const _Vp>
      { return std::make_reverse_iterator(ranges::end(_M_base)); }

      constexpr reverse_iterator<iterator_t<_Vp>>
      end()
      { return std::make_reverse_iterator(ranges::begin(_M_base)); }

      constexpr auto
      end() const requires common_range<const _Vp>
      { return std::make_reverse_iterator(ranges::begin(_M_base)); }

      constexpr auto
      size() requires sized_range<_Vp>
      { return ranges::size(_M_base); }

      constexpr auto
      size() const requires sized_range<const _Vp>
      { return ranges::size(_M_base); }
    };

  template<typename _Range>
    reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename>
	inline constexpr bool __is_reversible_subrange = false;

      template<typename _Iter, subrange_kind _Kind>
	inline constexpr bool
	  __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
					    reverse_iterator<_Iter>,
					    _Kind>> = true;

      template<typename>
	inline constexpr bool __is_reverse_view = false;

      template<typename _Vp>
	inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;

      template<typename _Range>
	concept __can_reverse_view
	  = requires { reverse_view{std::declval<_Range>()}; };
    } // namespace __detail

    struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
    {
      template<viewable_range _Range>
	requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
	  || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
	  || __detail::__can_reverse_view<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	{
	  using _Tp = remove_cvref_t<_Range>;
	  if constexpr (__detail::__is_reverse_view<_Tp>)
	    return std::forward<_Range>(__r).base();
#ifdef __cpp_lib_optional_range_support // >= C++26
	  else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
	    return std::forward<_Range>(__r);
#endif
	  else if constexpr (__detail::__is_reversible_subrange<_Tp>)
	    {
	      using _Iter = decltype(ranges::begin(__r).base());
	      if constexpr (sized_range<_Tp>)
		return subrange<_Iter, _Iter, subrange_kind::sized>
			{__r.end().base(), __r.begin().base(), __r.size()};
	      else
		return subrange<_Iter, _Iter, subrange_kind::unsized>
			{__r.end().base(), __r.begin().base()};
	    }
	  else
	    return reverse_view{std::forward<_Range>(__r)};
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _Reverse reverse;
  } // namespace views

  namespace __detail
  {
#if __cpp_lib_tuple_like // >= C++23
    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 3797. elements_view insufficiently constrained
    template<typename _Tp, size_t _Nm>
    concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>
      && requires(_Tp __t)
	 {
	   { std::get<_Nm>(__t) }
	     -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
	 };
#else
    template<typename _Tp, size_t _Nm>
    concept __has_tuple_element = requires(_Tp __t)
      {
	typename tuple_size<_Tp>::type;
	requires _Nm < tuple_size_v<_Tp>;
	typename tuple_element_t<_Nm, _Tp>;
	{ std::get<_Nm>(__t) }
	  -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
      };
#endif

    template<typename _Tp, size_t _Nm>
      concept __returnable_element
	= is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
  }

  template<input_range _Vp, size_t _Nm>
    requires view<_Vp>
      && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
      && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
				       _Nm>
      && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
    class elements_view : public view_interface<elements_view<_Vp, _Nm>>
    {
    public:
      elements_view() requires default_initializable<_Vp> = default;

      constexpr explicit
      elements_view(_Vp __base)
	: _M_base(std::move(__base))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr auto
      begin() requires (!__detail::__simple_view<_Vp>)
      { return _Iterator<false>(ranges::begin(_M_base)); }

      constexpr auto
      begin() const requires range<const _Vp>
      { return _Iterator<true>(ranges::begin(_M_base)); }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
      { return _Sentinel<false>{ranges::end(_M_base)}; }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
      { return _Iterator<false>{ranges::end(_M_base)}; }

      constexpr auto
      end() const requires range<const _Vp>
      { return _Sentinel<true>{ranges::end(_M_base)}; }

      constexpr auto
      end() const requires common_range<const _Vp>
      { return _Iterator<true>{ranges::end(_M_base)}; }

      constexpr auto
      size() requires sized_range<_Vp>
      { return ranges::size(_M_base); }

      constexpr auto
      size() const requires sized_range<const _Vp>
      { return ranges::size(_M_base); }

    private:
      template<bool _Const>
	using _Base = __detail::__maybe_const_t<_Const, _Vp>;

      template<bool _Const>
	struct __iter_cat
	{ };

      template<bool _Const>
	requires forward_range<_Base<_Const>>
	struct __iter_cat<_Const>
	{
	private:
	  static auto _S_iter_cat()
	  {
	    using _Base = elements_view::_Base<_Const>;
	    using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
	    using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
	    if constexpr (!is_lvalue_reference_v<_Res>)
	      return input_iterator_tag{};
	    else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
	      return random_access_iterator_tag{};
	    else
	      return _Cat{};
	  }
	public:
	  using iterator_category = decltype(_S_iter_cat());
	};

      template<bool _Const>
	struct _Sentinel;

      template<bool _Const>
	struct _Iterator : __iter_cat<_Const>
	{
	private:
	  using _Base = elements_view::_Base<_Const>;

	  iterator_t<_Base> _M_current = iterator_t<_Base>();

	  static constexpr decltype(auto)
	  _S_get_element(const iterator_t<_Base>& __i)
	  {
	    if constexpr (is_reference_v<range_reference_t<_Base>>)
	      return std::get<_Nm>(*__i);
	    else
	      {
		using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
		return static_cast<_Et>(std::get<_Nm>(*__i));
	      }
	  }

	  static auto
	  _S_iter_concept()
	  {
	    if constexpr (random_access_range<_Base>)
	      return random_access_iterator_tag{};
	    else if constexpr (bidirectional_range<_Base>)
	      return bidirectional_iterator_tag{};
	    else if constexpr (forward_range<_Base>)
	      return forward_iterator_tag{};
	    else
	      return input_iterator_tag{};
	  }

	  friend _Iterator<!_Const>;

	public:
	  using iterator_concept = decltype(_S_iter_concept());
	  // iterator_category defined in elements_view::__iter_cat
	  using value_type
	    = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
	  using difference_type = range_difference_t<_Base>;

	  _Iterator() requires default_initializable<iterator_t<_Base>> = default;

	  constexpr explicit
	  _Iterator(iterator_t<_Base> __current)
	    : _M_current(std::move(__current))
	  { }

	  constexpr
	  _Iterator(_Iterator<!_Const> __i)
	    requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
	    : _M_current(std::move(__i._M_current))
	  { }

	  constexpr const iterator_t<_Base>&
	  base() const& noexcept
	  { return _M_current; }

	  constexpr iterator_t<_Base>
	  base() &&
	  { return std::move(_M_current); }

	  constexpr decltype(auto)
	  operator*() const
	  { return _S_get_element(_M_current); }

	  constexpr _Iterator&
	  operator++()
	  {
	    ++_M_current;
	    return *this;
	  }

	  constexpr void
	  operator++(int)
	  { ++_M_current; }

	  constexpr _Iterator
	  operator++(int) requires forward_range<_Base>
	  {
	    auto __tmp = *this;
	    ++_M_current;
	    return __tmp;
	  }

	  constexpr _Iterator&
	  operator--() requires bidirectional_range<_Base>
	  {
	    --_M_current;
	    return *this;
	  }

	  constexpr _Iterator
	  operator--(int) requires bidirectional_range<_Base>
	  {
	    auto __tmp = *this;
	    --_M_current;
	    return __tmp;
	  }

	  constexpr _Iterator&
	  operator+=(difference_type __n)
	    requires random_access_range<_Base>
	  {
	    _M_current += __n;
	    return *this;
	  }

	  constexpr _Iterator&
	  operator-=(difference_type __n)
	    requires random_access_range<_Base>
	  {
	    _M_current -= __n;
	    return *this;
	  }

	  constexpr decltype(auto)
	  operator[](difference_type __n) const
	    requires random_access_range<_Base>
	  { return _S_get_element(_M_current + __n); }

	  friend constexpr bool
	  operator==(const _Iterator& __x, const _Iterator& __y)
	    requires equality_comparable<iterator_t<_Base>>
	  { return __x._M_current == __y._M_current; }

	  friend constexpr bool
	  operator<(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return __x._M_current < __y._M_current; }

	  friend constexpr bool
	  operator>(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return __y._M_current < __x._M_current; }

	  friend constexpr bool
	  operator<=(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return !(__y._M_current > __x._M_current); }

	  friend constexpr bool
	  operator>=(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return !(__x._M_current > __y._M_current); }

#ifdef __cpp_lib_three_way_comparison
	  friend constexpr auto
	  operator<=>(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	      && three_way_comparable<iterator_t<_Base>>
	  { return __x._M_current <=> __y._M_current; }
#endif

	  friend constexpr _Iterator
	  operator+(const _Iterator& __x, difference_type __y)
	    requires random_access_range<_Base>
	  { return _Iterator{__x} += __y; }

	  friend constexpr _Iterator
	  operator+(difference_type __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return __y + __x; }

	  friend constexpr _Iterator
	  operator-(const _Iterator& __x, difference_type __y)
	    requires random_access_range<_Base>
	  { return _Iterator{__x} -= __y; }

	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3483. transform_view::iterator's difference is overconstrained
	  friend constexpr difference_type
	  operator-(const _Iterator& __x, const _Iterator& __y)
	    requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
	  { return __x._M_current - __y._M_current; }

	  template <bool> friend struct _Sentinel;
	};

      template<bool _Const>
	struct _Sentinel
	{
	private:
	  using _Base = elements_view::_Base<_Const>;
	  sentinel_t<_Base> _M_end = sentinel_t<_Base>();

	public:
	  _Sentinel() = default;

	  constexpr explicit
	  _Sentinel(sentinel_t<_Base> __end)
	    : _M_end(std::move(__end))
	  { }

	  constexpr
	  _Sentinel(_Sentinel<!_Const> __other)
	    requires _Const
	      && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	    : _M_end(std::move(__other._M_end))
	  { }

	  constexpr sentinel_t<_Base>
	  base() const
	  { return _M_end; }

	  template<bool _Const2>
	    requires sentinel_for<sentinel_t<_Base>,
		       iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
	    friend constexpr bool
	    operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	    { return __x._M_current == __y._M_end; }

	  template<bool _Const2,
		   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
	    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	    friend constexpr range_difference_t<_Base2>
	    operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	    { return -(__y._M_end - __x._M_current); }

	  template<bool _Const2,
		   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
	    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	    friend constexpr range_difference_t<_Base2>
	    operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
	    { return __x._M_end - __y._M_current; }

	  friend _Sentinel<!_Const>;
	};

      _Vp _M_base = _Vp();
    };

  template<typename _Tp, size_t _Nm>
    inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
      = enable_borrowed_range<_Tp>;

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 3563. keys_view example is broken
  template<typename _Range>
    using keys_view = elements_view<_Range, 0>;

  template<typename _Range>
    using values_view = elements_view<_Range, 1>;

  namespace views
  {
    namespace __detail
    {
      template<size_t _Nm, typename _Range>
	concept __can_elements_view
	  = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
    } // namespace __detail

    template<size_t _Nm>
      struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
      {
	template<viewable_range _Range>
	  requires __detail::__can_elements_view<_Nm, _Range>
	  constexpr auto
	  operator() [[nodiscard]] (_Range&& __r) const
	  {
	    return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
	  }

	static constexpr bool _S_has_simple_call_op = true;
      };

    template<size_t _Nm>
      inline constexpr _Elements<_Nm> elements;
    inline constexpr auto keys = elements<0>;
    inline constexpr auto values = elements<1>;
  } // namespace views

#ifdef __cpp_lib_ranges_zip // C++ >= 23
  namespace __detail
  {
    template<typename... _Rs>
      concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
	|| (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
	|| ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));

    template<typename _Fp, typename _Tuple>
      constexpr auto
      __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
      {
	return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
	  return tuple<invoke_result_t<_Fp&, _Ts>...>
	    (std::__invoke(__f, std::forward<_Ts>(__elts))...);
	}, std::forward<_Tuple>(__tuple));
      }

    template<typename _Fp, typename _Tuple>
      constexpr void
      __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
      {
	std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
	  (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
	}, std::forward<_Tuple>(__tuple));
      }
  } // namespace __detail

  template<input_range... _Vs>
    requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
  class zip_view : public view_interface<zip_view<_Vs...>>
  {
    tuple<_Vs...> _M_views;

    template<bool> class _Iterator;
    template<bool> class _Sentinel;

  public:
    zip_view() = default;

    constexpr explicit
    zip_view(_Vs... __views)
      : _M_views(std::move(__views)...)
    { }

    constexpr auto
    begin() requires (!(__detail::__simple_view<_Vs> && ...))
    { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }

    constexpr auto
    begin() const requires (range<const _Vs> && ...)
    { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }

    constexpr auto
    end() requires (!(__detail::__simple_view<_Vs> && ...))
    {
      if constexpr (!__detail::__zip_is_common<_Vs...>)
        return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
      else if constexpr ((random_access_range<_Vs> && ...))
        return begin() + iter_difference_t<_Iterator<false>>(size());
      else
        return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
    }

    constexpr auto
    end() const requires (range<const _Vs> && ...)
    {
      if constexpr (!__detail::__zip_is_common<const _Vs...>)
        return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
      else if constexpr ((random_access_range<const _Vs> && ...))
        return begin() + iter_difference_t<_Iterator<true>>(size());
      else
        return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
    }

    constexpr auto
    size() requires (sized_range<_Vs> && ...)
    {
      return std::apply([](auto... __sizes) {
	using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
	return ranges::min({_CT(__sizes)...});
      }, __detail::__tuple_transform(ranges::size, _M_views));
    }

    constexpr auto
    size() const requires (sized_range<const _Vs> && ...)
    {
      return std::apply([](auto... __sizes) {
	using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
	return ranges::min({_CT(__sizes)...});
      }, __detail::__tuple_transform(ranges::size, _M_views));
    }
  };

  template<typename... _Rs>
    zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;

  template<typename... _Views>
    inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
      = (enable_borrowed_range<_Views> && ...);

  namespace __detail
  {
    template<bool _Const, typename... _Vs>
      concept __all_random_access
	= (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);

    template<bool _Const, typename... _Vs>
      concept __all_bidirectional
	= (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);

    template<bool _Const, typename... _Vs>
      concept __all_forward
	= (forward_range<__maybe_const_t<_Const, _Vs>> && ...);

    template<bool _Const, typename... _Views>
      struct __zip_view_iter_cat
      { };

    template<bool _Const, typename... _Views>
      requires __all_forward<_Const, _Views...>
      struct __zip_view_iter_cat<_Const, _Views...>
      { using iterator_category = input_iterator_tag; };
  } // namespace __detail

  template<input_range... _Vs>
    requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
  template<bool _Const>
  class zip_view<_Vs...>::_Iterator
    : public __detail::__zip_view_iter_cat<_Const, _Vs...>
  {
#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
  public:
#endif
    tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;

    constexpr explicit
    _Iterator(decltype(_M_current) __current)
      : _M_current(std::move(__current))
    { }

    static auto
    _S_iter_concept()
    {
      if constexpr (__detail::__all_random_access<_Const, _Vs...>)
	return random_access_iterator_tag{};
      else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
	return bidirectional_iterator_tag{};
      else if constexpr (__detail::__all_forward<_Const, _Vs...>)
	return forward_iterator_tag{};
      else
	return input_iterator_tag{};
    }

#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
    template<move_constructible _Fp, input_range... _Ws>
      requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
	&& regular_invocable<_Fp&, range_reference_t<_Ws>...>
	&& std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
      friend class zip_transform_view;
#endif

  public:
    // iterator_category defined in __zip_view_iter_cat
    using iterator_concept = decltype(_S_iter_concept());
    using value_type
      = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
    using difference_type
      = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;

    _Iterator() = default;

    constexpr
    _Iterator(_Iterator<!_Const> __i)
      requires _Const
	&& (convertible_to<iterator_t<_Vs>,
			   iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
      : _M_current(std::move(__i._M_current))
    { }

    constexpr auto
    operator*() const
    {
      auto __f = [](auto& __i) -> decltype(auto) {
	return *__i;
      };
      return __detail::__tuple_transform(__f, _M_current);
    }

    constexpr _Iterator&
    operator++()
    {
      __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    constexpr _Iterator
    operator++(int)
      requires __detail::__all_forward<_Const, _Vs...>
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--()
      requires __detail::__all_bidirectional<_Const, _Vs...>
    {
      __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
      return *this;
    }

    constexpr _Iterator
    operator--(int)
      requires __detail::__all_bidirectional<_Const, _Vs...>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __x)
      requires __detail::__all_random_access<_Const, _Vs...>
    {
      auto __f = [&]<typename _It>(_It& __i) {
	__i += iter_difference_t<_It>(__x);
      };
      __detail::__tuple_for_each(__f, _M_current);
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __x)
      requires __detail::__all_random_access<_Const, _Vs...>
    {
      auto __f = [&]<typename _It>(_It& __i) {
	__i -= iter_difference_t<_It>(__x);
      };
      __detail::__tuple_for_each(__f, _M_current);
      return *this;
    }

    constexpr auto
    operator[](difference_type __n) const
      requires __detail::__all_random_access<_Const, _Vs...>
    {
      auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
	return __i[iter_difference_t<_It>(__n)];
      };
      return __detail::__tuple_transform(__f, _M_current);
    }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
      requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
    {
      if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
	return __x._M_current == __y._M_current;
      else
	return [&]<size_t... _Is>(index_sequence<_Is...>) {
	  return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
	}(make_index_sequence<sizeof...(_Vs)>{});
    }

    friend constexpr auto
    operator<=>(const _Iterator& __x, const _Iterator& __y)
      requires __detail::__all_random_access<_Const, _Vs...>
    { return __x._M_current <=> __y._M_current; }

    friend constexpr _Iterator
    operator+(const _Iterator& __i, difference_type __n)
      requires __detail::__all_random_access<_Const, _Vs...>
    {
      auto __r = __i;
      __r += __n;
      return __r;
    }

    friend constexpr _Iterator
    operator+(difference_type __n, const _Iterator& __i)
      requires __detail::__all_random_access<_Const, _Vs...>
    {
      auto __r = __i;
      __r += __n;
      return __r;
    }

    friend constexpr _Iterator
    operator-(const _Iterator& __i, difference_type __n)
      requires __detail::__all_random_access<_Const, _Vs...>
    {
      auto __r = __i;
      __r -= __n;
      return __r;
    }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y)
      requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
				   iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
    {
      return [&]<size_t... _Is>(index_sequence<_Is...>) {
	return ranges::min({difference_type(std::get<_Is>(__x._M_current)
					    - std::get<_Is>(__y._M_current))...},
			   ranges::less{},
			   [](difference_type __i) {
			     return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
			   });
      }(make_index_sequence<sizeof...(_Vs)>{});
    }

    friend constexpr auto
    iter_move(const _Iterator& __i)
    { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }

    friend constexpr void
    iter_swap(const _Iterator& __l, const _Iterator& __r)
      requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
    {
      [&]<size_t... _Is>(index_sequence<_Is...>) {
	(ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
      }(make_index_sequence<sizeof...(_Vs)>{});
    }

    friend class zip_view;
  };

  template<input_range... _Vs>
    requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
  template<bool _Const>
  class zip_view<_Vs...>::_Sentinel
  {
    tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;

    constexpr explicit
    _Sentinel(decltype(_M_end) __end)
      : _M_end(__end)
    { }

    friend class zip_view;

  public:
    _Sentinel() = default;

    constexpr
    _Sentinel(_Sentinel<!_Const> __i)
      requires _Const
	&& (convertible_to<sentinel_t<_Vs>,
			   sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
      : _M_end(std::move(__i._M_end))
    { }

    template<bool _OtherConst>
      requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
			     iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
    friend constexpr bool
    operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    {
      return [&]<size_t... _Is>(index_sequence<_Is...>) {
	return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
      }(make_index_sequence<sizeof...(_Vs)>{});
    }

    template<bool _OtherConst>
      requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
				   iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
    friend constexpr auto
    operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    {
      using _Ret
	= common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
      return [&]<size_t... _Is>(index_sequence<_Is...>) {
	return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
			   ranges::less{},
			   [](_Ret __i) {
			     return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
			   });
      }(make_index_sequence<sizeof...(_Vs)>{});
    }

    template<bool _OtherConst>
      requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
				   iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
    friend constexpr auto
    operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
    { return -(__x - __y); }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename... _Ts>
	concept __can_zip_view
	  = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
    }

    struct _Zip
    {
      template<typename... _Ts>
	requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
	constexpr auto
	operator() [[nodiscard]] (_Ts&&... __ts) const
	{
	  if constexpr (sizeof...(_Ts) == 0)
	    return views::empty<tuple<>>;
	  else
	    return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
	}
    };

    inline constexpr _Zip zip;
  }

  namespace __detail
  {
    template<typename _Range, bool _Const>
      using __range_iter_cat
	= typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
  }

  template<move_constructible _Fp, input_range... _Vs>
    requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
      && regular_invocable<_Fp&, range_reference_t<_Vs>...>
      && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
  class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
  {
    [[no_unique_address]] __detail::__box<_Fp> _M_fun;
    zip_view<_Vs...> _M_zip;

    using _InnerView = zip_view<_Vs...>;

    template<bool _Const>
      using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;

    template<bool _Const>
      using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;

    template<bool _Const>
      using _Base = __detail::__maybe_const_t<_Const, _InnerView>;

    template<bool _Const>
      struct __iter_cat
      { };

    template<bool _Const>
      requires forward_range<_Base<_Const>>
      struct __iter_cat<_Const>
      {
      private:
	static auto
	_S_iter_cat()
	{
	  using __detail::__maybe_const_t;
	  using __detail::__range_iter_cat;
	  using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
				       range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3798. Rvalue reference and iterator_category
	  if constexpr (!is_reference_v<_Res>)
	    return input_iterator_tag{};
	  else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
					   random_access_iterator_tag> && ...))
	    return random_access_iterator_tag{};
	  else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
					   bidirectional_iterator_tag> && ...))
	    return bidirectional_iterator_tag{};
	  else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
					   forward_iterator_tag> && ...))
	    return forward_iterator_tag{};
	  else
	    return input_iterator_tag{};
	}
      public:
	using iterator_category = decltype(_S_iter_cat());
      };

    template<bool> class _Iterator;
    template<bool> class _Sentinel;

  public:
    zip_transform_view() = default;

    constexpr explicit
    zip_transform_view(_Fp __fun, _Vs... __views)
      : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
    { }

    constexpr auto
    begin()
    { return _Iterator<false>(*this, _M_zip.begin()); }

    constexpr auto
    begin() const
      requires range<const _InnerView>
	&& regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
    { return _Iterator<true>(*this, _M_zip.begin()); }

    constexpr auto
    end()
    {
      if constexpr (common_range<_InnerView>)
	return _Iterator<false>(*this, _M_zip.end());
      else
	return _Sentinel<false>(_M_zip.end());
    }

    constexpr auto
    end() const
      requires range<const _InnerView>
	&& regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
    {
      if constexpr (common_range<const _InnerView>)
	return _Iterator<true>(*this, _M_zip.end());
      else
	return _Sentinel<true>(_M_zip.end());
    }

    constexpr auto
    size() requires sized_range<_InnerView>
    { return _M_zip.size(); }

    constexpr auto
    size() const requires sized_range<const _InnerView>
    { return _M_zip.size(); }
  };

  template<class _Fp, class... _Rs>
    zip_transform_view(_Fp, _Rs&&...)
      -> zip_transform_view<_Fp, views::all_t<_Rs>...>;

  template<move_constructible _Fp, input_range... _Vs>
    requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
      && regular_invocable<_Fp&, range_reference_t<_Vs>...>
      && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
  template<bool _Const>
  class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
  {
    using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
    using _Fun_handle = __detail::__func_handle_t<
			  __detail::__maybe_const_t<_Const, _Fp>,
			  iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...>;

    [[no_unique_address]] _Fun_handle _M_fun;
    __ziperator<_Const> _M_inner;

    constexpr
    _Iterator(_Fun_handle __fun, __ziperator<_Const> __inner)
      : _M_fun(__fun), _M_inner(std::move(__inner))
    { }

    constexpr
    _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
      : _M_fun(*__parent._M_fun), _M_inner(std::move(__inner))
    { }

    friend class zip_transform_view;

  public:
    // iterator_category defined in zip_transform_view::__iter_cat
    using iterator_concept = typename __ziperator<_Const>::iterator_concept;
    using value_type
      = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
				       range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
    using difference_type = range_difference_t<_Base<_Const>>;

    _Iterator() = default;

    constexpr
    _Iterator(_Iterator<!_Const> __i)
      requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
      : _M_fun(__i._M_fun), _M_inner(std::move(__i._M_inner))
    { }

    constexpr decltype(auto)
    operator*() const
    {
      return std::apply([&](const auto&... __iters) -> decltype(auto) {
	return _M_fun._M_call_deref(__iters...);
      }, _M_inner._M_current);
    }

    constexpr _Iterator&
    operator++()
    {
      ++_M_inner;
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    constexpr _Iterator
    operator++(int) requires forward_range<_Base<_Const>>
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--() requires bidirectional_range<_Base<_Const>>
    {
      --_M_inner;
      return *this;
    }

    constexpr _Iterator
    operator--(int) requires bidirectional_range<_Base<_Const>>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
    {
      _M_inner += __x;
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
    {
      _M_inner -= __x;
      return *this;
    }

    constexpr decltype(auto)
    operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
    {
      return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
	return _M_fun._M_call_subscript(__n, __iters...);
      }, _M_inner._M_current);
    }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
      requires equality_comparable<__ziperator<_Const>>
    { return __x._M_inner == __y._M_inner; }

    friend constexpr auto
    operator<=>(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base<_Const>>
    { return __x._M_inner <=> __y._M_inner; }

    friend constexpr _Iterator
    operator+(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base<_Const>>
    { return _Iterator(__i._M_fun, __i._M_inner + __n); }

    friend constexpr _Iterator
    operator+(difference_type __n, const _Iterator& __i)
      requires random_access_range<_Base<_Const>>
    { return _Iterator(__i._M_fun, __i._M_inner + __n); }

    friend constexpr _Iterator
    operator-(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base<_Const>>
    { return _Iterator(__i._M_fun, __i._M_inner - __n); }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y)
      requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
    { return __x._M_inner - __y._M_inner; }
  };

  template<move_constructible _Fp, input_range... _Vs>
    requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
      && regular_invocable<_Fp&, range_reference_t<_Vs>...>
      && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
  template<bool _Const>
  class zip_transform_view<_Fp, _Vs...>::_Sentinel
  {
    __zentinel<_Const> _M_inner;

    constexpr explicit
    _Sentinel(__zentinel<_Const> __inner)
      : _M_inner(__inner)
    { }

    friend class zip_transform_view;

  public:
    _Sentinel() = default;

    constexpr
    _Sentinel(_Sentinel<!_Const> __i)
      requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
      : _M_inner(std::move(__i._M_inner))
    { }

    template<bool _OtherConst>
      requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
    friend constexpr bool
    operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    { return __x._M_inner == __y._M_inner; }

    template<bool _OtherConst>
      requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
    friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
    operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    { return __x._M_inner - __y._M_inner; }

    template<bool _OtherConst>
      requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
    friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
    operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
    { return __x._M_inner - __y._M_inner; }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename _Fp, typename... _Ts>
	concept __can_zip_transform_view
	  = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
    }

    struct _ZipTransform
    {
      template<typename _Fp>
	requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
	  && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
	constexpr auto
	operator() [[nodiscard]] (_Fp&&) const
	{
	  return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
	}

      template<typename _Fp, typename... _Ts>
	requires (sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
	constexpr auto
	operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
	{
          return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
	}
    };

    inline constexpr _ZipTransform zip_transform;
  }

  template<forward_range _Vp, size_t _Nm>
    requires view<_Vp> && (_Nm > 0)
  class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
  {
    _Vp _M_base = _Vp();

    template<bool> class _Iterator;
    template<bool> class _Sentinel;

    struct __as_sentinel
    { };

  public:
    adjacent_view() requires default_initializable<_Vp> = default;

    constexpr explicit
    adjacent_view(_Vp __base)
      : _M_base(std::move(__base))
    { }

    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
    constexpr _Vp
    base() const & requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr auto
    begin() requires (!__detail::__simple_view<_Vp>)
    { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }

    constexpr auto
    begin() const requires range<const _Vp>
    { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }

    constexpr auto
    end() requires (!__detail::__simple_view<_Vp>)
    {
      if constexpr (common_range<_Vp>)
	return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
      else
	return _Sentinel<false>(ranges::end(_M_base));
    }

    constexpr auto
    end() const requires range<const _Vp>
    {
      if constexpr (common_range<const _Vp>)
	return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
      else
	return _Sentinel<true>(ranges::end(_M_base));
    }

    constexpr auto
    size() requires sized_range<_Vp>
    {
      using _ST = decltype(ranges::size(_M_base));
      using _CT = common_type_t<_ST, size_t>;
      auto __sz = static_cast<_CT>(ranges::size(_M_base));
      __sz -= std::min<_CT>(__sz, _Nm - 1);
      return static_cast<_ST>(__sz);
    }

    constexpr auto
    size() const requires sized_range<const _Vp>
    {
      using _ST = decltype(ranges::size(_M_base));
      using _CT = common_type_t<_ST, size_t>;
      auto __sz = static_cast<_CT>(ranges::size(_M_base));
      __sz -= std::min<_CT>(__sz, _Nm - 1);
      return static_cast<_ST>(__sz);
    }
  };

  template<typename _Vp, size_t _Nm>
    inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
      = enable_borrowed_range<_Vp>;

  namespace __detail
  {
    // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
    template<typename _Tp, size_t _Nm>
      using __repeated_tuple = typename __make_tuple<array<_Tp, _Nm>>::__type;

    // For a functor F that is callable with N arguments, the expression
    // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
    template<typename _Fp, size_t _Nm>
      struct __unarize
      {
	template<typename... _Ts>
	  static invoke_result_t<_Fp, _Ts...>
	  __tuple_apply(const tuple<_Ts...>&); // not defined

	template<typename _Tp>
	  decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
	  operator()(_Tp&&); // not defined
      };
  }

  template<forward_range _Vp, size_t _Nm>
    requires view<_Vp> && (_Nm > 0)
  template<bool _Const>
  class adjacent_view<_Vp, _Nm>::_Iterator
  {
#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
  public:
#endif
    using _Base = __detail::__maybe_const_t<_Const, _Vp>;
    array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();

    constexpr
    _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
    {
      for (auto& __i : _M_current)
	{
	  __i = __first;
	  ranges::advance(__first, 1, __last);
	}
    }

    constexpr
    _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
    {
      if constexpr (!bidirectional_range<_Base>)
	for (auto& __it : _M_current)
	  __it = __last;
      else
	for (size_t __i = 0; __i < _Nm; ++__i)
	  {
	    _M_current[_Nm - 1 - __i] = __last;
	    ranges::advance(__last, -1, __first);
	  }
    }

    static auto
    _S_iter_concept()
    {
      if constexpr (random_access_range<_Base>)
	return random_access_iterator_tag{};
      else if constexpr (bidirectional_range<_Base>)
	return bidirectional_iterator_tag{};
      else
	return forward_iterator_tag{};
    }

    friend class adjacent_view;

#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
    template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
      requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
        && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
        && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
							 range_reference_t<_Wp>>>
      friend class adjacent_transform_view;
#endif

  public:
    using iterator_category = input_iterator_tag;
    using iterator_concept = decltype(_S_iter_concept());
    using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
    using difference_type = range_difference_t<_Base>;

    _Iterator() = default;

    constexpr
    _Iterator(_Iterator<!_Const> __i)
      requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
    {
      for (size_t __j = 0; __j < _Nm; ++__j)
	_M_current[__j] = std::move(__i._M_current[__j]);
    }

    constexpr auto
    operator*() const
    {
      auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
      return __detail::__tuple_transform(__f, _M_current);
    }

    constexpr _Iterator&
    operator++()
    {
      for (auto& __i : _M_current)
	++__i;
      return *this;
    }

    constexpr _Iterator
    operator++(int)
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--() requires bidirectional_range<_Base>
    {
      for (auto& __i : _M_current)
	--__i;
      return *this;
    }

    constexpr _Iterator
    operator--(int) requires bidirectional_range<_Base>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __x)
      requires random_access_range<_Base>
    {
      for (auto& __i : _M_current)
	__i += __x;
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __x)
      requires random_access_range<_Base>
    {
      for (auto& __i : _M_current)
	__i -= __x;
      return *this;
    }

    constexpr auto
    operator[](difference_type __n) const
      requires random_access_range<_Base>
    {
      auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
      return __detail::__tuple_transform(__f, _M_current);
    }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
    { return __x._M_current.back() == __y._M_current.back(); }

    friend constexpr bool
    operator<(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __x._M_current.back() < __y._M_current.back(); }

    friend constexpr bool
    operator>(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __y < __x; }

    friend constexpr bool
    operator<=(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return !(__y < __x); }

    friend constexpr bool
    operator>=(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return !(__x < __y); }

    friend constexpr auto
    operator<=>(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
	&& three_way_comparable<iterator_t<_Base>>
    { return __x._M_current.back() <=> __y._M_current.back(); }

    friend constexpr _Iterator
    operator+(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base>
    {
      auto __r = __i;
      __r += __n;
      return __r;
    }

    friend constexpr _Iterator
    operator+(difference_type __n, const _Iterator& __i)
      requires random_access_range<_Base>
    {
      auto __r = __i;
      __r += __n;
      return __r;
    }

    friend constexpr _Iterator
    operator-(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base>
    {
      auto __r = __i;
      __r -= __n;
      return __r;
    }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y)
      requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
    { return __x._M_current.back() - __y._M_current.back(); }

    friend constexpr auto
    iter_move(const _Iterator& __i)
    { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }

    friend constexpr void
    iter_swap(const _Iterator& __l, const _Iterator& __r)
      requires indirectly_swappable<iterator_t<_Base>>
    {
      for (size_t __i = 0; __i < _Nm; __i++)
	ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
    }
  };

  template<forward_range _Vp, size_t _Nm>
    requires view<_Vp> && (_Nm > 0)
  template<bool _Const>
  class adjacent_view<_Vp, _Nm>::_Sentinel
  {
    using _Base = __detail::__maybe_const_t<_Const, _Vp>;

    sentinel_t<_Base> _M_end = sentinel_t<_Base>();

    constexpr explicit
    _Sentinel(sentinel_t<_Base> __end)
      : _M_end(__end)
    { }

    friend class adjacent_view;

  public:
    _Sentinel() = default;

    constexpr
    _Sentinel(_Sentinel<!_Const> __i)
      requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
      : _M_end(std::move(__i._M_end))
    { }

    template<bool _OtherConst>
      requires sentinel_for<sentinel_t<_Base>,
			    iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
    friend constexpr bool
    operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    { return __x._M_current.back() == __y._M_end; }

    template<bool _OtherConst>
      requires sized_sentinel_for<sentinel_t<_Base>,
				  iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
    friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
    operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    { return __x._M_current.back() - __y._M_end; }

    template<bool _OtherConst>
      requires sized_sentinel_for<sentinel_t<_Base>,
				  iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
    friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
    operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
    { return __y._M_end - __x._M_current.back(); }
  };

  namespace views
  {
    namespace __detail
    {
      template<size_t _Nm, typename _Range>
	concept __can_adjacent_view
	  = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
    }

    template<size_t _Nm>
      struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 4098. views::adjacent<0> should reject non-forward ranges
	template<viewable_range _Range>
	  requires ((_Nm == 0) && forward_range<_Range>)
		   || __detail::__can_adjacent_view<_Nm, _Range>
	  constexpr auto
	  operator() [[nodiscard]] (_Range&& __r) const
	  {
	    if constexpr (_Nm == 0)
	      return views::empty<tuple<>>;
	    else
	      return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
	  }
      };

    template<size_t _Nm>
      inline constexpr _Adjacent<_Nm> adjacent;

    inline constexpr auto pairwise = adjacent<2>;
  }

  template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
   requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
     && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
     && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
						       range_reference_t<_Vp>>>
  class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
  {
    [[no_unique_address]] __detail::__box<_Fp> _M_fun;
    adjacent_view<_Vp, _Nm> _M_inner;

    using _InnerView = adjacent_view<_Vp, _Nm>;

    template<bool _Const>
      using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;

    template<bool _Const>
      using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;

    template<bool> class _Iterator;
    template<bool> class _Sentinel;

  public:
    adjacent_transform_view() = default;

    constexpr explicit
    adjacent_transform_view(_Vp __base, _Fp __fun)
      : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
    { }

    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
    // 3947. Unexpected constraints on adjacent_transform_view::base()
    constexpr _Vp
    base() const & requires copy_constructible<_Vp>
    { return _M_inner.base(); }

    constexpr _Vp
    base() &&
    { return std::move(_M_inner.base()); }

    constexpr auto
    begin()
    { return _Iterator<false>(*this, _M_inner.begin()); }

    constexpr auto
    begin() const
      requires range<const _InnerView>
	&& regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
			     range_reference_t<const _Vp>>
    { return _Iterator<true>(*this, _M_inner.begin()); }

    constexpr auto
    end()
    {
      if constexpr (common_range<_InnerView>)
        return _Iterator<false>(*this, _M_inner.end());
      else
        return _Sentinel<false>(_M_inner.end());
    }

    constexpr auto
    end() const
      requires range<const _InnerView>
	&& regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
			     range_reference_t<const _Vp>>
    {
      if constexpr (common_range<const _InnerView>)
        return _Iterator<true>(*this, _M_inner.end());
      else
        return _Sentinel<true>(_M_inner.end());
    }

    constexpr auto
    size() requires sized_range<_InnerView>
    { return _M_inner.size(); }

    constexpr auto
    size() const requires sized_range<const _InnerView>
    { return _M_inner.size(); }
  };

  template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
   requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
     && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
     && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
						       range_reference_t<_Vp>>>
  template<bool _Const>
  class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
  {
    using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
    using _Base = __detail::__maybe_const_t<_Const, _Vp>;
    using _Fun_handle = decltype([]<size_t... _Ids>(std::index_sequence<_Ids...>) {
			   return __detail::__func_handle_t<
				    __detail::__maybe_const_t<_Const, _Fp>,
				    iterator_t<__detail::__maybe_const_t<(_Ids, _Const), _Vp>>...>();
			}(make_index_sequence<_Nm>()));

    [[no_unique_address]] _Fun_handle _M_fun;
    _InnerIter<_Const> _M_inner;

    constexpr
    _Iterator(_Fun_handle __fun, _InnerIter<_Const> __inner)
      : _M_fun(__fun), _M_inner(std::move(__inner))
    { }

    constexpr
    _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
      : _M_fun(*__parent._M_fun), _M_inner(std::move(__inner))
    { }

    static auto
    _S_iter_cat()
    {
      using __detail::__maybe_const_t;
      using __detail::__unarize;
      using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
				   range_reference_t<_Base>>;
      using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3798. Rvalue reference and iterator_category
      if constexpr (!is_reference_v<_Res>)
	return input_iterator_tag{};
      else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
	return random_access_iterator_tag{};
      else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
	return bidirectional_iterator_tag{};
      else if constexpr (derived_from<_Cat, forward_iterator_tag>)
	return forward_iterator_tag{};
      else
	return input_iterator_tag{};
    }

    friend class adjacent_transform_view;

  public:
    using iterator_category = decltype(_S_iter_cat());
    using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
    using value_type
      = remove_cvref_t<invoke_result_t
		       <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
			range_reference_t<_Base>>>;
    using difference_type = range_difference_t<_Base>;

    _Iterator() = default;

    constexpr
    _Iterator(_Iterator<!_Const> __i)
      requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
      : _M_fun(__i._M_fun), _M_inner(std::move(__i._M_inner))
    { }

    constexpr decltype(auto)
    operator*() const
    {
      return std::apply([&](const auto&... __iters) -> decltype(auto) {
	return _M_fun._M_call_deref(__iters...);
      }, _M_inner._M_current);
    }

    constexpr _Iterator&
    operator++()
    {
      ++_M_inner;
      return *this;
    }

    constexpr _Iterator
    operator++(int)
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--() requires bidirectional_range<_Base>
    {
      --_M_inner;
      return *this;
    }

    constexpr _Iterator
    operator--(int) requires bidirectional_range<_Base>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __x) requires random_access_range<_Base>
    {
      _M_inner += __x;
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __x) requires random_access_range<_Base>
    {
      _M_inner -= __x;
      return *this;
    }

    constexpr decltype(auto)
    operator[](difference_type __n) const requires random_access_range<_Base>
    {
      return std::apply([&](const auto&... __iters) -> decltype(auto) {
	return _M_fun._M_call_subscript(__n, __iters...);
      }, _M_inner._M_current);
    }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
    { return __x._M_inner == __y._M_inner; }

    friend constexpr bool
    operator<(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __x._M_inner < __y._M_inner; }

    friend constexpr bool
    operator>(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __x._M_inner > __y._M_inner; }

    friend constexpr bool
    operator<=(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __x._M_inner <= __y._M_inner; }

    friend constexpr bool
    operator>=(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __x._M_inner >= __y._M_inner; }

    friend constexpr auto
    operator<=>(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base> &&
      three_way_comparable<_InnerIter<_Const>>
    { return __x._M_inner <=> __y._M_inner; }

    friend constexpr _Iterator
    operator+(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base>
    { return _Iterator(__i._M_fun, __i._M_inner + __n); }

    friend constexpr _Iterator
    operator+(difference_type __n, const _Iterator& __i)
      requires random_access_range<_Base>
    { return _Iterator(__i._M_fun, __i._M_inner + __n); }

    friend constexpr _Iterator
    operator-(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base>
    { return _Iterator(__i._M_fun, __i._M_inner - __n); }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y)
      requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
    { return __x._M_inner - __y._M_inner; }
  };

  template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
   requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
     && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
     && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
						       range_reference_t<_Vp>>>
  template<bool _Const>
  class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
  {
    _InnerSent<_Const> _M_inner;

    constexpr explicit
    _Sentinel(_InnerSent<_Const> __inner)
      : _M_inner(__inner)
    { }

    friend class adjacent_transform_view;

  public:
    _Sentinel() = default;

    constexpr
    _Sentinel(_Sentinel<!_Const> __i)
      requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
      : _M_inner(std::move(__i._M_inner))
    { }

    template<bool _OtherConst>
      requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
    friend constexpr bool
    operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    { return __x._M_inner == __y._M_inner; }

    template<bool _OtherConst>
      requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
    friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
    operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    { return __x._M_inner - __y._M_inner; }

    template<bool _OtherConst>
      requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
    friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
    operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
    { return __x._M_inner - __y._M_inner; }
  };

  namespace views
  {
    namespace __detail
    {
      template<size_t _Nm, typename _Range, typename _Fp>
	concept __can_adjacent_transform_view
	  = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
		         (std::declval<_Range>(), std::declval<_Fp>()); };
    }

    template<size_t _Nm>
      struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 4098. views::adjacent<0> should reject non-forward ranges
	template<viewable_range _Range, typename _Fp>
	  requires ((_Nm == 0) && forward_range<_Range>)
		   || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
	  constexpr auto
	  operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
	  {
	    if constexpr (_Nm == 0)
	      return zip_transform(std::forward<_Fp>(__f));
	    else
	      return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
		(std::forward<_Range>(__r), std::forward<_Fp>(__f));
	  }

	using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
	static constexpr int _S_arity = 2;
	static constexpr bool _S_has_simple_extra_args = true;
      };

    template<size_t _Nm>
      inline constexpr _AdjacentTransform<_Nm> adjacent_transform;

    inline constexpr auto pairwise_transform = adjacent_transform<2>;
  }
#endif // __cpp_lib_ranges_zip

#ifdef __cpp_lib_ranges_chunk // C++ >= 23
  namespace __detail
  {
    template<typename _Tp>
    constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
    {
      _Tp __r = __num / __denom;
      if (__num % __denom)
	++__r;
      return __r;
    }
  }

  template<view _Vp>
    requires input_range<_Vp>
  class chunk_view : public view_interface<chunk_view<_Vp>>
  {
    _Vp _M_base;
    range_difference_t<_Vp> _M_n;
    range_difference_t<_Vp> _M_remainder = 0;
    __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;

    class _OuterIter;
    class _InnerIter;

  public:
    constexpr explicit
    chunk_view(_Vp __base, range_difference_t<_Vp> __n)
      : _M_base(std::move(__base)), _M_n(__n)
    { __glibcxx_assert(__n >= 0); }

    constexpr _Vp
    base() const & requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr _OuterIter
    begin()
    {
      _M_current = ranges::begin(_M_base);
      _M_remainder = _M_n;
      return _OuterIter(*this);
    }

    constexpr default_sentinel_t
    end() const noexcept
    { return default_sentinel; }

    constexpr auto
    size() requires sized_range<_Vp>
    {
      return __detail::__to_unsigned_like(__detail::__div_ceil
					  (ranges::distance(_M_base), _M_n));
    }

    constexpr auto
    size() const requires sized_range<const _Vp>
    {
      return __detail::__to_unsigned_like(__detail::__div_ceil
					  (ranges::distance(_M_base), _M_n));
    }
  };

  template<typename _Range>
    chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;

  template<view _Vp>
    requires input_range<_Vp>
  class chunk_view<_Vp>::_OuterIter
  {
    chunk_view* _M_parent;

    constexpr explicit
    _OuterIter(chunk_view& __parent) noexcept
      : _M_parent(std::__addressof(__parent))
    { }

    friend chunk_view;

  public:
    using iterator_concept = input_iterator_tag;
    using difference_type = range_difference_t<_Vp>;

    struct value_type;

    _OuterIter(_OuterIter&&) = default;
    _OuterIter& operator=(_OuterIter&&) = default;

    constexpr value_type
    operator*() const
    {
      __glibcxx_assert(*this != default_sentinel);
      return value_type(*_M_parent);
    }

    constexpr _OuterIter&
    operator++()
    {
      __glibcxx_assert(*this != default_sentinel);
      ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
		      ranges::end(_M_parent->_M_base));
      _M_parent->_M_remainder = _M_parent->_M_n;
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    friend constexpr bool
    operator==(const _OuterIter& __x, default_sentinel_t)
    {
      return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
	&& __x._M_parent->_M_remainder != 0;
    }

    friend constexpr difference_type
    operator-(default_sentinel_t, const _OuterIter& __x)
    requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
    {
      const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;

      if (__dist < __x._M_parent->_M_remainder)
	return __dist == 0 ? 0 : 1;

      return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
				      __x._M_parent->_M_n);
    }

    friend constexpr difference_type
    operator-(const _OuterIter& __x, default_sentinel_t __y)
    requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
    { return -(__y - __x); }
  };

  template<view _Vp>
    requires input_range<_Vp>
  struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
  {
  private:
    chunk_view* _M_parent;

    constexpr explicit
    value_type(chunk_view& __parent) noexcept
    : _M_parent(std::__addressof(__parent))
    { }

    friend _OuterIter;

  public:
    constexpr _InnerIter
    begin() const noexcept
    { return _InnerIter(*_M_parent); }

    constexpr default_sentinel_t
    end() const noexcept
    { return default_sentinel; }

    constexpr auto
    size() const
    requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
    {
      return __detail::__to_unsigned_like
	(ranges::min(_M_parent->_M_remainder,
		     ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
    }
  };

  template<view _Vp>
    requires input_range<_Vp>
  class chunk_view<_Vp>::_InnerIter
  {
    chunk_view* _M_parent;

    constexpr explicit
    _InnerIter(chunk_view& __parent) noexcept
    : _M_parent(std::__addressof(__parent))
    { }

    friend _OuterIter::value_type;

  public:
    using iterator_concept = input_iterator_tag;
    using difference_type = range_difference_t<_Vp>;
    using value_type = range_value_t<_Vp>;

    _InnerIter(_InnerIter&&) = default;
    _InnerIter& operator=(_InnerIter&&) = default;

    constexpr const iterator_t<_Vp>&
    base() const &
    { return *_M_parent->_M_current; }

    constexpr range_reference_t<_Vp>
    operator*() const
    {
      __glibcxx_assert(*this != default_sentinel);
      return **_M_parent->_M_current;
    }

    constexpr _InnerIter&
    operator++()
    {
      __glibcxx_assert(*this != default_sentinel);
      ++*_M_parent->_M_current;
      if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
	_M_parent->_M_remainder = 0;
      else
	--_M_parent->_M_remainder;
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    friend constexpr bool
    operator==(const _InnerIter& __x, default_sentinel_t) noexcept
    { return __x._M_parent->_M_remainder == 0; }

    friend constexpr difference_type
    operator-(default_sentinel_t, const _InnerIter& __x)
      requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
    {
      return ranges::min(__x._M_parent->_M_remainder,
			 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
    }

    friend constexpr difference_type
    operator-(const _InnerIter& __x, default_sentinel_t __y)
      requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
    { return -(__y - __x); }

    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
    friend constexpr range_rvalue_reference_t<_Vp>
    iter_move(const _InnerIter& __i)
    noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
    { return ranges::iter_move(*__i._M_parent->_M_current); }

    friend constexpr void
    iter_swap(const _InnerIter& __x, const _InnerIter& __y)
    noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
					*__x._M_parent->_M_current)))
    requires indirectly_swappable<iterator_t<_Vp>>
    { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
  };

  template<view _Vp>
    requires forward_range<_Vp>
  class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
  {
    _Vp _M_base;
    range_difference_t<_Vp> _M_n;
    template<bool> class _Iterator;

  public:
    constexpr explicit
    chunk_view(_Vp __base, range_difference_t<_Vp> __n)
    : _M_base(std::move(__base)), _M_n(__n)
    { __glibcxx_assert(__n > 0); }

    constexpr _Vp
    base() const & requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr auto
    begin() requires (!__detail::__simple_view<_Vp>)
    { return _Iterator<false>(this, ranges::begin(_M_base)); }

    constexpr auto
    begin() const requires forward_range<const _Vp>
    { return _Iterator<true>(this, ranges::begin(_M_base)); }

    constexpr auto
    end() requires (!__detail::__simple_view<_Vp>)
    {
      if constexpr (common_range<_Vp> && sized_range<_Vp>)
	{
	  auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
	  return _Iterator<false>(this, ranges::end(_M_base), __missing);
	}
      else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
	return _Iterator<false>(this, ranges::end(_M_base));
      else
	return default_sentinel;
    }

    constexpr auto
    end() const requires forward_range<const _Vp>
    {
      if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
	{
	  auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
	  return _Iterator<true>(this, ranges::end(_M_base), __missing);
	}
      else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
	return _Iterator<true>(this, ranges::end(_M_base));
      else
	return default_sentinel;
    }

    constexpr auto
    size() requires sized_range<_Vp>
    {
      return __detail::__to_unsigned_like(__detail::__div_ceil
					  (ranges::distance(_M_base), _M_n));
    }

    constexpr auto
    size() const requires sized_range<const _Vp>
    {
      return __detail::__to_unsigned_like(__detail::__div_ceil
					  (ranges::distance(_M_base), _M_n));
    }
  };

  template<typename _Vp>
    inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
      = forward_range<_Vp> && enable_borrowed_range<_Vp>;

  template<view _Vp>
    requires forward_range<_Vp>
  template<bool _Const>
  class chunk_view<_Vp>::_Iterator
  {
    using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
    using _Base = __detail::__maybe_const_t<_Const, _Vp>;

    iterator_t<_Base> _M_current = iterator_t<_Base>();
    sentinel_t<_Base> _M_end = sentinel_t<_Base>();
    range_difference_t<_Base> _M_n = 0;
    range_difference_t<_Base> _M_missing = 0;

    constexpr
    _Iterator(_Parent* __parent, iterator_t<_Base> __current,
	      range_difference_t<_Base> __missing = 0)
    : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
      _M_n(__parent->_M_n), _M_missing(__missing)
    { }

    static auto
    _S_iter_cat()
    {
      if constexpr (random_access_range<_Base>)
	return random_access_iterator_tag{};
      else if constexpr (bidirectional_range<_Base>)
	return bidirectional_iterator_tag{};
      else
	return forward_iterator_tag{};
    }

    friend chunk_view;

  public:
    using iterator_category = input_iterator_tag;
    using iterator_concept = decltype(_S_iter_cat());
    using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
    using difference_type = range_difference_t<_Base>;

    _Iterator() = default;

    constexpr _Iterator(_Iterator<!_Const> __i)
      requires _Const
	&& convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
	&& convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
    : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
      _M_n(__i._M_n), _M_missing(__i._M_missing)
    { }

    constexpr iterator_t<_Base>
    base() const
    { return _M_current; }

    constexpr value_type
    operator*() const
    {
      __glibcxx_assert(_M_current != _M_end);
      return views::take(subrange(_M_current, _M_end), _M_n);
    }

    constexpr _Iterator&
    operator++()
    {
      __glibcxx_assert(_M_current != _M_end);
      _M_missing = ranges::advance(_M_current, _M_n, _M_end);
      return *this;
    }

    constexpr _Iterator
    operator++(int)
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--() requires bidirectional_range<_Base>
    {
      ranges::advance(_M_current, _M_missing - _M_n);
      _M_missing = 0;
      return *this;
    }

    constexpr _Iterator
    operator--(int) requires bidirectional_range<_Base>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __x)
      requires random_access_range<_Base>
    {
      if (__x > 0)
	{
	  __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
	  _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
	}
      else if (__x < 0)
	{
	  ranges::advance(_M_current, _M_n * __x + _M_missing);
	  _M_missing = 0;
	}
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __x)
      requires random_access_range<_Base>
    { return *this += -__x; }

    constexpr value_type
    operator[](difference_type __n) const
      requires random_access_range<_Base>
    { return *(*this + __n); }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
    { return __x._M_current == __y._M_current; }

    friend constexpr bool
    operator==(const _Iterator& __x, default_sentinel_t)
    { return __x._M_current == __x._M_end; }

    friend constexpr bool
    operator<(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __x._M_current > __y._M_current; }

    friend constexpr bool
    operator>(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __y < __x; }

    friend constexpr bool
    operator<=(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return !(__y < __x); }

    friend constexpr bool
    operator>=(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return !(__x < __y); }

    friend constexpr auto
    operator<=>(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
	&& three_way_comparable<iterator_t<_Base>>
    { return __x._M_current <=> __y._M_current; }

    friend constexpr _Iterator
    operator+(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base>
    {
      auto __r  = __i;
      __r += __n;
      return __r;
    }

    friend constexpr _Iterator
    operator+(difference_type __n, const _Iterator& __i)
      requires random_access_range<_Base>
    {
      auto __r  = __i;
      __r += __n;
      return __r;
    }

    friend constexpr _Iterator
    operator-(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base>
    {
      auto __r  = __i;
      __r -= __n;
      return __r;
    }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y)
      requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
    {
      return (__x._M_current - __y._M_current
	      + __x._M_missing - __y._M_missing) / __x._M_n;
    }

    friend constexpr difference_type
    operator-(default_sentinel_t, const _Iterator& __x)
      requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
    { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }

    friend constexpr difference_type
    operator-(const _Iterator& __x, default_sentinel_t __y)
      requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
    { return -(__y - __x); }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Dp>
	concept __can_chunk_view
	  = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
    }

    struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
    {
      template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
	requires __detail::__can_chunk_view<_Range, _Dp>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
	{ return chunk_view(std::forward<_Range>(__r), __n); }

      using __adaptor::_RangeAdaptor<_Chunk>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _Chunk chunk;
  }
#endif // __cpp_lib_ranges_chunk

#ifdef __cpp_lib_ranges_slide // C++ >= 23
  namespace __detail
  {
    template<typename _Vp>
      concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;

    template<typename _Vp>
      concept __slide_caches_last
      = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;

    template<typename _Vp>
      concept __slide_caches_first
      = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
  }

  template<forward_range _Vp>
    requires view<_Vp>
  class slide_view : public view_interface<slide_view<_Vp>>
  {
    _Vp _M_base;
    range_difference_t<_Vp> _M_n;
    [[no_unique_address]]
      __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
				  __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
    [[no_unique_address]]
      __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
				  __detail::_CachedPosition<_Vp>, 1> _M_cached_end;

    template<bool> class _Iterator;
    class _Sentinel;

  public:
    constexpr explicit
    slide_view(_Vp __base, range_difference_t<_Vp> __n)
    : _M_base(std::move(__base)), _M_n(__n)
    { __glibcxx_assert(__n > 0); }

    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
    constexpr _Vp
    base() const & requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr auto
    begin() requires (!(__detail::__simple_view<_Vp>
			&& __detail::__slide_caches_nothing<const _Vp>))
    {
      if constexpr (__detail::__slide_caches_first<_Vp>)
	{
	  iterator_t<_Vp> __it;
	  if (_M_cached_begin._M_has_value())
	    __it = _M_cached_begin._M_get(_M_base);
	  else
	    {
	      __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
	      _M_cached_begin._M_set(_M_base, __it);
	    }
	  return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
	}
      else
	return _Iterator<false>(ranges::begin(_M_base), _M_n);
    }

    constexpr auto
    begin() const requires __detail::__slide_caches_nothing<const _Vp>
    { return _Iterator<true>(ranges::begin(_M_base), _M_n); }

    constexpr auto
    end() requires (!(__detail::__simple_view<_Vp>
		      && __detail::__slide_caches_nothing<const _Vp>))
    {
      if constexpr (__detail::__slide_caches_nothing<_Vp>)
	return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
				_M_n);
      else if constexpr (__detail::__slide_caches_last<_Vp>)
	{
	  iterator_t<_Vp> __it;
	  if (_M_cached_end._M_has_value())
	    __it = _M_cached_end._M_get(_M_base);
	  else
	    {
	      __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
	      _M_cached_end._M_set(_M_base, __it);
	    }
	  return _Iterator<false>(std::move(__it), _M_n);
	}
      else if constexpr (common_range<_Vp>)
	return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
      else
	return _Sentinel(ranges::end(_M_base));
    }

    constexpr auto
    end() const requires __detail::__slide_caches_nothing<const _Vp>
    { return begin() + range_difference_t<const _Vp>(size()); }

    constexpr auto
    size() requires sized_range<_Vp>
    {
      auto __sz = ranges::distance(_M_base) - _M_n + 1;
      if (__sz < 0)
	__sz = 0;
      return __detail::__to_unsigned_like(__sz);
    }

    constexpr auto
    size() const requires sized_range<const _Vp>
    {
      auto __sz = ranges::distance(_M_base) - _M_n + 1;
      if (__sz < 0)
	__sz = 0;
      return __detail::__to_unsigned_like(__sz);
    }
  };

  template<typename _Range>
    slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;

  template<typename _Vp>
    inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
      = enable_borrowed_range<_Vp>;

  template<forward_range _Vp>
    requires view<_Vp>
  template<bool _Const>
  class slide_view<_Vp>::_Iterator
  {
    using _Base = __detail::__maybe_const_t<_Const, _Vp>;
    static constexpr bool _S_last_elt_present
      = __detail::__slide_caches_first<_Base>;

    iterator_t<_Base> _M_current = iterator_t<_Base>();
    [[no_unique_address]]
      __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
	_M_last_elt = decltype(_M_last_elt)();
    range_difference_t<_Base> _M_n = 0;

    constexpr
    _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
      requires (!_S_last_elt_present)
    : _M_current(__current), _M_n(__n)
    { }

    constexpr
    _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
	      range_difference_t<_Base> __n)
      requires _S_last_elt_present
    : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
    { }

    static auto
    _S_iter_concept()
    {
      if constexpr (random_access_range<_Base>)
	return random_access_iterator_tag{};
      else if constexpr (bidirectional_range<_Base>)
	return bidirectional_iterator_tag{};
      else
	return forward_iterator_tag{};
    }

    friend slide_view;
    friend slide_view::_Sentinel;

  public:
    using iterator_category = input_iterator_tag;
    using iterator_concept = decltype(_S_iter_concept());
    using value_type = decltype(views::counted(_M_current, _M_n));
    using difference_type = range_difference_t<_Base>;

    _Iterator() = default;

    constexpr
    _Iterator(_Iterator<!_Const> __i)
      requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
    : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
    { }

    constexpr auto
    operator*() const
    { return views::counted(_M_current, _M_n); }

    constexpr _Iterator&
    operator++()
    {
      ++_M_current;
      if constexpr (_S_last_elt_present)
	++_M_last_elt;
      return *this;
    }

    constexpr _Iterator
    operator++(int)
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--() requires bidirectional_range<_Base>
    {
      --_M_current;
      if constexpr (_S_last_elt_present)
	--_M_last_elt;
      return *this;
    }

    constexpr _Iterator
    operator--(int) requires bidirectional_range<_Base>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __x)
      requires random_access_range<_Base>
    {
      _M_current += __x;
      if constexpr (_S_last_elt_present)
	_M_last_elt += __x;
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __x)
      requires random_access_range<_Base>
    {
      _M_current -= __x;
      if constexpr (_S_last_elt_present)
	_M_last_elt -= __x;
      return *this;
    }

    constexpr auto
    operator[](difference_type __n) const
      requires random_access_range<_Base>
    { return views::counted(_M_current + __n, _M_n); }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
    {
      if constexpr (_S_last_elt_present)
	return __x._M_last_elt == __y._M_last_elt;
      else
	return __x._M_current == __y._M_current;
    }

    friend constexpr bool
    operator<(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __x._M_current < __y._M_current; }

    friend constexpr bool
    operator>(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __y < __x; }

    friend constexpr bool
    operator<=(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return !(__y < __x); }

    friend constexpr bool
    operator>=(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return !(__x < __y); }

    friend constexpr auto
    operator<=>(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
	&& three_way_comparable<iterator_t<_Base>>
     { return __x._M_current <=> __y._M_current; }

    friend constexpr _Iterator
    operator+(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base>
    {
      auto __r = __i;
      __r += __n;
      return __r;
    }

    friend constexpr _Iterator
    operator+(difference_type __n, const _Iterator& __i)
      requires random_access_range<_Base>
    {
      auto __r = __i;
      __r += __n;
      return __r;
    }

    friend constexpr _Iterator
    operator-(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base>
    {
      auto __r = __i;
      __r -= __n;
      return __r;
    }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y)
      requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
    {
      if constexpr (_S_last_elt_present)
	return __x._M_last_elt - __y._M_last_elt;
      else
	return __x._M_current - __y._M_current;
    }
  };

  template<forward_range _Vp>
    requires view<_Vp>
  class slide_view<_Vp>::_Sentinel
  {
    sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();

    constexpr explicit
    _Sentinel(sentinel_t<_Vp> __end)
    : _M_end(__end)
    { }

    friend slide_view;

  public:
    _Sentinel() = default;

    friend constexpr bool
    operator==(const _Iterator<false>& __x, const _Sentinel& __y)
    { return __x._M_last_elt == __y._M_end; }

    friend constexpr range_difference_t<_Vp>
    operator-(const _Iterator<false>& __x, const _Sentinel& __y)
      requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
    { return __x._M_last_elt - __y._M_end; }

    friend constexpr range_difference_t<_Vp>
    operator-(const _Sentinel& __y, const _Iterator<false>& __x)
      requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
    { return __y._M_end -__x._M_last_elt; }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Dp>
	concept __can_slide_view
	  = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
    }

    struct _Slide : __adaptor::_RangeAdaptor<_Slide>
    {
      template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
	requires __detail::__can_slide_view<_Range, _Dp>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
	{ return slide_view(std::forward<_Range>(__r), __n); }

      using __adaptor::_RangeAdaptor<_Slide>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _Slide slide;
  }
#endif // __cpp_lib_ranges_slide

#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
  template<forward_range _Vp,
	   indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
    requires view<_Vp> && is_object_v<_Pred>
  class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
  {
    _Vp _M_base = _Vp();
    __detail::__box<_Pred> _M_pred;
    __detail::_CachedPosition<_Vp> _M_cached_begin;

    constexpr iterator_t<_Vp>
    _M_find_next(iterator_t<_Vp> __current)
    {
      __glibcxx_assert(_M_pred.has_value());
      auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
	return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
      };
      auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
      return ranges::next(__it, 1, ranges::end(_M_base));
    }

    constexpr iterator_t<_Vp>
    _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
    {
      __glibcxx_assert(_M_pred.has_value());
      auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
	return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
      };
      auto __rbegin = std::make_reverse_iterator(__current);
      auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
      __glibcxx_assert(__rbegin != __rend);
      auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
      return ranges::prev(__it, 1, ranges::begin(_M_base));
    }

    class _Iterator;

  public:
    chunk_by_view() requires (default_initializable<_Vp>
			      && default_initializable<_Pred>)
      = default;

    constexpr explicit
    chunk_by_view(_Vp __base, _Pred __pred)
    : _M_base(std::move(__base)), _M_pred(std::move(__pred))
    { }

    constexpr _Vp
    base() const & requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr const _Pred&
    pred() const
    { return *_M_pred; }

    constexpr _Iterator
    begin()
    {
      __glibcxx_assert(_M_pred.has_value());
      iterator_t<_Vp> __it;
      if (_M_cached_begin._M_has_value())
	__it = _M_cached_begin._M_get(_M_base);
      else
	{
	  __it = _M_find_next(ranges::begin(_M_base));
	  _M_cached_begin._M_set(_M_base, __it);
	}
      return _Iterator(*this, ranges::begin(_M_base), __it);
    }

    constexpr auto
    end()
    {
      if constexpr (common_range<_Vp>)
	return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
      else
	return default_sentinel;
    }
  };

  template<typename _Range, typename _Pred>
    chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;

  template<forward_range _Vp,
	   indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
    requires view<_Vp> && is_object_v<_Pred>
  class chunk_by_view<_Vp, _Pred>::_Iterator
  {
    chunk_by_view* _M_parent = nullptr;
    iterator_t<_Vp> _M_current = iterator_t<_Vp>();
    iterator_t<_Vp> _M_next = iterator_t<_Vp>();

    constexpr
    _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
    : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
    { }

    static auto
    _S_iter_concept()
    {
      if constexpr (bidirectional_range<_Vp>)
	return bidirectional_iterator_tag{};
      else
	return forward_iterator_tag{};
    }

    friend chunk_by_view;

  public:
    using value_type = subrange<iterator_t<_Vp>>;
    using difference_type = range_difference_t<_Vp>;
    using iterator_category = input_iterator_tag;
    using iterator_concept = decltype(_S_iter_concept());

    _Iterator() = default;

    constexpr value_type
    operator*() const
    {
      __glibcxx_assert(_M_current != _M_next);
      return ranges::subrange(_M_current, _M_next);
    }

    constexpr _Iterator&
    operator++()
    {
      __glibcxx_assert(_M_current != _M_next);
      _M_current = _M_next;
      _M_next = _M_parent->_M_find_next(_M_current);
      return *this;
    }

    constexpr _Iterator
    operator++(int)
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--() requires bidirectional_range<_Vp>
    {
      _M_next = _M_current;
      _M_current = _M_parent->_M_find_prev(_M_next);
      return *this;
    }

    constexpr _Iterator
    operator--(int) requires bidirectional_range<_Vp>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
    { return __x._M_current == __y._M_current; }

    friend constexpr bool
    operator==(const _Iterator& __x, default_sentinel_t)
    { return __x._M_current == __x._M_next; }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pred>
	concept __can_chunk_by_view
	  = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
    }

    struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
    {
      template<viewable_range _Range, typename _Pred>
	requires __detail::__can_chunk_by_view<_Range, _Pred>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
	{ return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }

      using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _ChunkBy chunk_by;
  }
#endif // __cpp_lib_ranges_chunk_by

#ifdef __cpp_lib_ranges_join_with // C++ >= 23
  namespace __detail
  {
    template<typename _Range, typename _Pattern>
      concept __compatible_joinable_ranges
	= common_with<range_value_t<_Range>, range_value_t<_Pattern>>
	  && common_reference_with<range_reference_t<_Range>,
				   range_reference_t<_Pattern>>
	  && common_reference_with<range_rvalue_reference_t<_Range>,
				   range_rvalue_reference_t<_Pattern>>;

    template<typename _Range>
      concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
  }

  template<input_range _Vp, forward_range _Pattern>
    requires view<_Vp> && view<_Pattern>
      && input_range<range_reference_t<_Vp>>
      && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
  class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
  {
    using _InnerRange = range_reference_t<_Vp>;

    _Vp _M_base = _Vp();
    [[no_unique_address]]
      __detail::__maybe_present_t<!forward_range<_Vp>,
	__detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
    __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
    _Pattern _M_pattern = _Pattern();

    template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
    template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
    template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;

    template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
    template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
    template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;

    template<bool _Const>
      static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;

    template<bool _Const>
    struct __iter_cat
    { };

    template<bool _Const>
      requires _S_ref_is_glvalue<_Const>
	&& forward_range<_Base<_Const>>
	&& forward_range<_InnerBase<_Const>>
    struct __iter_cat<_Const>
    {
      private:
	static auto
	_S_iter_cat()
	{
	  using _OuterIter = join_with_view::_OuterIter<_Const>;
	  using _InnerIter = join_with_view::_InnerIter<_Const>;
	  using _PatternIter = join_with_view::_PatternIter<_Const>;
	  using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
	  using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
	  using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3798. Rvalue reference and iterator_category
	  if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
							   iter_reference_t<_PatternIter>>>)
	    return input_iterator_tag{};
	  else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
			     && derived_from<_InnerCat, bidirectional_iterator_tag>
			     && derived_from<_PatternCat, bidirectional_iterator_tag>
			     && common_range<_InnerBase<_Const>>
			     && common_range<_PatternBase<_Const>>)
	    return bidirectional_iterator_tag{};
	  else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
			     && derived_from<_InnerCat, forward_iterator_tag>
			     && derived_from<_PatternCat, forward_iterator_tag>)
	    return forward_iterator_tag{};
	  else
	    return input_iterator_tag{};
	}
      public:
	using iterator_category = decltype(_S_iter_cat());
    };

    template<bool> class _Iterator;
    template<bool> class _Sentinel;

  public:
    join_with_view() requires (default_initializable<_Vp>
			       && default_initializable<_Pattern>)
      = default;

    constexpr explicit
    join_with_view(_Vp __base, _Pattern __pattern)
    : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
    { }

    template<input_range _Range>
      requires constructible_from<_Vp, views::all_t<_Range>>
	&& constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
    constexpr explicit
    join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
    : _M_base(views::all(std::forward<_Range>(__r))),
      _M_pattern(views::single(std::move(__e)))
    { }

    constexpr _Vp
    base() const& requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr auto
    begin()
    {
      if constexpr (forward_range<_Vp>)
	{
	  constexpr bool __use_const = is_reference_v<_InnerRange>
	    && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
	  return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
	}
      else
	{
	  _M_outer_it = ranges::begin(_M_base);
	  return _Iterator<false>{*this};
	}
    }

    constexpr auto
    begin() const
      requires forward_range<const _Vp>
	&& forward_range<const _Pattern>
	&& is_reference_v<range_reference_t<const _Vp>>
	&& input_range<range_reference_t<const _Vp>>
    { return _Iterator<true>{*this, ranges::begin(_M_base)}; }

    constexpr auto
    end()
    {
      constexpr bool __use_const
	= __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
      if constexpr (is_reference_v<_InnerRange>
		    && forward_range<_Vp> && common_range<_Vp>
		    && forward_range<_InnerRange> && common_range<_InnerRange>)
        return _Iterator<__use_const>{*this, ranges::end(_M_base)};
      else
        return _Sentinel<__use_const>{*this};
    }

    constexpr auto
    end() const
      requires forward_range<const _Vp>
	&& forward_range<const _Pattern>
	&& is_reference_v<range_reference_t<const _Vp>>
	&& input_range<range_reference_t<const _Vp>>
    {
      using _InnerConstRange = range_reference_t<const _Vp>;
      if constexpr (forward_range<_InnerConstRange>
		    && common_range<const _Vp>
		    && common_range<_InnerConstRange>)
        return _Iterator<true>{*this, ranges::end(_M_base)};
      else
        return _Sentinel<true>{*this};
    }
  };

  template<typename _Range, typename _Pattern>
    join_with_view(_Range&&, _Pattern&&)
      -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;

  template<input_range _Range>
    join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
      -> join_with_view<views::all_t<_Range>,
			single_view<range_value_t<range_reference_t<_Range>>>>;

  template<input_range _Vp, forward_range _Pattern>
    requires view<_Vp> && view<_Pattern>
      && input_range<range_reference_t<_Vp>>
      && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
  template<bool _Const>
  class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
  {
    using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
    using _Base = join_with_view::_Base<_Const>;
    using _InnerBase = join_with_view::_InnerBase<_Const>;
    using _PatternBase = join_with_view::_PatternBase<_Const>;

    using _OuterIter = join_with_view::_OuterIter<_Const>;
    using _InnerIter = join_with_view::_InnerIter<_Const>;
    using _PatternIter = join_with_view::_PatternIter<_Const>;

    static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;

    _Parent* _M_parent = nullptr;
    [[no_unique_address]]
      __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
	= decltype(_M_outer_it)();
    variant<_PatternIter, _InnerIter> _M_inner_it;

    constexpr _OuterIter&
    _M_get_outer()
    {
      if constexpr (forward_range<_Base>)
	return _M_outer_it;
      else
	return *_M_parent->_M_outer_it;
    }

    constexpr const _OuterIter&
    _M_get_outer() const
    {
      if constexpr (forward_range<_Base>)
	return _M_outer_it;
      else
	return *_M_parent->_M_outer_it;
    }

    constexpr
    _Iterator(_Parent& __parent, _OuterIter __outer)
      requires forward_range<_Base>
    : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
    {
      if (_M_get_outer() != ranges::end(_M_parent->_M_base))
	{
	  auto&& __inner = _M_update_inner();
	  _M_inner_it.template emplace<1>(ranges::begin(__inner));
	  _M_satisfy();
	}
    }

    constexpr
    _Iterator(_Parent& __parent)
      requires (!forward_range<_Base>)
    : _M_parent(std::__addressof(__parent))
    {
      if (_M_get_outer() != ranges::end(_M_parent->_M_base))
	{
	  auto&& __inner = _M_update_inner();
	  _M_inner_it.template emplace<1>(ranges::begin(__inner));
	  _M_satisfy();
	}
    }

    constexpr auto&
    _M_update_inner()
    {
      _OuterIter& __outer = _M_get_outer();
      if constexpr (_S_ref_is_glvalue)
	return __detail::__as_lvalue(*__outer);
      else
	return _M_parent->_M_inner._M_emplace_deref(__outer);
    }

    constexpr auto&
    _M_get_inner()
    {
      if constexpr (_S_ref_is_glvalue)
	return __detail::__as_lvalue(*_M_get_outer());
      else
	return *_M_parent->_M_inner;
    }

    constexpr void
    _M_satisfy()
    {
      while (true)
	{
	  if (_M_inner_it.index() == 0)
	    {
	      if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
		break;

	      auto&& __inner = _M_update_inner();
	      _M_inner_it.template emplace<1>(ranges::begin(__inner));
	    }
	  else
	    {
	      auto&& __inner = _M_get_inner();
	      if (std::get<1>(_M_inner_it) != ranges::end(__inner))
		break;

	      if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
		{
		  if constexpr (_S_ref_is_glvalue)
		    _M_inner_it.template emplace<0>();
		  break;
		}

	      _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
	    }
	}
    }

    static auto
    _S_iter_concept()
    {
      if constexpr (_S_ref_is_glvalue
		    && bidirectional_range<_Base>
		    && __detail::__bidirectional_common<_InnerBase>
		    && __detail::__bidirectional_common<_PatternBase>)
	return bidirectional_iterator_tag{};
      else if constexpr (_S_ref_is_glvalue
			 && forward_range<_Base>
			 && forward_range<_InnerBase>)
	return forward_iterator_tag{};
      else
	return input_iterator_tag{};
    }

    friend join_with_view;

  public:
    using iterator_concept = decltype(_S_iter_concept());
    // iterator_category defined in join_with_view::__iter_cat
    using value_type = common_type_t<iter_value_t<_InnerIter>,
				     iter_value_t<_PatternIter>>;
    using difference_type = common_type_t<iter_difference_t<_OuterIter>,
					  iter_difference_t<_InnerIter>,
					  iter_difference_t<_PatternIter>>;

    _Iterator() = default;

    constexpr
    _Iterator(_Iterator<!_Const> __i)
      requires _Const
	&& convertible_to<iterator_t<_Vp>, _OuterIter>
	&& convertible_to<iterator_t<_InnerRange>, _InnerIter>
	&& convertible_to<iterator_t<_Pattern>, _PatternIter>
    : _M_parent(__i._M_parent),
      _M_outer_it(std::move(__i._M_outer_it))
    {
      if (__i._M_inner_it.index() == 0)
	_M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
      else
	_M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
    }

    constexpr common_reference_t<iter_reference_t<_InnerIter>,
			         iter_reference_t<_PatternIter>>
    operator*() const
    {
      if (_M_inner_it.index() == 0)
	return *std::get<0>(_M_inner_it);
      else
	return *std::get<1>(_M_inner_it);
    }

    constexpr _Iterator&
    operator++()
    {
      if (_M_inner_it.index() == 0)
	++std::get<0>(_M_inner_it);
      else
	++std::get<1>(_M_inner_it);
      _M_satisfy();
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    constexpr _Iterator
    operator++(int)
      requires _S_ref_is_glvalue
	&& forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
    {
      _Iterator __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--()
      requires _S_ref_is_glvalue
	&& bidirectional_range<_Base>
	&& __detail::__bidirectional_common<_InnerBase>
	&& __detail::__bidirectional_common<_PatternBase>
    {
      if (_M_outer_it == ranges::end(_M_parent->_M_base))
	{
	  auto&& __inner = *--_M_outer_it;
	  _M_inner_it.template emplace<1>(ranges::end(__inner));
	}

      while (true)
	{
	  if (_M_inner_it.index() == 0)
	    {
	      auto& __it = std::get<0>(_M_inner_it);
	      if (__it == ranges::begin(_M_parent->_M_pattern))
		{
		  auto&& __inner = *--_M_outer_it;
		  _M_inner_it.template emplace<1>(ranges::end(__inner));
		}
	      else
		break;
	    }
	  else
	    {
	      auto& __it = std::get<1>(_M_inner_it);
	      auto&& __inner = *_M_outer_it;
	      if (__it == ranges::begin(__inner))
		_M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
	      else
		break;
	    }
	}

      if (_M_inner_it.index() == 0)
	--std::get<0>(_M_inner_it);
      else
	--std::get<1>(_M_inner_it);
      return *this;
    }

    constexpr _Iterator
    operator--(int)
      requires _S_ref_is_glvalue && bidirectional_range<_Base>
	&& __detail::__bidirectional_common<_InnerBase>
	&& __detail::__bidirectional_common<_PatternBase>
    {
      _Iterator __tmp = *this;
      --*this;
      return __tmp;
    }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
      requires _S_ref_is_glvalue
	&& forward_range<_Base> && equality_comparable<_InnerIter>
    { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }

    friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
					iter_rvalue_reference_t<_PatternIter>>
    iter_move(const _Iterator& __x)
    {
      if (__x._M_inner_it.index() == 0)
	return ranges::iter_move(std::get<0>(__x._M_inner_it));
      else
	return ranges::iter_move(std::get<1>(__x._M_inner_it));
    }

    friend constexpr void
    iter_swap(const _Iterator& __x, const _Iterator& __y)
      requires indirectly_swappable<_InnerIter, _PatternIter>
    {
      if (__x._M_inner_it.index() == 0)
	{
	  if (__y._M_inner_it.index() == 0)
	    ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
	  else
	    ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
	}
      else
	{
	  if (__y._M_inner_it.index() == 0)
	    ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
	  else
	    ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
	}
    }
  };

  template<input_range _Vp, forward_range _Pattern>
    requires view<_Vp> && view<_Pattern>
      && input_range<range_reference_t<_Vp>>
      && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
  template<bool _Const>
  class join_with_view<_Vp, _Pattern>::_Sentinel
  {
    using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
    using _Base = join_with_view::_Base<_Const>;

    sentinel_t<_Base> _M_end = sentinel_t<_Base>();

    constexpr explicit
    _Sentinel(_Parent& __parent)
    : _M_end(ranges::end(__parent._M_base))
    { }

    friend join_with_view;

  public:
    _Sentinel() = default;

    constexpr
    _Sentinel(_Sentinel<!_Const> __s)
      requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
    : _M_end(std::move(__s._M_end))
    { }

    template<bool _OtherConst>
      requires sentinel_for<sentinel_t<_Base>,
			    iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
    friend constexpr bool
    operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    { return __x._M_get_outer() == __y._M_end; }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pattern>
	concept __can_join_with_view
	  = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
    } // namespace __detail

    struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
    {
      template<viewable_range _Range, typename _Pattern>
	requires __detail::__can_join_with_view<_Range, _Pattern>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
	{
	  return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
	}

      using _RangeAdaptor<_JoinWith>::operator();
      static constexpr int _S_arity = 2;
      template<typename _Pattern>
	static constexpr bool _S_has_simple_extra_args
	  = _LazySplit::_S_has_simple_extra_args<_Pattern>;
    };

    inline constexpr _JoinWith join_with;
  } // namespace views
#endif // __cpp_lib_ranges_join_with

#ifdef __cpp_lib_ranges_repeat // C++ >= 23
  template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
    requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
      && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
  class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
  {
    [[no_unique_address]] __detail::__box<_Tp> _M_value;
    [[no_unique_address]] _Bound _M_bound = _Bound();

    class _Iterator;

    template<typename _Range>
    friend constexpr auto
    views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);

    template<typename _Range>
    friend constexpr auto
    views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);

  public:
    repeat_view() requires default_initializable<_Tp> = default;

    constexpr explicit
    repeat_view(const _Tp& __value, _Bound __bound = _Bound())
    requires copy_constructible<_Tp>
    : _M_value(__value), _M_bound(__bound)
    {
      if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
	__glibcxx_assert(__bound >= 0);
    }

    constexpr explicit
    repeat_view(_Tp&& __value, _Bound __bound = _Bound())
    : _M_value(std::move(__value)), _M_bound(__bound)
    { }

    template<typename... _Args, typename... _BoundArgs>
      requires constructible_from<_Tp, _Args...>
        && constructible_from<_Bound, _BoundArgs...>
    constexpr explicit
    repeat_view(piecewise_construct_t,
		tuple<_Args...> __args,
		tuple<_BoundArgs...> __bound_args = tuple<>{})
    : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
      _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
    { }

    constexpr _Iterator
    begin() const
    { return _Iterator(std::__addressof(*_M_value)); }

    constexpr _Iterator
    end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
    { return _Iterator(std::__addressof(*_M_value), _M_bound); }

    constexpr unreachable_sentinel_t
    end() const noexcept
    { return unreachable_sentinel; }

    constexpr auto
    size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
    { return __detail::__to_unsigned_like(_M_bound); }
  };

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 4053. Unary call to std::views::repeat does not decay the argument
  template<typename _Tp, typename _Bound = unreachable_sentinel_t>
    repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;

  template<move_constructible _Tp, semiregular _Bound>
    requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
      && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
  class repeat_view<_Tp, _Bound>::_Iterator
  {
    using __index_type
      = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;

    const _Tp* _M_value = nullptr;
    __index_type _M_current = __index_type();

    constexpr explicit
    _Iterator(const _Tp* __value, __index_type __bound = __index_type())
    : _M_value(__value), _M_current(__bound)
    {
      if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
	__glibcxx_assert(__bound >= 0);
    }

    friend repeat_view;

  public:
    using iterator_concept = random_access_iterator_tag;
    using iterator_category = random_access_iterator_tag;
    using value_type = _Tp;
    using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
					    __index_type,
					    __detail::__iota_diff_t<__index_type>>;

    _Iterator() = default;

    constexpr const _Tp&
    operator*() const noexcept
    { return *_M_value; }

    constexpr _Iterator&
    operator++()
    {
      ++_M_current;
      return *this;
    }

    constexpr _Iterator
    operator++(int)
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--()
    {
      if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
	__glibcxx_assert(_M_current > 0);
      --_M_current;
      return *this;
    }

    constexpr _Iterator
    operator--(int)
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __n)
    {
      if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
	__glibcxx_assert(_M_current + __n >= 0);
      _M_current += __n;
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __n)
    {
      if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
	__glibcxx_assert(_M_current - __n >= 0);
      _M_current -= __n;
      return *this;
    }

    constexpr const _Tp&
    operator[](difference_type __n) const noexcept
    { return *(*this + __n); }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
    { return __x._M_current == __y._M_current; }

    friend constexpr auto
    operator<=>(const _Iterator& __x, const _Iterator& __y)
    { return __x._M_current <=> __y._M_current; }

    friend constexpr _Iterator
    operator+(_Iterator __i, difference_type __n)
    {
      __i += __n;
      return __i;
    }

    friend constexpr _Iterator
    operator+(difference_type __n, _Iterator __i)
    { return __i + __n; }

    friend constexpr _Iterator
    operator-(_Iterator __i, difference_type __n)
    {
      __i -= __n;
      return __i;
    }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y)
    {
      return (static_cast<difference_type>(__x._M_current)
	      - static_cast<difference_type>(__y._M_current));
    }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename _Tp, typename _Bound>
	inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;

      template<typename _Tp>
	concept __can_repeat_view
	  = requires { repeat_view(std::declval<_Tp>()); };

      template<typename _Tp, typename _Bound>
	concept __can_bounded_repeat_view
	  = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
    }

    struct _Repeat
    {
      template<typename _Tp>
	requires __detail::__can_repeat_view<_Tp>
      constexpr auto
      operator() [[nodiscard]] (_Tp&& __value) const
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 4054. Repeating a repeat_view should repeat the view
	return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
      }

      template<typename _Tp, typename _Bound>
	requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
      constexpr auto
      operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
      { return repeat_view(std::forward<_Tp>(__value), __bound); }
    };

    inline constexpr _Repeat repeat;

    namespace __detail
    {
      template<typename _Range>
	constexpr auto
	__take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
	{
	  using _Tp = remove_cvref_t<_Range>;
	  static_assert(__is_repeat_view<_Tp>);
	  if constexpr (sized_range<_Tp>)
	    return views::repeat(*std::forward<_Range>(__r)._M_value,
				 std::min(ranges::distance(__r), __n));
	  else
	    return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
	}

      template<typename _Range>
	constexpr auto
	__drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
	{
	  using _Tp = remove_cvref_t<_Range>;
	  static_assert(__is_repeat_view<_Tp>);
	  if constexpr (sized_range<_Tp>)
	    {
	      auto __sz = ranges::distance(__r);
	      return views::repeat(*std::forward<_Range>(__r)._M_value,
				   __sz - std::min(__sz, __n));
	    }
	  else
	    return __r;
	}
    }
  }
#endif // __cpp_lib_ranges_repeat

#ifdef __cpp_lib_ranges_stride // C++ >= 23
  template<input_range _Vp>
    requires view<_Vp>
  class stride_view : public view_interface<stride_view<_Vp>>
  {
    _Vp _M_base;
    range_difference_t<_Vp> _M_stride;

    template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;

    template<bool _Const>
    struct __iter_cat
    { };

    template<bool _Const>
      requires forward_range<_Base<_Const>>
    struct __iter_cat<_Const>
    {
    private:
      static auto
      _S_iter_cat()
      {
	using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
	if constexpr (derived_from<_Cat, random_access_iterator_tag>)
	  return random_access_iterator_tag{};
	else
	  return _Cat{};
      }
    public:
      using iterator_category = decltype(_S_iter_cat());
    };

    template<bool> class _Iterator;

  public:
    constexpr explicit
    stride_view(_Vp __base, range_difference_t<_Vp> __stride)
    : _M_base(std::move(__base)), _M_stride(__stride)
    { __glibcxx_assert(__stride > 0); }

    constexpr _Vp
    base() const& requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr range_difference_t<_Vp>
    stride() const noexcept
    { return _M_stride; }

    constexpr auto
    begin() requires (!__detail::__simple_view<_Vp>)
    { return _Iterator<false>(this, ranges::begin(_M_base)); }

    constexpr auto
    begin() const requires range<const _Vp>
    { return _Iterator<true>(this, ranges::begin(_M_base)); }

    constexpr auto
    end() requires (!__detail::__simple_view<_Vp>)
    {
      if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
	{
	  auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
	  return _Iterator<false>(this, ranges::end(_M_base), __missing);
	}
      else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
	return _Iterator<false>(this, ranges::end(_M_base));
      else
        return default_sentinel;
    }

    constexpr auto
    end() const requires range<const _Vp>
    {
      if constexpr (common_range<const _Vp> && sized_range<const _Vp>
		    && forward_range<const _Vp>)
	{
	  auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
	  return _Iterator<true>(this, ranges::end(_M_base), __missing);
	}
      else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
        return _Iterator<true>(this, ranges::end(_M_base));
      else
        return default_sentinel;
    }

    constexpr auto
    size() requires sized_range<_Vp>
    {
      return __detail::__to_unsigned_like
	(__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
    }

    constexpr auto
    size() const requires sized_range<const _Vp>
    {
      return __detail::__to_unsigned_like
	(__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
    }
  };

  template<typename _Range>
    stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;

  template<typename _Vp>
    inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
      = enable_borrowed_range<_Vp>;

  template<input_range _Vp>
    requires view<_Vp>
  template<bool _Const>
  class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
  {
    using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
    using _Base = stride_view::_Base<_Const>;

    iterator_t<_Base> _M_current = iterator_t<_Base>();
    sentinel_t<_Base> _M_end = sentinel_t<_Base>();
    range_difference_t<_Base> _M_stride = 0;
    range_difference_t<_Base> _M_missing = 0;

    constexpr
    _Iterator(_Parent* __parent, iterator_t<_Base> __current,
	      range_difference_t<_Base> __missing = 0)
    : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
      _M_stride(__parent->_M_stride), _M_missing(__missing)
    { }

    static auto
    _S_iter_concept()
    {
      if constexpr (random_access_range<_Base>)
	return random_access_iterator_tag{};
      else if constexpr (bidirectional_range<_Base>)
	return bidirectional_iterator_tag{};
      else if constexpr (forward_range<_Base>)
	return forward_iterator_tag{};
      else
	return input_iterator_tag{};
    }

    friend stride_view;

  public:
    using difference_type = range_difference_t<_Base>;
    using value_type = range_value_t<_Base>;
    using iterator_concept = decltype(_S_iter_concept());
    // iterator_category defined in stride_view::__iter_cat

    _Iterator() requires default_initializable<iterator_t<_Base>> = default;

    constexpr
    _Iterator(_Iterator<!_Const> __other)
      requires _Const
	&& convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
	&& convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
     : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
       _M_stride(__other._M_stride), _M_missing(__other._M_missing)
     { }

    constexpr iterator_t<_Base>
    base() &&
    { return std::move(_M_current); }

    constexpr const iterator_t<_Base>&
    base() const & noexcept
    { return _M_current; }

    constexpr decltype(auto)
    operator*() const
    { return *_M_current; }

    constexpr _Iterator&
    operator++()
    {
      __glibcxx_assert(_M_current != _M_end);
      _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    constexpr _Iterator
    operator++(int) requires forward_range<_Base>
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--() requires bidirectional_range<_Base>
    {
      ranges::advance(_M_current, _M_missing - _M_stride);
      _M_missing = 0;
      return *this;
    }

    constexpr _Iterator
    operator--(int) requires bidirectional_range<_Base>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __n) requires random_access_range<_Base>
    {
      if (__n > 0)
	{
	  __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
	  _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
	}
      else if (__n < 0)
	{
	  ranges::advance(_M_current, _M_stride * __n + _M_missing);
	  _M_missing = 0;
	}
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __n) requires random_access_range<_Base>
    { return *this += -__n; }

    constexpr decltype(auto) operator[](difference_type __n) const
      requires random_access_range<_Base>
    { return *(*this + __n); }

    friend constexpr bool
    operator==(const _Iterator& __x, default_sentinel_t)
    { return __x._M_current == __x._M_end; }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
      requires equality_comparable<iterator_t<_Base>>
    { return __x._M_current == __y._M_current; }

    friend constexpr bool
    operator<(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __x._M_current < __y._M_current; }

    friend constexpr bool
    operator>(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return __y._M_current < __x._M_current; }

    friend constexpr bool
    operator<=(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return !(__y._M_current < __x._M_current); }

    friend constexpr bool
    operator>=(const _Iterator& __x, const _Iterator& __y)
      requires random_access_range<_Base>
    { return !(__x._M_current < __y._M_current); }

    friend constexpr auto
    operator<=>(const _Iterator& __x, const _Iterator& __y)
        requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
    { return __x._M_current <=> __y._M_current; }

    friend constexpr _Iterator
    operator+(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base>
    {
      auto __r = __i;
      __r += __n;
      return __r;
    }

    friend constexpr _Iterator
    operator+(difference_type __n, const _Iterator& __i)
      requires random_access_range<_Base>
    { return __i + __n; }

    friend constexpr _Iterator
    operator-(const _Iterator& __i, difference_type __n)
      requires random_access_range<_Base>
    {
      auto __r = __i;
      __r -= __n;
      return __r;
    }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y)
      requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
    {
      auto __n = __x._M_current - __y._M_current;
      if constexpr (forward_range<_Base>)
	return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
      else if (__n < 0)
	return -__detail::__div_ceil(-__n, __x._M_stride);
      else
	return __detail::__div_ceil(__n, __x._M_stride);
    }

    friend constexpr difference_type
    operator-(default_sentinel_t, const _Iterator& __x)
      requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
    { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }

    friend constexpr difference_type
    operator-(const _Iterator& __x, default_sentinel_t __y)
      requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
    { return -(__y - __x); }

    friend constexpr range_rvalue_reference_t<_Base>
    iter_move(const _Iterator& __i)
      noexcept(noexcept(ranges::iter_move(__i._M_current)))
    { return ranges::iter_move(__i._M_current); }

    friend constexpr void
    iter_swap(const _Iterator& __x, const _Iterator& __y)
      noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
      requires indirectly_swappable<iterator_t<_Base>>
    { ranges::iter_swap(__x._M_current, __y._M_current); }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Dp>
	concept __can_stride_view
	  = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
    }

    struct _Stride : __adaptor::_RangeAdaptor<_Stride>
    {
      template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
	requires __detail::__can_stride_view<_Range, _Dp>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
	{ return stride_view(std::forward<_Range>(__r), __n); }

      using __adaptor::_RangeAdaptor<_Stride>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _Stride stride;
  }
#endif // __cpp_lib_ranges_stride

#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
  namespace __detail
  {
    template<bool _Const, typename _First, typename... _Vs>
      concept __cartesian_product_is_random_access
	= (random_access_range<__maybe_const_t<_Const, _First>>
	   && ...
	   && (random_access_range<__maybe_const_t<_Const, _Vs>>
	       && sized_range<__maybe_const_t<_Const, _Vs>>));

    template<typename _Range>
      concept __cartesian_product_common_arg
	= common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);

    template<bool _Const, typename _First, typename... _Vs>
      concept __cartesian_product_is_bidirectional
	= (bidirectional_range<__maybe_const_t<_Const, _First>>
	   && ...
	   && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
	       && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));

    template<typename _First, typename... _Vs>
      concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;

    template<typename... _Vs>
      concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);

    template<bool _Const, template<typename> class _FirstSent,
	     typename _First, typename... _Vs>
      concept __cartesian_is_sized_sentinel
	= (sized_sentinel_for<_FirstSent<__maybe_const_t<_Const, _First>>,
			      iterator_t<__maybe_const_t<_Const, _First>>>
	   && ...
	   && (sized_range<__maybe_const_t<_Const, _Vs>>
	       && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
				     iterator_t<__maybe_const_t<_Const, _Vs>>>));

    template<__cartesian_product_common_arg _Range>
      constexpr auto
      __cartesian_common_arg_end(_Range& __r)
      {
	if constexpr (common_range<_Range>)
	  return ranges::end(__r);
	else
	  return ranges::begin(__r) + ranges::distance(__r);
      }
  } // namespace __detail

  template<input_range _First, forward_range... _Vs>
    requires (view<_First> && ... && view<_Vs>)
  class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
  {
    tuple<_First, _Vs...> _M_bases;

    template<bool> class _Iterator;

    static auto
    _S_difference_type()
    {
      // TODO: Implement the recommended practice of using the smallest
      // sufficiently wide type according to the maximum sizes of the
      // underlying ranges?
      return common_type_t<ptrdiff_t,
			   range_difference_t<_First>,
			   range_difference_t<_Vs>...>{};
    }

  public:
    cartesian_product_view() = default;

    constexpr explicit
    cartesian_product_view(_First __first, _Vs... __rest)
    : _M_bases(std::move(__first), std::move(__rest)...)
    { }

    constexpr _Iterator<false>
    begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
    { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }

    constexpr _Iterator<true>
    begin() const requires (range<const _First> && ... && range<const _Vs>)
    { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }

    constexpr _Iterator<false>
    end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
		    && __detail::__cartesian_product_is_common<_First, _Vs...>)
    {
      auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
	using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
	bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
	auto& __first = std::get<0>(_M_bases);
	return _Ret{(__empty_tail
		     ? ranges::begin(__first)
		     : __detail::__cartesian_common_arg_end(__first)),
		    ranges::begin(std::get<1 + _Is>(_M_bases))...};
      }(make_index_sequence<sizeof...(_Vs)>{});

      return _Iterator<false>{*this, std::move(__its)};
    }

    constexpr _Iterator<true>
    end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
    {
      auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
	using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
	bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
	auto& __first = std::get<0>(_M_bases);
	return _Ret{(__empty_tail
		     ? ranges::begin(__first)
		     : __detail::__cartesian_common_arg_end(__first)),
		    ranges::begin(std::get<1 + _Is>(_M_bases))...};
      }(make_index_sequence<sizeof...(_Vs)>{});

      return _Iterator<true>{*this, std::move(__its)};
    }

    constexpr default_sentinel_t
    end() const noexcept
    { return default_sentinel; }

    constexpr auto
    size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
    {
      using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
      return [&]<size_t... _Is>(index_sequence<_Is...>) {
	auto __size = static_cast<_ST>(1);
#ifdef _GLIBCXX_ASSERTIONS
	if constexpr (integral<_ST>)
	  {
	    bool __overflow
	      = (__builtin_mul_overflow(__size,
					static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
					&__size)
		 || ...);
	    __glibcxx_assert(!__overflow);
	  }
	else
#endif
	  __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
	return __size;
      }(make_index_sequence<1 + sizeof...(_Vs)>{});
    }

    constexpr auto
    size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
    {
      using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
      return [&]<size_t... _Is>(index_sequence<_Is...>) {
	auto __size = static_cast<_ST>(1);
#ifdef _GLIBCXX_ASSERTIONS
	if constexpr (integral<_ST>)
	  {
	    bool __overflow
	      = (__builtin_mul_overflow(__size,
					static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
					&__size)
		 || ...);
	    __glibcxx_assert(!__overflow);
	  }
	else
#endif
	  __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
	return __size;
      }(make_index_sequence<1 + sizeof...(_Vs)>{});
    }
  };

  template<typename... _Vs>
    cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;

  template<input_range _First, forward_range... _Vs>
    requires (view<_First> && ... && view<_Vs>)
  template<bool _Const>
  class cartesian_product_view<_First, _Vs...>::_Iterator
  {
    using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
    _Parent* _M_parent = nullptr;
    tuple<iterator_t<__maybe_const_t<_Const, _First>>,
	  iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;

    constexpr
    _Iterator(_Parent& __parent, decltype(_M_current) __current)
    : _M_parent(std::__addressof(__parent)),
      _M_current(std::move(__current))
    { }

    static auto
    _S_iter_concept()
    {
      if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
	return random_access_iterator_tag{};
      else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
	return bidirectional_iterator_tag{};
      else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
	return forward_iterator_tag{};
      else
	return input_iterator_tag{};
    }

    friend cartesian_product_view;

  public:
    using iterator_category = input_iterator_tag;
    using iterator_concept = decltype(_S_iter_concept());
    using value_type
      = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
	      range_value_t<__maybe_const_t<_Const, _Vs>>...>;
    using reference
      = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
	      range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
    using difference_type = decltype(cartesian_product_view::_S_difference_type());

    _Iterator() = default;

    constexpr
    _Iterator(_Iterator<!_Const> __i)
      requires _Const
	&& (convertible_to<iterator_t<_First>, iterator_t<const _First>>
	    && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
    : _M_parent(std::__addressof(__i._M_parent)),
      _M_current(std::move(__i._M_current))
    { }

    constexpr auto
    operator*() const
    {
      auto __f = [](auto& __i) -> decltype(auto) {
	return *__i;
      };
      return __detail::__tuple_transform(__f, _M_current);
    }

    constexpr _Iterator&
    operator++()
    {
      _M_next();
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    constexpr _Iterator
    operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--()
      requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
    {
      _M_prev();
      return *this;
    }

    constexpr _Iterator
    operator--(int)
      requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __x)
      requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
    {
      _M_advance(__x);
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __x)
      requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
    { return *this += -__x; }

    constexpr reference
    operator[](difference_type __n) const
      requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
    { return *((*this) + __n); }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
      requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
    { return __x._M_current == __y._M_current; }

    friend constexpr bool
    operator==(const _Iterator& __x, default_sentinel_t)
    {
      return [&]<size_t... _Is>(index_sequence<_Is...>) {
	return ((std::get<_Is>(__x._M_current)
		 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
		|| ...);
      }(make_index_sequence<1 + sizeof...(_Vs)>{});
    }

    friend constexpr auto
    operator<=>(const _Iterator& __x, const _Iterator& __y)
      requires __detail::__all_random_access<_Const, _First, _Vs...>
    { return __x._M_current <=> __y._M_current; }

    friend constexpr _Iterator
    operator+(_Iterator __x, difference_type __y)
      requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
    { return __x += __y; }

    friend constexpr _Iterator
    operator+(difference_type __x, _Iterator __y)
      requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
    { return __y += __x; }

    friend constexpr _Iterator
    operator-(_Iterator __x, difference_type __y)
      requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
    { return __x -= __y; }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y)
      requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
    { return __x._M_distance_from(__y._M_current); }

    friend constexpr difference_type
    operator-(const _Iterator& __i, default_sentinel_t)
      requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
    {
      tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
	return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
		     ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
      }(make_index_sequence<sizeof...(_Vs)>{});
      return __i._M_distance_from(__end_tuple);
    }

    friend constexpr difference_type
    operator-(default_sentinel_t, const _Iterator& __i)
      requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
    { return -(__i - default_sentinel); }

    friend constexpr auto
    iter_move(const _Iterator& __i)
    { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }

    friend constexpr void
    iter_swap(const _Iterator& __l, const _Iterator& __r)
      requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
		&& ...
		&& indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
    {
      [&]<size_t... _Is>(index_sequence<_Is...>) {
	(ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
      }(make_index_sequence<1 + sizeof...(_Vs)>{});
    }

  private:
    template<size_t _Nm = sizeof...(_Vs)>
    constexpr void
    _M_next()
    {
      auto& __it = std::get<_Nm>(_M_current);
      ++__it;
      if constexpr (_Nm > 0)
	if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
	  {
	    __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
	    _M_next<_Nm - 1>();
	  }
    }

    template<size_t _Nm = sizeof...(_Vs)>
    constexpr void
    _M_prev()
    {
      auto& __it = std::get<_Nm>(_M_current);
      if constexpr (_Nm > 0)
	if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
	  {
	    __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
	    _M_prev<_Nm - 1>();
	  }
      --__it;
    }

    template<size_t _Nm = sizeof...(_Vs)>
    constexpr void
    _M_advance(difference_type __x)
      requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
    {
      if (__x == 1)
	_M_next<_Nm>();
      else if (__x == -1)
	_M_prev<_Nm>();
      else if (__x != 0)
	{
	  // Constant time iterator advancement.
	  auto& __r = std::get<_Nm>(_M_parent->_M_bases);
	  auto& __it = std::get<_Nm>(_M_current);
	  if constexpr (_Nm == 0)
	    {
#ifdef _GLIBCXX_ASSERTIONS
	      if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
		{
		  auto __size = ranges::ssize(__r);
		  auto __begin = ranges::begin(__r);
		  auto __offset = __it - __begin;
		  __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
		}
#endif
	      __it += __x;
	    }
	  else
	    {
	      auto __size = ranges::ssize(__r);
	      auto __begin = ranges::begin(__r);
	      auto __offset = __it - __begin;
	      __offset += __x;
	      __x = __offset / __size;
	      __offset %= __size;
	      if (__offset < 0)
		{
		  __offset = __size + __offset;
		  --__x;
		}
	      __it = __begin + __offset;
	      _M_advance<_Nm - 1>(__x);
	    }
	}
    }

    template<typename _Tuple>
    constexpr difference_type
    _M_distance_from(const _Tuple& __t) const
    {
      return [&]<size_t... _Is>(index_sequence<_Is...>) {
	auto __sum = static_cast<difference_type>(0);
#ifdef _GLIBCXX_ASSERTIONS
	if constexpr (integral<difference_type>)
	  {
	    bool __overflow
	      = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
		 || ...);
	    __glibcxx_assert(!__overflow);
	  }
	else
#endif
	  __sum = (_M_scaled_distance<_Is>(__t) + ...);
	return __sum;
      }(make_index_sequence<1 + sizeof...(_Vs)>{});
    }

    template<size_t _Nm, typename _Tuple>
    constexpr difference_type
    _M_scaled_distance(const _Tuple& __t) const
    {
      auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
						 - std::get<_Nm>(__t));
#ifdef _GLIBCXX_ASSERTIONS
      if constexpr (integral<difference_type>)
	{
	  bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
	  __glibcxx_assert(!__overflow);
	}
      else
#endif
	__dist *= _M_scaled_size<_Nm+1>();
      return __dist;
    }

    template<size_t _Nm>
    constexpr difference_type
    _M_scaled_size() const
    {
      if constexpr (_Nm <= sizeof...(_Vs))
	{
	  auto __size = static_cast<difference_type>(ranges::size
						     (std::get<_Nm>(_M_parent->_M_bases)));
#ifdef _GLIBCXX_ASSERTIONS
	  if constexpr (integral<difference_type>)
	    {
	      bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
	      __glibcxx_assert(!__overflow);
	    }
	  else
#endif
	    __size *= _M_scaled_size<_Nm+1>();
	  return __size;
	}
      else
	return static_cast<difference_type>(1);
    }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename... _Ts>
	concept __can_cartesian_product_view
	  = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
    }

    struct _CartesianProduct
    {
      template<typename... _Ts>
	requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
	constexpr auto
	operator() [[nodiscard]] (_Ts&&... __ts) const
	{
	  if constexpr (sizeof...(_Ts) == 0)
	    return views::single(tuple{});
	  else
	    return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
	}
    };

    inline constexpr _CartesianProduct cartesian_product;
  }
#endif // __cpp_lib_ranges_cartesian_product

#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
  template<input_range _Vp>
    requires view<_Vp>
  class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
  {
    _Vp _M_base = _Vp();

  public:
    as_rvalue_view() requires default_initializable<_Vp> = default;

    constexpr explicit
    as_rvalue_view(_Vp __base)
    : _M_base(std::move(__base))
    { }

    constexpr _Vp
    base() const& requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr auto
    begin() requires (!__detail::__simple_view<_Vp>)
    { return move_iterator(ranges::begin(_M_base)); }

    constexpr auto
    begin() const requires range<const _Vp>
    { return move_iterator(ranges::begin(_M_base)); }

    constexpr auto
    end() requires (!__detail::__simple_view<_Vp>)
    {
      if constexpr (common_range<_Vp>)
	return move_iterator(ranges::end(_M_base));
      else
	return move_sentinel(ranges::end(_M_base));
    }

    constexpr auto
    end() const requires range<const _Vp>
    {
      if constexpr (common_range<const _Vp>)
	return move_iterator(ranges::end(_M_base));
      else
	return move_sentinel(ranges::end(_M_base));
    }

    constexpr auto
    size() requires sized_range<_Vp>
    { return ranges::size(_M_base); }

    constexpr auto
    size() const requires sized_range<const _Vp>
    { return ranges::size(_M_base); }
  };

  template<typename _Range>
    as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Tp>
	concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
    }

    struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
    {
      template<viewable_range _Range>
	requires __detail::__can_as_rvalue_view<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	{
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 4083. views::as_rvalue should reject non-input ranges
	  // input_range<_Range> is implied by __detail::__can_as_rvalue_view<_Range>
	  if constexpr (same_as<range_rvalue_reference_t<_Range>,
				range_reference_t<_Range>>)
	    return views::all(std::forward<_Range>(__r));
	  else
	    return as_rvalue_view(std::forward<_Range>(__r));
	}
    };

    inline constexpr _AsRvalue as_rvalue;
  }
#endif // __cpp_lib_as_rvalue

#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
  namespace __detail
  {
    template<typename _Range>
      concept __range_with_movable_reference = input_range<_Range>
	&& move_constructible<range_reference_t<_Range>>
	&& move_constructible<range_rvalue_reference_t<_Range>>;
  }

  template<view _Vp>
    requires __detail::__range_with_movable_reference<_Vp>
  class enumerate_view : public view_interface<enumerate_view<_Vp>>
  {
    _Vp _M_base = _Vp();

    template<bool _Const> class _Iterator;
    template<bool _Const> class _Sentinel;

  public:
    enumerate_view() requires default_initializable<_Vp> = default;

    constexpr explicit
    enumerate_view(_Vp __base)
    : _M_base(std::move(__base))
    { }

    constexpr auto
    begin() requires (!__detail::__simple_view<_Vp>)
    { return _Iterator<false>(ranges::begin(_M_base), 0); }

    constexpr auto
    begin() const requires __detail::__range_with_movable_reference<const _Vp>
    { return _Iterator<true>(ranges::begin(_M_base), 0); }

    constexpr auto
    end() requires (!__detail::__simple_view<_Vp>)
    {
      if constexpr (common_range<_Vp> && sized_range<_Vp>)
	return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
      else
	return _Sentinel<false>(ranges::end(_M_base));
    }

    constexpr auto
    end() const requires __detail::__range_with_movable_reference<const _Vp>
    {
      if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
	return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
      else
	return _Sentinel<true>(ranges::end(_M_base));
    }

    constexpr auto
    size() requires sized_range<_Vp>
    { return ranges::size(_M_base); }

    constexpr auto
    size() const requires sized_range<const _Vp>
    { return ranges::size(_M_base); }

    constexpr _Vp
    base() const & requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }
  };

  template<typename _Range>
    enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  template<view _Vp>
  requires __detail::__range_with_movable_reference<_Vp>
  template<bool _Const>
  class enumerate_view<_Vp>::_Iterator
  {
    using _Base = __maybe_const_t<_Const, _Vp>;

    static auto
    _S_iter_concept()
    {
      if constexpr (random_access_range<_Base>)
	return random_access_iterator_tag{};
      else if constexpr (bidirectional_range<_Base>)
	return bidirectional_iterator_tag{};
      else if constexpr (forward_range<_Base>)
	return forward_iterator_tag{};
      else
	return input_iterator_tag{};
    }

    friend enumerate_view;

  public:
    using iterator_category = input_iterator_tag;
    using iterator_concept = decltype(_S_iter_concept());
    using difference_type = range_difference_t<_Base>;
    using value_type = tuple<difference_type, range_value_t<_Base>>;

  private:
    using __reference_type = tuple<difference_type, range_reference_t<_Base>>;

    iterator_t<_Base> _M_current = iterator_t<_Base>();
    difference_type _M_pos = 0;

    constexpr explicit
    _Iterator(iterator_t<_Base> __current, difference_type __pos)
    : _M_current(std::move(__current)), _M_pos(__pos)
    { }

  public:
    _Iterator() requires default_initializable<iterator_t<_Base>> = default;

    constexpr
    _Iterator(_Iterator<!_Const> __i)
    requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
    : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
    { }

    constexpr const iterator_t<_Base> &
    base() const & noexcept
    { return _M_current; }

    constexpr iterator_t<_Base>
    base() &&
    { return std::move(_M_current); }

    constexpr difference_type
    index() const noexcept
    { return _M_pos; }

    constexpr auto
    operator*() const
    { return __reference_type(_M_pos, *_M_current); }

    constexpr _Iterator&
    operator++()
    {
      ++_M_current;
      ++_M_pos;
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    constexpr _Iterator
    operator++(int) requires forward_range<_Base>
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--() requires bidirectional_range<_Base>
    {
      --_M_current;
      --_M_pos;
      return *this;
    }

    constexpr _Iterator
    operator--(int) requires bidirectional_range<_Base>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __n) requires random_access_range<_Base>
    {
      _M_current += __n;
      _M_pos += __n;
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __n) requires random_access_range<_Base>
    {
      _M_current -= __n;
      _M_pos -= __n;
      return *this;
    }

    constexpr auto
    operator[](difference_type __n) const requires random_access_range<_Base>
    { return __reference_type(_M_pos + __n, _M_current[__n]); }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y) noexcept
    { return __x._M_pos == __y._M_pos; }

    friend constexpr strong_ordering
    operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
    { return __x._M_pos <=> __y._M_pos; }

    friend constexpr _Iterator
    operator+(const _Iterator& __x, difference_type __y)
    requires random_access_range<_Base>
    { return (auto(__x) += __y); }

    friend constexpr _Iterator
    operator+(difference_type __x, const _Iterator& __y)
    requires random_access_range<_Base>
    { return auto(__y) += __x; }

    friend constexpr _Iterator
    operator-(const _Iterator& __x, difference_type __y)
    requires random_access_range<_Base>
    { return auto(__x) -= __y; }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y) noexcept
    { return __x._M_pos - __y._M_pos; }

    friend constexpr auto
    iter_move(const _Iterator& __i)
    noexcept(noexcept(ranges::iter_move(__i._M_current))
	     && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
    {
      return tuple<difference_type, range_rvalue_reference_t<_Base>>
	(__i._M_pos, ranges::iter_move(__i._M_current));
    }
  };

  template<view _Vp>
  requires __detail::__range_with_movable_reference<_Vp>
  template<bool _Const>
  class enumerate_view<_Vp>::_Sentinel
  {
    using _Base = __maybe_const_t<_Const, _Vp>;

    sentinel_t<_Base> _M_end = sentinel_t<_Base>();

    constexpr explicit
    _Sentinel(sentinel_t<_Base> __end)
    : _M_end(std::move(__end))
    { }

    friend enumerate_view;

  public:
    _Sentinel() = default;

    constexpr
    _Sentinel(_Sentinel<!_Const> __other)
    requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
    : _M_end(std::move(__other._M_end))
    { }

    constexpr sentinel_t<_Base>
    base() const
    { return _M_end; }

    template<bool _OtherConst>
    requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
    friend constexpr bool
    operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    { return __x._M_current == __y._M_end; }

    template<bool _OtherConst>
    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
    friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
    operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
    { return __x._M_current - __y._M_end; }

    template<bool _OtherConst>
    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
    friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
    operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
    { return __x._M_end - __y._M_current; }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename _Tp>
	concept __can_enumerate_view
	  = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
    }

    struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
    {
      template<viewable_range _Range>
	requires __detail::__can_enumerate_view<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	{ return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
    };

    inline constexpr _Enumerate enumerate;
  }
#endif // __cpp_lib_ranges_enumerate

#ifdef __cpp_lib_ranges_as_const // C++ >= 23
  template<view _Vp>
    requires input_range<_Vp>
  class as_const_view : public view_interface<as_const_view<_Vp>>
  {
    _Vp _M_base = _Vp();

  public:
    as_const_view() requires default_initializable<_Vp> = default;

    constexpr explicit
    as_const_view(_Vp __base)
    noexcept(is_nothrow_move_constructible_v<_Vp>)
    : _M_base(std::move(__base))
    { }

    constexpr _Vp
    base() const &
    noexcept(is_nothrow_copy_constructible_v<_Vp>)
    requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    noexcept(is_nothrow_move_constructible_v<_Vp>)
    { return std::move(_M_base); }

    constexpr auto
    begin() requires (!__detail::__simple_view<_Vp>)
    { return ranges::cbegin(_M_base); }

    constexpr auto
    begin() const requires range<const _Vp>
    { return ranges::cbegin(_M_base); }

    constexpr auto
    end() requires (!__detail::__simple_view<_Vp>)
    { return ranges::cend(_M_base); }

    constexpr auto
    end() const requires range<const _Vp>
    { return ranges::cend(_M_base); }

    constexpr auto
    size() requires sized_range<_Vp>
    { return ranges::size(_M_base); }

    constexpr auto
    size() const requires sized_range<const _Vp>
    { return ranges::size(_M_base); }
  };

  template<typename _Range>
    as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Tp>
	inline constexpr bool __is_constable_ref_view = false;

      template<typename _Range>
	inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
	  = constant_range<const _Range>;

      template<typename _Range>
	concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
    }

    struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
    {
      template<viewable_range _Range>
      constexpr auto
      operator()(_Range&& __r) const
      noexcept(noexcept(as_const_view(std::declval<_Range>())))
      requires __detail::__can_as_const_view<_Range>
      {
	using _Tp = remove_cvref_t<_Range>;
	using element_type = remove_reference_t<range_reference_t<_Range>>;
	if constexpr (constant_range<views::all_t<_Range>>)
	  return views::all(std::forward<_Range>(__r));
	else if constexpr (__detail::__is_empty_view<_Tp>)
	  return views::empty<const element_type>;
#if __cpp_lib_optional >= 202506L && __cpp_lib_optional_range_support // >= C++26
	else if constexpr (__is_optional_ref_v<_Tp>)
	  return optional<const typename _Tp::value_type&>(__r);
#endif
	else if constexpr (std::__detail::__is_span<_Tp>)
	  return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
	else if constexpr (__detail::__is_constable_ref_view<_Tp>)
	  return ref_view(std::as_const(std::forward<_Range>(__r).base()));
	else if constexpr (is_lvalue_reference_v<_Range>
			   && constant_range<const _Tp>
			   && !view<_Tp>)
	  return ref_view(static_cast<const _Tp&>(__r));
	else
	  return as_const_view(std::forward<_Range>(__r));
      }
    };

    inline constexpr _AsConst as_const;
  }
#endif // __cpp_lib_as_const
} // namespace ranges

  namespace views = ranges::views;

#if __cpp_lib_ranges_to_container // C++ >= 23
namespace ranges
{
/// @cond undocumented
namespace __detail
{
  template<typename _Container>
    constexpr bool __reservable_container
      = sized_range<_Container>
      && requires(_Container& __c, range_size_t<_Container> __n) {
	__c.reserve(__n);
	{ __c.capacity() } -> same_as<decltype(__n)>;
	{ __c.max_size() } -> same_as<decltype(__n)>;
      };

  template<typename _Cont, typename _Range>
    constexpr bool __toable = requires {
      requires (!input_range<_Cont>
		  || convertible_to<range_reference_t<_Range>,
				    range_value_t<_Cont>>);
    };
} // namespace __detail
/// @endcond

  /// Convert a range to a container.
  /**
   * @tparam _Cont A container type.
   * @param __r A range that models the `input_range` concept.
   * @param __args... Arguments to pass to the container constructor.
   * @since C++23
   *
   * This function converts a range to the `_Cont` type.
   *
   * For example, `std::ranges::to<std::vector<int>>(some_view)`
   * will convert the view to `std::vector<int>`.
   *
   * Additional constructor arguments for the container can be supplied after
   * the input range argument, e.g.
   * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
   */
  template<typename _Cont, input_range _Rg, typename... _Args>
    requires (!view<_Cont>)
    constexpr _Cont
    to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
    {
      static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
      static_assert(is_class_v<_Cont> || is_union_v<_Cont>);

      if constexpr (__detail::__toable<_Cont, _Rg>)
	{
	  if constexpr (constructible_from<_Cont, _Rg, _Args...>)
	    return _Cont(std::forward<_Rg>(__r),
			 std::forward<_Args>(__args)...);
	  else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
	    return _Cont(from_range, std::forward<_Rg>(__r),
			 std::forward<_Args>(__args)...);
	  else if constexpr (requires { requires common_range<_Rg>;
		typename __iter_category_t<iterator_t<_Rg>>;
		requires derived_from<__iter_category_t<iterator_t<_Rg>>,
				      input_iterator_tag>;
		requires constructible_from<_Cont, iterator_t<_Rg>,
					    sentinel_t<_Rg>, _Args...>;
	      })
	    return _Cont(ranges::begin(__r), ranges::end(__r),
			 std::forward<_Args>(__args)...);
	  else
	    {
	      static_assert(constructible_from<_Cont, _Args...>);
	      _Cont __c(std::forward<_Args>(__args)...);
	      if constexpr (sized_range<_Rg>
			      && __detail::__reservable_container<_Cont>)
		__c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
	      // 4016. container-insertable checks do not match what
	      // container-inserter does
	      auto __it = ranges::begin(__r);
	      const auto __sent = ranges::end(__r);
	      while (__it != __sent)
		{
		  if constexpr (requires { __c.emplace_back(*__it); })
		    __c.emplace_back(*__it);
		  else if constexpr (requires { __c.push_back(*__it); })
		    __c.push_back(*__it);
		  else if constexpr (requires { __c.emplace(__c.end(), *__it); })
		    __c.emplace(__c.end(), *__it);
		  else
		    __c.insert(__c.end(), *__it);
		  ++__it;
		}
	      return __c;
	    }
	}
      else
	{
	  static_assert(input_range<range_reference_t<_Rg>>);
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3984. ranges::to's recursion branch may be ill-formed
	  return ranges::to<_Cont>(ref_view(__r) | views::transform(
		[]<typename _Elt>(_Elt&& __elem) {
		  using _ValT = range_value_t<_Cont>;
		  return ranges::to<_ValT>(std::forward<_Elt>(__elem));
		}), std::forward<_Args>(__args)...);
	}
    }

/// @cond undocumented
namespace __detail
{
  template<typename _Rg>
    struct _InputIter
    {
      using iterator_category = input_iterator_tag;
      using value_type = range_value_t<_Rg>;
      using difference_type = ptrdiff_t;
      using pointer = add_pointer_t<range_reference_t<_Rg>>;
      using reference = range_reference_t<_Rg>;
      reference operator*() const;
      pointer operator->() const;
      _InputIter& operator++();
      _InputIter operator++(int);
      bool operator==(const _InputIter&) const;
    };

  template<template<typename...> typename _Cont, input_range _Rg,
	   typename... _Args>
    using _DeduceExpr1
      = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));

  template<template<typename...> typename _Cont, input_range _Rg,
	   typename... _Args>
    using _DeduceExpr2
      = decltype(_Cont(from_range, std::declval<_Rg>(),
		       std::declval<_Args>()...));

  template<template<typename...> typename _Cont, input_range _Rg,
	   typename... _Args>
    using _DeduceExpr3
      = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
		       std::declval<_InputIter<_Rg>>(),
		       std::declval<_Args>()...));

} // namespace __detail
/// @endcond

  template<template<typename...> typename _Cont, input_range _Rg,
	   typename... _Args>
    constexpr auto
    to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
    {
      using __detail::_DeduceExpr1;
      using __detail::_DeduceExpr2;
      using __detail::_DeduceExpr3;
      if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
	return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
	    std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
      else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
	return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
	    std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
      else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
	return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
	    std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
      else
	static_assert(false); // Cannot deduce container specialization.
    }

/// @cond undocumented
namespace __detail
{
  template<typename _Cont>
    struct _To
    {
      template<typename _Range, typename... _Args>
	requires requires { ranges::to<_Cont>(std::declval<_Range>(),
					      std::declval<_Args>()...); }
	constexpr auto
	operator()(_Range&& __r, _Args&&... __args) const
	{
	  return ranges::to<_Cont>(std::forward<_Range>(__r),
				   std::forward<_Args>(__args)...);
	}
    };
} // namespace __detail
/// @endcond

  /// ranges::to adaptor for converting a range to a container type
  /**
   * @tparam _Cont A container type.
   * @param __args... Arguments to pass to the container constructor.
   * @since C++23
   *
   * This range adaptor returns a range adaptor closure object that converts
   * a range to the `_Cont` type.
   *
   * For example, `some_view | std::ranges::to<std::vector<int>>()`
   * will convert the view to `std::vector<int>`.
   *
   * Additional constructor arguments for the container can be supplied, e.g.
   * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
   */
  template<typename _Cont, typename... _Args>
    requires (!view<_Cont>)
    constexpr auto
    to [[nodiscard]] (_Args&&... __args)
    {
      static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
      static_assert(is_class_v<_Cont> || is_union_v<_Cont>);

      using __detail::_To;
      using views::__adaptor::_Partial;
      return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
    }

/// @cond undocumented
namespace __detail
{
  template<template<typename...> typename _Cont>
    struct _To2
    {
      template<typename _Range, typename... _Args>
	requires requires { ranges::to<_Cont>(std::declval<_Range>(),
					      std::declval<_Args>()...); }
	constexpr auto
	operator()(_Range&& __r, _Args&&... __args) const
	{
	  return ranges::to<_Cont>(std::forward<_Range>(__r),
				   std::forward<_Args>(__args)...);
	}
    };
} // namespace __detail
/// @endcond

  /// ranges::to adaptor for converting a range to a deduced container type.
  /**
   * @tparam _Cont A container template.
   * @param __args... Arguments to pass to the container constructor.
   * @since C++23
   *
   * This range adaptor returns a range adaptor closure object that converts
   * a range to a specialization of the `_Cont` class template. The specific
   * specialization of `_Cont` to be used is deduced automatically.
   *
   * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
   * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
   * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
   *
   * Additional constructor arguments for the container can be supplied, e.g.
   * `r | std::ranges::to<std::vector>(an_allocator)`.
   */
  template<template<typename...> typename _Cont, typename... _Args>
    constexpr auto
    to [[nodiscard]] (_Args&&... __args)
    {
      using __detail::_To2;
      using views::__adaptor::_Partial;
      return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
    }

} // namespace ranges
#endif // __cpp_lib_ranges_to_container

#if __cpp_lib_ranges_concat // C++ >= C++26
namespace ranges
{
  namespace __detail
  {
    template<typename... _Rs>
      using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;

    template<typename... _Rs>
      using __concat_value_t = common_type_t<range_value_t<_Rs>...>;

    template<typename... _Rs>
      using __concat_rvalue_reference_t
	= common_reference_t<range_rvalue_reference_t<_Rs>...>;

    template<typename _Ref, typename _RRef, typename _It>
      concept __concat_indirectly_readable_impl = requires(const _It __it) {
	{ *__it } -> convertible_to<_Ref>;
	{ ranges::iter_move(__it) } -> convertible_to<_RRef>;
      };

    template<typename... _Rs>
      concept __concat_indirectly_readable
	= common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
	  && common_reference_with<__concat_reference_t<_Rs...>&&,
				   __concat_rvalue_reference_t<_Rs...>&&>
	  && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
				   __concat_value_t<_Rs...> const&>
	  && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
						__concat_rvalue_reference_t<_Rs...>,
						iterator_t<_Rs>>
	      && ...);

    template<typename... _Rs>
      concept __concatable = requires {
	typename __concat_reference_t<_Rs...>;
	typename __concat_value_t<_Rs...>;
	typename __concat_rvalue_reference_t<_Rs...>;
      } && __concat_indirectly_readable<_Rs...>;

    template<bool _Const, typename _Range, typename... _Rs>
      struct __all_but_last_common
      {
	static inline constexpr bool value
	  = requires { requires (common_range<__maybe_const_t<_Const, _Range>>
				 && __all_but_last_common<_Const, _Rs...>::value); };
      };

    template<bool _Const, typename _Range>
      struct __all_but_last_common<_Const, _Range>
      { static inline constexpr bool value = true; };

    template<bool _Const, typename... _Rs>
      concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
	&& __all_but_last_common<_Const, _Rs...>::value;

    template<bool _Const, typename... _Rs>
      concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
	&& __all_but_last_common<_Const, _Rs...>::value;

    template<typename _Range, typename... _Rs>
      struct __all_but_first_sized
      { static inline constexpr bool value = (sized_range<_Rs> && ...); };
  } // namespace __detail

  template<input_range... _Vs>
    requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
  class concat_view : public view_interface<concat_view<_Vs...>>
  {
    tuple<_Vs...> _M_views;

    template<bool _Const> class _Iterator;

  public:
    constexpr concat_view() = default;

    constexpr explicit
    concat_view(_Vs... __views)
    : _M_views(std::move(__views)...)
    { }

    constexpr _Iterator<false>
    begin() requires (!(__detail::__simple_view<_Vs> && ...))
    {
      _Iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
      __it.template _M_satisfy<0>();
      return __it;
    }

    constexpr _Iterator<true>
    begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
    {
      _Iterator<true> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
      __it.template _M_satisfy<0>();
      return __it;
    }

    constexpr auto
    end() requires (!(__detail::__simple_view<_Vs> && ...))
    {
      constexpr auto __n = sizeof...(_Vs);
      if constexpr (__detail::__all_forward<false, _Vs...>
		    && common_range<_Vs...[__n - 1]>)
	return _Iterator<false>(this, in_place_index<__n - 1>,
				ranges::end(std::get<__n - 1>(_M_views)));
      else
	return default_sentinel;
    }

    constexpr auto
    end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
    {
      constexpr auto __n = sizeof...(_Vs);
      if constexpr (__detail::__all_forward<true, _Vs...>
		    && common_range<const _Vs...[__n - 1]>)
	return _Iterator<true>(this, in_place_index<__n - 1>,
			       ranges::end(std::get<__n - 1>(_M_views)));
      else
	return default_sentinel;
    }

    constexpr auto
    size() requires (sized_range<_Vs>&&...)
    {
      return std::apply([](auto... __sizes) {
	using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
	return (_CT(__sizes) + ...);
      }, __detail::__tuple_transform(ranges::size, _M_views));
    }

    constexpr auto
    size() const requires (sized_range<const _Vs>&&...)
    {
      return std::apply([](auto... __sizes) {
	using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
	return (_CT(__sizes) + ...);
      }, __detail::__tuple_transform(ranges::size, _M_views));
    }
  };

  template<typename... _Rs>
    concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;

  namespace __detail
  {
    template<bool _Const, typename... _Vs>
      struct __concat_view_iter_cat
      { };

    template<bool _Const, typename... _Vs>
      requires __detail::__all_forward<_Const, _Vs...>
      struct __concat_view_iter_cat<_Const, _Vs...>
      {
	static auto
	_S_iter_cat()
	{
	  if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
	    return input_iterator_tag{};
	  else
	    return []<typename... _Cats>(_Cats... __cats) {
	      if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
			    && __concat_is_random_access<_Const, _Vs...>)
		return random_access_iterator_tag{};
	      else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
				 && __concat_is_bidirectional<_Const, _Vs...>)
		return bidirectional_iterator_tag{};
	      else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
		return forward_iterator_tag{};
	      else
		return input_iterator_tag{};
	    }(typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
	      ::iterator_category{}...);
	}
      };
  }

  template<input_range... _Vs>
    requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
  template<bool _Const>
  class concat_view<_Vs...>::_Iterator
  : public __detail::__concat_view_iter_cat<_Const, _Vs...>
  {
    static auto
    _S_iter_concept()
    {
      if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
	return random_access_iterator_tag{};
      else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
	return bidirectional_iterator_tag{};
      else if constexpr (__detail::__all_forward<_Const, _Vs...>)
	return forward_iterator_tag{};
      else
	return input_iterator_tag{};
    }

    friend concat_view;
    friend _Iterator<!_Const>;

  public:
    // iterator_category defined in __concat_view_iter_cat
    using iterator_concept = decltype(_S_iter_concept());
    using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
    using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;

  private:
    using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;

    __maybe_const_t<_Const, concat_view>* _M_parent = nullptr;
    __base_iter _M_it;

    template<size_t _Nm>
      constexpr void
      _M_satisfy()
      {
	if constexpr (_Nm < (sizeof...(_Vs) - 1))
	  {
	    if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
	      {
		_M_it.template emplace<_Nm + 1>(ranges::begin
						(std::get<_Nm + 1>(_M_parent->_M_views)));
		_M_satisfy<_Nm + 1>();
	      }
	  }
      }

    template<size_t _Nm>
      constexpr void
      _M_prev()
      {
	if constexpr (_Nm == 0)
	  --std::get<0>(_M_it);
	else
	  {
	    if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
	      {
		_M_it.template emplace<_Nm - 1>(ranges::end
						(std::get<_Nm - 1>(_M_parent->_M_views)));
		_M_prev<_Nm - 1>();
	      }
	    else
	      --std::get<_Nm>(_M_it);
	  }
      }

    template<size_t _Nm>
      constexpr void
      _M_advance_fwd(difference_type __offset, difference_type __steps)
      {
	using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
	if constexpr (_Nm == sizeof...(_Vs) - 1)
	  std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
	else
	  {
	    auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
	    if (__offset + __steps < __n_size)
		std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
	    else
	      {
		_M_it.template emplace<_Nm + 1>(ranges::begin
						(std::get<_Nm + 1>(_M_parent->_M_views)));
		_M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
	      }
	  }
      }

    template<size_t _Nm>
      constexpr void
      _M_advance_bwd(difference_type __offset, difference_type __steps)
      {
	using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
	if constexpr (_Nm == 0)
	  std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
	else {
	    if (__offset >= __steps)
	      std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
	    else
	      {
		auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
		_M_it.template emplace<_Nm - 1>(ranges::end
						(std::get<_Nm - 1>(_M_parent->_M_views)));
		_M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
	      }
	}
      }

    // Invoke the function object __f, which has a call operator with a size_t
    // template parameter (corresponding to an index into the pack of views),
    // using the runtime value of __index as the template argument.
    template<typename _Fp>
      static constexpr auto
      _S_invoke_with_runtime_index(_Fp&& __f, size_t __index)
      {
	return [&__f, __index]<size_t _Idx>(this auto&& __self) {
	  if (_Idx == __index)
	    return __f.template operator()<_Idx>();
	  if constexpr (_Idx + 1 < sizeof...(_Vs))
	    return __self.template operator()<_Idx + 1>();
	  __builtin_unreachable();
	}.template operator()<0>();
      }

    template<typename _Fp>
      constexpr auto
      _M_invoke_with_runtime_index(_Fp&& __f)
      { return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); }

    template<typename... _Args>
      explicit constexpr
      _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
	requires constructible_from<__base_iter, _Args&&...>
      : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...)
      { }

  public:
    _Iterator() = default;

    constexpr
    _Iterator(_Iterator<!_Const> __it)
      requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
    : _M_parent(__it._M_parent),
      _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
	      return __base_iter(in_place_index<_Idx>,
				 std::get<_Idx>(std::move(__it._M_it)));
	    }, __it._M_it.index()))
    { }

    constexpr decltype(auto)
    operator*() const
    {
      __glibcxx_assert(!_M_it.valueless_by_exception());
      using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
      return std::visit([](auto&& __it) -> reference { return *__it; }, _M_it);
    }

    constexpr _Iterator&
    operator++()
    {
      _M_invoke_with_runtime_index([this]<size_t _Idx>() {
	++std::get<_Idx>(_M_it);
	_M_satisfy<_Idx>();
      });
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    constexpr _Iterator
    operator++(int)
      requires __detail::__all_forward<_Const, _Vs...>
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator--()
      requires __detail::__concat_is_bidirectional<_Const, _Vs...>
    {
      __glibcxx_assert(!_M_it.valueless_by_exception());
      _M_invoke_with_runtime_index([this]<size_t _Idx>() {
	_M_prev<_Idx>();
      });
      return *this;
    }

    constexpr _Iterator
    operator--(int)
      requires __detail::__concat_is_bidirectional<_Const, _Vs...>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr _Iterator&
    operator+=(difference_type __n)
      requires __detail::__concat_is_random_access<_Const, _Vs...>
    {
      __glibcxx_assert(!_M_it.valueless_by_exception());
      _M_invoke_with_runtime_index([this, __n]<size_t _Idx>() {
	auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
	if (__n > 0)
	  _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
	else if (__n < 0)
	  _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
      });
      return *this;
    }

    constexpr _Iterator&
    operator-=(difference_type __n)
      requires __detail::__concat_is_random_access<_Const, _Vs...>
    {
      *this += -__n;
      return *this;
    }

    constexpr decltype(auto)
    operator[](difference_type __n) const
      requires __detail::__concat_is_random_access<_Const, _Vs...>
    { return *((*this) + __n); }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Iterator& __y)
      requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
    {
      __glibcxx_assert(!__x._M_it.valueless_by_exception());
      __glibcxx_assert(!__y._M_it.valueless_by_exception());
      return __x._M_it == __y._M_it;
    }

    friend constexpr bool
    operator==(const _Iterator& __it, default_sentinel_t)
    {
      __glibcxx_assert(!__it._M_it.valueless_by_exception());
      constexpr auto __last_idx = sizeof...(_Vs) - 1;
      return (__it._M_it.index() == __last_idx
	      && (std::get<__last_idx>(__it._M_it)
		  == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
    }

    friend constexpr bool
    operator<(const _Iterator& __x, const _Iterator& __y)
      requires __detail::__all_random_access<_Const, _Vs...>
    { return __x._M_it < __y._M_it; }

    friend constexpr bool
    operator>(const _Iterator& __x, const _Iterator& __y)
      requires __detail::__all_random_access<_Const, _Vs...>
    { return __x._M_it > __y._M_it; }

    friend constexpr bool
    operator<=(const _Iterator& __x, const _Iterator& __y)
      requires __detail::__all_random_access<_Const, _Vs...>
    { return __x._M_it <= __y._M_it; }

    friend constexpr bool
    operator>=(const _Iterator& __x, const _Iterator& __y)
      requires __detail::__all_random_access<_Const, _Vs...>
    { return __x._M_it >= __y._M_it; }

    friend constexpr auto
    operator<=>(const _Iterator& __x, const _Iterator& __y)
      requires __detail::__all_random_access<_Const, _Vs...>
	&& (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
    { return __x._M_it <=> __y._M_it; }

    friend constexpr _Iterator
    operator+(const _Iterator& __it, difference_type __n)
      requires __detail::__concat_is_random_access<_Const, _Vs...>
    { return auto(__it) += __n; }

    friend constexpr _Iterator
    operator+(difference_type __n, const _Iterator& __it)
      requires __detail::__concat_is_random_access<_Const, _Vs...>
    { return __it + __n; }

    friend constexpr _Iterator
    operator-(const _Iterator& __it, difference_type __n)
      requires __detail::__concat_is_random_access<_Const, _Vs...>
    { return auto(__it) -= __n; }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const _Iterator& __y)
      requires __detail::__concat_is_random_access<_Const, _Vs...>
    {
      return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
        return _S_invoke_with_runtime_index([&]<size_t _Iy>() -> difference_type {
	  if constexpr (_Ix > _Iy)
	    {
	      auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
					   ranges::end(std::get<_Iy>(__y._M_parent
								     ->_M_views)));
	      auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
								       ->_M_views)),
					   std::get<_Ix>(__x._M_it));
	      difference_type __s = 0;
	      [&]<size_t _Idx = _Iy + 1>(this auto&& __self) {
	        if constexpr (_Idx < _Ix)
		  {
		    __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
		    __self.template operator()<_Idx + 1>();
		  }
	      }();
	      return __dy + __s + __dx;
	    }
	  else if constexpr (_Ix < _Iy)
	    return -(__y - __x);
	  else
	    return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
	}, __y._M_it.index());
      }, __x._M_it.index());
    }

    friend constexpr difference_type
    operator-(const _Iterator& __x, default_sentinel_t)
      requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
				   iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
	&& __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
    {
      return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
	auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
				     ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
	difference_type __s = 0;
	[&]<size_t _Idx = _Ix + 1>(this auto&& __self) {
	  if constexpr (_Idx < sizeof...(_Vs))
	    {
	      __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
	      __self.template operator()<_Idx + 1>();
	    }
	}();
	return -(__dx + __s);
      }, __x._M_it.index());
    }

    friend constexpr difference_type
    operator-(default_sentinel_t, const _Iterator& __x)
      requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
				   iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
	&& __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
    { return -(__x - default_sentinel); }

    friend constexpr decltype(auto)
    iter_move(const _Iterator& __it)
    {
      using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
      return std::visit([](const auto& __i) -> _Res {
	return ranges::iter_move(__i);
      }, __it._M_it);
    }

    friend constexpr void
    iter_swap(const _Iterator& __x, const _Iterator& __y)
      requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
	&& (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
    {
      std::visit([&]<typename _Tp, typename _Up>(const _Tp& __it1, const _Up& __it2) {
	if constexpr (is_same_v<_Tp, _Up>)
	  ranges::iter_swap(__it1, __it2);
	else
	  ranges::swap(*__it1, *__it2);
      }, __x._M_it, __y._M_it);
    }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename... _Ts>
	concept __can_concat_view = requires { concat_view(std::declval<_Ts>()...); };
    }

    struct _Concat
    {
      template<typename... _Ts>
	requires __detail::__can_concat_view<_Ts...>
      constexpr auto
      operator() [[nodiscard]] (_Ts&&... __ts) const
      { return concat_view(std::forward<_Ts>(__ts)...); }

      template<input_range _Range>
      constexpr auto
      operator() [[nodiscard]] (_Range&& __t) const
      { return views::all(std::forward<_Range>(__t)); }
    };

    inline constexpr _Concat concat;
  }

} // namespace ranges
#endif // __cpp_lib_ranges_concat

#if __cpp_lib_ranges_cache_latest // C++ >= 26
namespace ranges
{
  template<input_range _Vp>
    requires view<_Vp>
  class cache_latest_view : public view_interface<cache_latest_view<_Vp>>
  {
    _Vp _M_base = _Vp();

    using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
				      add_pointer_t<range_reference_t<_Vp>>,
				      range_reference_t<_Vp>>;
    __detail::__non_propagating_cache<__cache_t> _M_cache;

    class _Iterator;
    class _Sentinel;

  public:
    cache_latest_view() requires default_initializable<_Vp> = default;

    constexpr explicit
    cache_latest_view(_Vp __base)
    : _M_base(std::move(__base))
    { }

    constexpr _Vp
    base() const & requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr auto
    begin()
    { return _Iterator(*this); }

    constexpr auto
    end()
    { return _Sentinel(*this); }

    constexpr auto
    size() requires sized_range<_Vp>
    { return ranges::size(_M_base); }

    constexpr auto
    size() const requires sized_range<const _Vp>
    { return ranges::size(_M_base); }
  };

  template<typename _Range>
    cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;

  template<input_range _Vp>
    requires view<_Vp>
  class cache_latest_view<_Vp>::_Iterator
  {
    cache_latest_view* _M_parent;
    iterator_t<_Vp> _M_current;

    constexpr explicit
    _Iterator(cache_latest_view& __parent)
    : _M_parent(std::__addressof(__parent)),
      _M_current(ranges::begin(__parent._M_base))
    { }

    friend class cache_latest_view;

  public:
    using difference_type = range_difference_t<_Vp>;
    using value_type = range_value_t<_Vp>;
    using iterator_concept = input_iterator_tag;

    _Iterator(_Iterator&&) = default;

    _Iterator&
    operator=(_Iterator&&) = default;

    constexpr iterator_t<_Vp>
    base() &&
    { return std::move(_M_current); }

    constexpr const iterator_t<_Vp>&
    base() const & noexcept
    { return _M_current; }

    constexpr range_reference_t<_Vp>&
    operator*() const
    {
      if constexpr (is_reference_v<range_reference_t<_Vp>>)
	{
	  if (!_M_parent->_M_cache)
	    _M_parent->_M_cache = std::__addressof(__detail::__as_lvalue(*_M_current));
	  return **_M_parent->_M_cache;
	}
      else
	{
	  if (!_M_parent->_M_cache)
	    _M_parent->_M_cache._M_emplace_deref(_M_current);
	  return *_M_parent->_M_cache;
	}
    }

    constexpr _Iterator&
    operator++()
    {
      _M_parent->_M_cache._M_reset();
      ++_M_current;
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    friend constexpr range_rvalue_reference_t<_Vp>
    iter_move(const _Iterator& __i)
      noexcept(noexcept(ranges::iter_move(__i._M_current)))
    { return ranges::iter_move(__i._M_current); }

    friend constexpr void
    iter_swap(const _Iterator& __x, const _Iterator& __y)
      noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
      requires indirectly_swappable<iterator_t<_Vp>>
    { ranges::iter_swap(__x._M_current, __y._M_current); }
  };

  template<input_range _Vp>
    requires view<_Vp>
  class cache_latest_view<_Vp>::_Sentinel
  {
    sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();

    constexpr explicit
    _Sentinel(cache_latest_view& __parent)
    : _M_end(ranges::end(__parent._M_base))
    { }

    friend class cache_latest_view;

  public:
    _Sentinel() = default;

    constexpr sentinel_t<_Vp>
    base() const
    { return _M_end; }

    friend constexpr bool
    operator==(const _Iterator& __x, const _Sentinel& __y)
    { return __x._M_current == __y._M_end; }

    friend constexpr range_difference_t<_Vp>
    operator-(const _Iterator& __x, const _Sentinel& __y)
      requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
    { return __x._M_current - __y._M_end; }

    friend constexpr range_difference_t<_Vp>
    operator-(const _Sentinel& __x, const _Iterator& __y)
      requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
    { return __x._M_end - __y._M_current; }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename _Tp>
	concept __can_cache_latest = requires { cache_latest_view(std::declval<_Tp>()); };
    }

    struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
    {
      template<viewable_range _Range>
	requires __detail::__can_cache_latest<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	{ return cache_latest_view(std::forward<_Range>(__r)); }

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _CacheLatest cache_latest;
  }
} // namespace ranges
#endif // __cpp_lib_ranges_cache_latest

#if __cpp_lib_ranges_as_input // C++ >= 26
namespace ranges
{
  template<input_range _Vp>
    requires view<_Vp>
  class as_input_view : public view_interface<as_input_view<_Vp>>
  {
    _Vp _M_base = _Vp();

    template<bool _Const>
    class _Iterator;

  public:
    as_input_view() requires default_initializable<_Vp> = default;

    constexpr explicit
    as_input_view(_Vp __base)
    : _M_base(std::move(__base))
    { }

    constexpr _Vp
    base() const & requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr auto
    begin() requires (!__detail::__simple_view<_Vp>)
    { return _Iterator<false>(ranges::begin(_M_base)); }

    constexpr auto
    begin() const requires range<const _Vp>
    { return _Iterator<true>(ranges::begin(_M_base)); }

    constexpr auto
    end() requires (!__detail::__simple_view<_Vp>)
    { return ranges::end(_M_base); }

    constexpr auto
    end() const requires range<const _Vp>
    { return ranges::end(_M_base); }

    constexpr auto
    size() requires sized_range<_Vp>
    { return ranges::size(_M_base); }

    constexpr auto
    size() const requires sized_range<const _Vp>
    { return ranges::size(_M_base); }
  };

  template<typename _Range>
    as_input_view(_Range&&) -> as_input_view<views::all_t<_Range>>;

  template<input_range _Vp>
    requires view<_Vp>
  template<bool _Const>
  class as_input_view<_Vp>::_Iterator
  {
    using _Base = __maybe_const_t<_Const, _Vp>;

    iterator_t<_Base> _M_current = iterator_t<_Base>();

    constexpr explicit
    _Iterator(iterator_t<_Base> __current)
    : _M_current(std::move(__current))
    { }

    friend as_input_view;
    friend _Iterator<!_Const>;

  public:
    using difference_type = range_difference_t<_Base>;
    using value_type = range_value_t<_Base>;
    using iterator_concept = input_iterator_tag;

    _Iterator() requires default_initializable<iterator_t<_Base>> = default;

    _Iterator(_Iterator&&) = default;
    _Iterator& operator=(_Iterator&&) = default;

    constexpr
    _Iterator(_Iterator<!_Const> __i)
      requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
    : _M_current(std::move(__i._M_current))
    { }

    constexpr iterator_t<_Base>
    base() &&
    { return std::move(_M_current); }

    constexpr const iterator_t<_Base>&
    base() const & noexcept
    { return _M_current; }

    constexpr decltype(auto)
    operator*() const
    { return *_M_current; }

    constexpr _Iterator&
    operator++()
    {
      ++_M_current;
      return *this;
    }

    constexpr void
    operator++(int)
    { ++*this; }

    friend constexpr bool
    operator==(const _Iterator& __x, const sentinel_t<_Base>& __y)
    { return __x._M_current == __y; }

    friend constexpr difference_type
    operator-(const sentinel_t<_Base>& __y, const _Iterator& __x)
      requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
    { return __y - __x._M_current; }

    friend constexpr difference_type
    operator-(const _Iterator& __x, const sentinel_t<_Base>& __y)
      requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
    { return __x._M_current - __y; }

    friend constexpr range_rvalue_reference_t<_Base>
    iter_move(const _Iterator& __i)
      noexcept(noexcept(ranges::iter_move(__i._M_current)))
    { return ranges::iter_move(__i._M_current); }

    friend constexpr void
    iter_swap(const _Iterator& __x, const _Iterator& __y)
      noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
      requires indirectly_swappable<iterator_t<_Base>>
    { ranges::iter_swap(__x._M_current, __y._M_current); }
  };

  namespace views
  {
    namespace __detail
    {
      template<typename _Tp>
	concept __can_as_input = requires { as_input_view(std::declval<_Tp>()); };
    }

    struct _AsInput : __adaptor::_RangeAdaptorClosure<_AsInput>
    {
      template<viewable_range _Range>
	requires __detail::__can_as_input<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	{
	  if constexpr (input_range<_Range>
			&& !common_range<_Range>
			&& !forward_range<_Range>)
	    return views::all(std::forward<_Range>(__r));
	  else
	    return as_input_view(std::forward<_Range>(__r));
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _AsInput as_input;
  }
} // namespace ranges
#endif // __cpp_lib_ranges_as_input

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // library concepts
#endif // C++2a
#endif /* _GLIBCXX_RANGES */
