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

// Copyright (C) 2019-2025 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_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_to_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); }
      };

      template<template<typename> class>
	constexpr bool __is_std_op_template = false;

      template<>
	inline constexpr bool __is_std_op_template<std::equal_to> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::not_equal_to> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::greater> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::less> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::greater_equal> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::less_equal> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::plus> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::minus> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::multiplies> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::divides> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::modulus> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::negate> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::logical_and> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::logical_or> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::logical_not> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::bit_and> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::bit_or> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::bit_xor> = true;
      template<>
	inline constexpr bool __is_std_op_template<std::bit_not> = true;


      template<typename _Fn>
	constexpr bool __is_std_op_wrapper = false;

      template<template<typename> class _Ft, typename _Tp>
	constexpr bool __is_std_op_wrapper<_Ft<_Tp>>
	  = __is_std_op_template<_Ft>;

      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:
	constexpr bool
	_M_equal(const _Iterator& __x) const
	{ return __x._M_value == _M_bound; }

	constexpr auto
	_M_distance_from(const _Iterator& __x) const
	{ return _M_bound - __x._M_value; }

	_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 __y._M_equal(__x); }

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

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

	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
  {
    template<__detail::__can_iota_view _Tp>
      constexpr auto
      operator() [[nodiscard]] (_Tp&& __e) const
      { return iota_view(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_at_end(); }

      private:
	basic_istream_view* _M_parent;

	bool
	_M_at_end() const
	{ return !*_M_parent->_M_stream; }
      };

      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:
      struct _Sentinel;

      struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
      {
      private:
	static constexpr auto
	_S_iter_concept()
	{
	  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;

	using _Vp_iter = iterator_t<_Vp>;

	_Vp_iter _M_current = _Vp_iter();
	filter_view* _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<_Vp>;
	using difference_type = range_difference_t<_Vp>;

	_Iterator() requires default_initializable<_Vp_iter> = default;

	constexpr
	_Iterator(filter_view* __parent, _Vp_iter __current)
	  : _M_current(std::move(__current)),
	    _M_parent(__parent)
	{ }

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

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

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

	constexpr _Vp_iter
	operator->() const
	  requires __detail::__has_arrow<_Vp_iter>
	    && copyable<_Vp_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<_Vp>
	{
	  auto __tmp = *this;
	  ++*this;
	  return __tmp;
	}

	constexpr _Iterator&
	operator--() requires bidirectional_range<_Vp>
	{
	  do
	    --_M_current;
	  while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
	  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)
	  requires equality_comparable<_Vp_iter>
	{ return __x._M_current == __y._M_current; }

	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<_Vp_iter>
	{ ranges::iter_swap(__x._M_current, __y._M_current); }
      };

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

	constexpr bool
	__equal(const _Iterator& __i) const
	{ return __i._M_current == _M_end; }

      public:
	_Sentinel() = default;

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

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

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

      _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
      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 auto
      end()
      {
	if constexpr (common_range<_Vp>)
	  return _Iterator{this, ranges::end(_M_base)};
	else
	  return _Sentinel{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>;

	  template<bool _Const2>
	    constexpr auto
	    __distance_from(const _Iterator<_Const2>& __i) const
	    { return _M_end - __i._M_current; }

	  template<bool _Const2>
	    constexpr bool
	    __equal(const _Iterator<_Const2>& __i) const
	    { return __i._M_current == _M_end; }

	  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 __y.__equal(__x); }

	  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.__distance_from(__x); }

	  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.__distance_from(__x); }

	  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>;

	  template<bool _Const2>
	    constexpr bool
	    __equal(const _Iterator<_Const2>& __i) const
	    { return __i._M_get_outer() == _M_end; }

	  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 __y.__equal(__x); }

	  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>;

	  constexpr bool
	  __at_end() const
	  { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }

	  // [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.__at_end(); };

	  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};
	  }
      }

      constexpr auto
      begin() const requires forward_range<_Vp> && forward_range<const _Vp>
      {
	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>)
	  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>();

      constexpr bool
      _M_equal(const _Iterator& __x) const
      { return __x._M_cur == _M_end && !__x._M_trailing_empty; }

    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 __y._M_equal(__x); }
    };
  };

  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
    template<typename _Tp, size_t _Nm>
    concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_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:
	  template<bool _Const2>
	    constexpr bool
	    _M_equal(const _Iterator<_Const2>& __x) const
	    { return __x._M_current == _M_end; }

	  template<bool _Const2>
	    constexpr auto
	    _M_distance_from(const _Iterator<_Const2>& __i) const
	    { return _M_end - __i._M_current; }

	  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 __y._M_equal(__x); }

	  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_distance_from(__x); }

	  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_distance_from(__y); }

	  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>>
      {
	template<viewable_range _Range>
	  requires (_Nm == 0) || __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>>
      {
	template<viewable_range _Range, typename _Fp>
	  requires (_Nm == 0) || __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>>
  {
    __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
	{
	  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_to_input // C++ >= 26
namespace ranges
{
  template<input_range _Vp>
    requires view<_Vp>
  class to_input_view : public view_interface<to_input_view<_Vp>>
  {
    _Vp _M_base = _Vp();

    template<bool _Const>
    class _Iterator;

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

    constexpr explicit
    to_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>
    to_input_view(_Range&&) -> to_input_view<views::all_t<_Range>>;

  template<input_range _Vp>
    requires view<_Vp>
  template<bool _Const>
  class to_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 to_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_to_input = requires { to_input_view(std::declval<_Tp>()); };
    }

    struct _ToInput : __adaptor::_RangeAdaptorClosure<_ToInput>
    {
      template<viewable_range _Range>
	requires __detail::__can_to_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 to_input_view(std::forward<_Range>(__r));
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _ToInput to_input;
  }
} // namespace ranges
#endif // __cpp_lib_ranges_to_input

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // library concepts
#endif // C++2a
#endif /* _GLIBCXX_RANGES */
