// Core concepts and definitions for <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 bits/ranges_base.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{ranges}
 */

#ifndef _GLIBCXX_RANGES_BASE_H
#define _GLIBCXX_RANGES_BASE_H 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#if __cplusplus > 201703L
#include <initializer_list>
#include <bits/stl_iterator.h>
#include <ext/numeric_traits.h>
#include <bits/max_size_type.h>
#include <bits/version.h>

#if __glibcxx_ranges_to_container // C++ >= 23
# include <bits/utility.h> // for tuple_element_t
#endif

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic" // __int128

#if __glibcxx_algorithm_default_value_type // C++ >= 26
# define _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_I, _P) = projected_value_t<_I, _P>
#else
# define _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_I, _P)
#endif

#ifdef __cpp_lib_concepts
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges
{
  template<typename>
    inline constexpr bool disable_sized_range = false;

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

  namespace __detail
  {
    constexpr __max_size_type
    __to_unsigned_like(__max_size_type __t) noexcept
    { return __t; }

    constexpr __max_size_type
    __to_unsigned_like(__max_diff_type __t) noexcept
    { return __max_size_type(__t); }

    template<integral _Tp>
      constexpr auto
      __to_unsigned_like(_Tp __t) noexcept
      { return static_cast<make_unsigned_t<_Tp>>(__t); }

#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
    constexpr unsigned __int128
    __to_unsigned_like(__int128 __t) noexcept
    { return __t; }

    constexpr unsigned __int128
    __to_unsigned_like(unsigned __int128 __t) noexcept
    { return __t; }
#endif

    template<typename _Tp>
      using __make_unsigned_like_t
	= decltype(__detail::__to_unsigned_like(std::declval<_Tp>()));

    // Part of the constraints of ranges::borrowed_range
    template<typename _Tp>
      concept __maybe_borrowed_range
	= is_lvalue_reference_v<_Tp>
	  || enable_borrowed_range<remove_cvref_t<_Tp>>;

  } // namespace __detail

  // Namespace for helpers for the <ranges> customization points.
  namespace __access
  {
    using std::ranges::__detail::__maybe_borrowed_range;
    using std::__detail::__range_iter_t;

    struct _Begin
    {
    private:
      template<typename _Tp>
	static constexpr bool
	_S_noexcept()
	{
	  if constexpr (is_array_v<remove_reference_t<_Tp>>)
	    return true;
	  else if constexpr (__member_begin<_Tp>)
	    return noexcept(__decay_copy(std::declval<_Tp&>().begin()));
	  else
	    return noexcept(__decay_copy(begin(std::declval<_Tp&>())));
	}

    public:
      template<__maybe_borrowed_range _Tp>
	requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
	  || __adl_begin<_Tp>
	constexpr auto
	operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>())
	{
	  if constexpr (is_array_v<remove_reference_t<_Tp>>)
	    {
	      static_assert(is_lvalue_reference_v<_Tp>);
	      return __t + 0;
	    }
	  else if constexpr (__member_begin<_Tp>)
	    return __t.begin();
	  else
	    return begin(__t);
	}
    };

    template<typename _Tp>
      concept __member_end = requires(_Tp& __t)
	{
	  { __decay_copy(__t.end()) } -> sentinel_for<__range_iter_t<_Tp>>;
	};

    // Poison pill so that unqualified lookup doesn't find std::end.
    void end() = delete;

    template<typename _Tp>
      concept __adl_end = __class_or_enum<remove_reference_t<_Tp>>
	&& requires(_Tp& __t)
	{
	  { __decay_copy(end(__t)) } -> sentinel_for<__range_iter_t<_Tp>>;
	};

    struct _End
    {
    private:
      template<typename _Tp>
	static constexpr bool
	_S_noexcept()
	{
	  if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
	    return true;
	  else if constexpr (__member_end<_Tp>)
	    return noexcept(__decay_copy(std::declval<_Tp&>().end()));
	  else
	    return noexcept(__decay_copy(end(std::declval<_Tp&>())));
	}

    public:
      template<__maybe_borrowed_range _Tp>
	requires is_bounded_array_v<remove_reference_t<_Tp>>
	  || __member_end<_Tp> || __adl_end<_Tp>
	constexpr auto
	operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>())
	{
	  if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
	    {
	      static_assert(is_lvalue_reference_v<_Tp>);
	      return __t + extent_v<remove_reference_t<_Tp>>;
	    }
	  else if constexpr (__member_end<_Tp>)
	    return __t.end();
	  else
	    return end(__t);
	}
    };

    template<typename _Tp>
      concept __member_rbegin = requires(_Tp& __t)
	{
	  { __decay_copy(__t.rbegin()) } -> input_or_output_iterator;
	};

    void rbegin() = delete;

    template<typename _Tp>
      concept __adl_rbegin = __class_or_enum<remove_reference_t<_Tp>>
	&& requires(_Tp& __t)
	{
	  { __decay_copy(rbegin(__t)) } -> input_or_output_iterator;
	};

    template<typename _Tp>
      concept __reversable = requires(_Tp& __t)
	{
	  { _Begin{}(__t) } -> bidirectional_iterator;
	  { _End{}(__t) } -> same_as<decltype(_Begin{}(__t))>;
	};

    struct _RBegin
    {
    private:
      template<typename _Tp>
	static constexpr bool
	_S_noexcept()
	{
	  if constexpr (__member_rbegin<_Tp>)
	    return noexcept(__decay_copy(std::declval<_Tp&>().rbegin()));
	  else if constexpr (__adl_rbegin<_Tp>)
	    return noexcept(__decay_copy(rbegin(std::declval<_Tp&>())));
	  else
	    {
	      if constexpr (noexcept(_End{}(std::declval<_Tp&>())))
		{
		  using _It = decltype(_End{}(std::declval<_Tp&>()));
		  // std::reverse_iterator copy-initializes its member.
		  return is_nothrow_copy_constructible_v<_It>;
		}
	      else
		return false;
	    }
	}

    public:
      template<__maybe_borrowed_range _Tp>
	requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp>
	constexpr auto
	operator()[[nodiscard]](_Tp&& __t) const
	noexcept(_S_noexcept<_Tp&>())
	{
	  if constexpr (__member_rbegin<_Tp>)
	    return __t.rbegin();
	  else if constexpr (__adl_rbegin<_Tp>)
	    return rbegin(__t);
	  else
	    return std::make_reverse_iterator(_End{}(__t));
	}
    };

    template<typename _Tp>
      concept __member_rend = requires(_Tp& __t)
	{
	  { __decay_copy(__t.rend()) }
	    -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
	};

    void rend() = delete;

    template<typename _Tp>
      concept __adl_rend = __class_or_enum<remove_reference_t<_Tp>>
	&& requires(_Tp& __t)
	{
	  { __decay_copy(rend(__t)) }
	    -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
	};

    struct _REnd
    {
    private:
      template<typename _Tp>
	static constexpr bool
	_S_noexcept()
	{
	  if constexpr (__member_rend<_Tp>)
	    return noexcept(__decay_copy(std::declval<_Tp&>().rend()));
	  else if constexpr (__adl_rend<_Tp>)
	    return noexcept(__decay_copy(rend(std::declval<_Tp&>())));
	  else
	    {
	      if constexpr (noexcept(_Begin{}(std::declval<_Tp&>())))
		{
		  using _It = decltype(_Begin{}(std::declval<_Tp&>()));
		  // std::reverse_iterator copy-initializes its member.
		  return is_nothrow_copy_constructible_v<_It>;
		}
	      else
		return false;
	    }
	}

    public:
      template<__maybe_borrowed_range _Tp>
	requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp>
	constexpr auto
	operator()[[nodiscard]](_Tp&& __t) const
	noexcept(_S_noexcept<_Tp&>())
	{
	  if constexpr (__member_rend<_Tp>)
	    return __t.rend();
	  else if constexpr (__adl_rend<_Tp>)
	    return rend(__t);
	  else
	    return std::make_reverse_iterator(_Begin{}(__t));
	}
    };

    template<typename _Tp>
      concept __member_size = !disable_sized_range<remove_cvref_t<_Tp>>
	&& requires(_Tp& __t)
	{
	  { __decay_copy(__t.size()) } -> __detail::__is_integer_like;
	};

    void size() = delete;

    template<typename _Tp>
      concept __adl_size = __class_or_enum<remove_reference_t<_Tp>>
	&& !disable_sized_range<remove_cvref_t<_Tp>>
	&& requires(_Tp& __t)
	{
	  { __decay_copy(size(__t)) } -> __detail::__is_integer_like;
	};

    template<typename _Tp>
      concept __sentinel_size = requires(_Tp& __t)
	{
	  requires (!is_unbounded_array_v<remove_reference_t<_Tp>>);

	  { _Begin{}(__t) } -> forward_iterator;

	  { _End{}(__t) } -> sized_sentinel_for<decltype(_Begin{}(__t))>;

	  __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t));
	};

    struct _Size
    {
    private:
      template<typename _Tp>
	static constexpr bool
	_S_noexcept()
	{
	  if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
	    return true;
	  else if constexpr (__member_size<_Tp>)
	    return noexcept(__decay_copy(std::declval<_Tp&>().size()));
	  else if constexpr (__adl_size<_Tp>)
	    return noexcept(__decay_copy(size(std::declval<_Tp&>())));
	  else if constexpr (__sentinel_size<_Tp>)
	    return noexcept(_End{}(std::declval<_Tp&>())
			    - _Begin{}(std::declval<_Tp&>()));
	}

    public:
      template<typename _Tp>
	requires is_bounded_array_v<remove_reference_t<_Tp>>
	  || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp>
	constexpr auto
	operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>())
	{
	  if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
	    return extent_v<remove_reference_t<_Tp>>;
	  else if constexpr (__member_size<_Tp>)
	    return __t.size();
	  else if constexpr (__adl_size<_Tp>)
	    return size(__t);
	  else if constexpr (__sentinel_size<_Tp>)
	    return __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t));
	}
    };

    struct _SSize
    {
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3403. Domain of ranges::ssize(E) doesn't match ranges::size(E)
      template<typename _Tp>
	requires requires (_Tp& __t) { _Size{}(__t); }
	constexpr auto
	operator()[[nodiscard]](_Tp&& __t) const noexcept(noexcept(_Size{}(__t)))
	{
	  auto __size = _Size{}(__t);
	  using __size_type = decltype(__size);
	  // Return the wider of ptrdiff_t and make-signed-like-t<__size_type>.
	  if constexpr (integral<__size_type>)
	    {
	      using __gnu_cxx::__int_traits;
	      if constexpr (__int_traits<__size_type>::__digits
			    < __int_traits<ptrdiff_t>::__digits)
		return static_cast<ptrdiff_t>(__size);
	      else
		return static_cast<make_signed_t<__size_type>>(__size);
	    }
#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
	  // For strict-ansi modes integral<__int128> is false
	  else if constexpr (__detail::__is_int128<__size_type>)
	    return static_cast<__int128>(__size);
#endif
	  else // Must be one of __max_diff_type or __max_size_type.
	    return __detail::__max_diff_type(__size);
	}
    };

    template<typename _Tp>
      concept __member_empty = requires(_Tp& __t) { bool(__t.empty()); };

    template<typename _Tp>
      concept __size0_empty = requires(_Tp& __t) { _Size{}(__t) == 0; };

    template<typename _Tp>
      concept __eq_iter_empty = requires(_Tp& __t)
	{
	  requires (!is_unbounded_array_v<remove_reference_t<_Tp>>);

	  { _Begin{}(__t) } -> forward_iterator;

	  bool(_Begin{}(__t) == _End{}(__t));
	};

    struct _Empty
    {
    private:
      template<typename _Tp>
	static constexpr bool
	_S_noexcept()
	{
	  if constexpr (__member_empty<_Tp>)
	    return noexcept(bool(std::declval<_Tp&>().empty()));
	  else if constexpr (__size0_empty<_Tp>)
	    return noexcept(_Size{}(std::declval<_Tp&>()) == 0);
	  else
	    return noexcept(bool(_Begin{}(std::declval<_Tp&>())
		== _End{}(std::declval<_Tp&>())));
	}

    public:
      template<typename _Tp>
	requires __member_empty<_Tp> || __size0_empty<_Tp>
	  || __eq_iter_empty<_Tp>
	constexpr bool
	operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>())
	{
	  if constexpr (__member_empty<_Tp>)
	    return bool(__t.empty());
	  else if constexpr (__size0_empty<_Tp>)
	    return _Size{}(__t) == 0;
	  else
	    return bool(_Begin{}(__t) == _End{}(__t));
	}
    };

    template<typename _Tp>
      concept __pointer_to_object = is_pointer_v<_Tp>
				    && is_object_v<remove_pointer_t<_Tp>>;

    template<typename _Tp>
      concept __member_data = requires(_Tp& __t)
	{
	  { __decay_copy(__t.data()) } -> __pointer_to_object;
	};

    template<typename _Tp>
      concept __begin_data = contiguous_iterator<__range_iter_t<_Tp>>;

    struct _Data
    {
    private:
      template<typename _Tp>
	static constexpr bool
	_S_noexcept()
	{
	  if constexpr (__member_data<_Tp>)
	    return noexcept(__decay_copy(std::declval<_Tp&>().data()));
	  else
	    return noexcept(_Begin{}(std::declval<_Tp&>()));
	}

    public:
      template<__maybe_borrowed_range _Tp>
	requires __member_data<_Tp> || __begin_data<_Tp>
	constexpr auto
	operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
	{
	  if constexpr (__member_data<_Tp>)
	    return __t.data();
	  else
	    return std::to_address(_Begin{}(__t));
	}
    };

  } // namespace __access

  inline namespace _Cpo
  {
    inline constexpr ranges::__access::_Begin begin{};
    inline constexpr ranges::__access::_End end{};
    inline constexpr ranges::__access::_RBegin rbegin{};
    inline constexpr ranges::__access::_REnd rend{};
    inline constexpr ranges::__access::_Size size{};
    inline constexpr ranges::__access::_SSize ssize{};
    inline constexpr ranges::__access::_Empty empty{};
    inline constexpr ranges::__access::_Data data{};
  }

  /// [range.range] The range concept.
  template<typename _Tp>
    concept range = requires(_Tp& __t)
      {
	ranges::begin(__t);
	ranges::end(__t);
      };

  /// [range.range] The borrowed_range concept.
  template<typename _Tp>
    concept borrowed_range
      = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>;

  template<typename _Tp>
    using iterator_t = std::__detail::__range_iter_t<_Tp>;

  template<range _Range>
    using sentinel_t = decltype(ranges::end(std::declval<_Range&>()));

#if __glibcxx_ranges_as_const // >= C++23
  template<range _Range>
    using const_iterator_t = const_iterator<iterator_t<_Range>>;

  template<range _Range>
    using const_sentinel_t = const_sentinel<sentinel_t<_Range>>;

  template<range _Range>
    using range_const_reference_t = iter_const_reference_t<iterator_t<_Range>>;
#endif

  template<range _Range>
    using range_difference_t = iter_difference_t<iterator_t<_Range>>;

  template<range _Range>
    using range_value_t = iter_value_t<iterator_t<_Range>>;

  template<range _Range>
    using range_reference_t = iter_reference_t<iterator_t<_Range>>;

  template<range _Range>
    using range_rvalue_reference_t
      = iter_rvalue_reference_t<iterator_t<_Range>>;

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 3860. range_common_reference_t is missing
  template<range _Range>
    using range_common_reference_t
      = iter_common_reference_t<iterator_t<_Range>>;

  /// [range.sized] The sized_range concept.
  template<typename _Tp>
    concept sized_range = range<_Tp>
      && requires(_Tp& __t) { ranges::size(__t); };

  template<sized_range _Range>
    using range_size_t = decltype(ranges::size(std::declval<_Range&>()));

  template<typename _Derived>
    requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
    class view_interface; // defined in <bits/ranges_util.h>

  namespace __detail
  {
    template<typename _Tp, typename _Up>
      requires (!same_as<_Tp, view_interface<_Up>>)
      void __is_derived_from_view_interface_fn(const _Tp&,
					       const view_interface<_Up>&); // not defined

    // Returns true iff _Tp has exactly one public base class that's a
    // specialization of view_interface.
    template<typename _Tp>
      concept __is_derived_from_view_interface
	= requires (_Tp __t) { __is_derived_from_view_interface_fn(__t, __t); };
  } // namespace __detail

  /// [range.view] The ranges::view_base type.
  struct view_base { };

  /// [range.view] The ranges::enable_view boolean.
  template<typename _Tp>
    inline constexpr bool enable_view = derived_from<_Tp, view_base>
      || __detail::__is_derived_from_view_interface<_Tp>;

  /// [range.view] The ranges::view concept.
  template<typename _Tp>
    concept view
      = range<_Tp> && movable<_Tp> && enable_view<_Tp>;

  // [range.refinements]

  /// A range for which ranges::begin returns an output iterator.
  template<typename _Range, typename _Tp>
    concept output_range
      = range<_Range> && output_iterator<iterator_t<_Range>, _Tp>;

  /// A range for which ranges::begin returns an input iterator.
  template<typename _Tp>
    concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;

  /// A range for which ranges::begin returns a forward iterator.
  template<typename _Tp>
    concept forward_range
      = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;

  /// A range for which ranges::begin returns a bidirectional iterator.
  template<typename _Tp>
    concept bidirectional_range
      = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;

  /// A range for which ranges::begin returns a random access iterator.
  template<typename _Tp>
    concept random_access_range
      = bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;

  /// A range for which ranges::begin returns a contiguous iterator.
  template<typename _Tp>
    concept contiguous_range
      = random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>>
      && requires(_Tp& __t)
      {
	{ ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
      };

  /// A range for which ranges::begin and ranges::end return the same type.
  template<typename _Tp>
    concept common_range
      = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;

#if __glibcxx_ranges_as_const // >= C++23
  template<typename _Tp>
    concept constant_range
      = input_range<_Tp> && std::__detail::__constant_iterator<iterator_t<_Tp>>;
#endif

  namespace __access
  {
#if __glibcxx_ranges_as_const // >= C++23
    template<input_range _Range>
      constexpr auto&
      __possibly_const_range(_Range& __r) noexcept
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 4027. possibly-const-range should prefer returning const R&
	if constexpr (input_range<const _Range>)
	  return const_cast<const _Range&>(__r);
	else
	  return __r;
      }
#else
    // If _To is an lvalue-reference, return const _Tp&, otherwise const _Tp&&.
    template<typename _To, typename _Tp>
      constexpr decltype(auto)
      __as_const(_Tp& __t) noexcept
      {
	static_assert(std::is_same_v<_To&, _Tp&>);

	if constexpr (is_lvalue_reference_v<_To>)
	  return const_cast<const _Tp&>(__t);
	else
	  return static_cast<const _Tp&&>(__t);
      }
#endif

    struct _CBegin
    {
#if __glibcxx_ranges_as_const // >= C++23
      template<__maybe_borrowed_range _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __t) const
	noexcept(noexcept(std::make_const_iterator
			  (ranges::begin(__access::__possibly_const_range(__t)))))
	requires requires { std::make_const_iterator
			    (ranges::begin(__access::__possibly_const_range(__t))); }
	{
	  auto& __r = __access::__possibly_const_range(__t);
	  return const_iterator_t<decltype(__r)>(ranges::begin(__r));
	}
#else
      template<typename _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __e) const
	noexcept(noexcept(_Begin{}(__access::__as_const<_Tp>(__e))))
	requires requires { _Begin{}(__access::__as_const<_Tp>(__e)); }
	{
	  return _Begin{}(__access::__as_const<_Tp>(__e));
	}
#endif
    };

    struct _CEnd final
    {
#if __glibcxx_ranges_as_const // >= C++23
      template<__maybe_borrowed_range _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __t) const
	noexcept(noexcept(std::make_const_sentinel
			  (ranges::end(__access::__possibly_const_range(__t)))))
	requires requires { std::make_const_sentinel
			    (ranges::end(__access::__possibly_const_range(__t))); }
	{
	  auto& __r = __access::__possibly_const_range(__t);
	  return const_sentinel_t<decltype(__r)>(ranges::end(__r));
	}
#else
      template<typename _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __e) const
	noexcept(noexcept(_End{}(__access::__as_const<_Tp>(__e))))
	requires requires { _End{}(__access::__as_const<_Tp>(__e)); }
	{
	  return _End{}(__access::__as_const<_Tp>(__e));
	}
#endif
    };

    struct _CRBegin
    {
#if __glibcxx_ranges_as_const // >= C++23
      template<__maybe_borrowed_range _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __t) const
	noexcept(noexcept(std::make_const_iterator
			  (ranges::rbegin(__access::__possibly_const_range(__t)))))
	requires requires { std::make_const_iterator
			    (ranges::rbegin(__access::__possibly_const_range(__t))); }
	{
	  auto& __r = __access::__possibly_const_range(__t);
	  return const_iterator<decltype(ranges::rbegin(__r))>(ranges::rbegin(__r));
	}
#else
      template<typename _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __e) const
	noexcept(noexcept(_RBegin{}(__access::__as_const<_Tp>(__e))))
	requires requires { _RBegin{}(__access::__as_const<_Tp>(__e)); }
	{
	  return _RBegin{}(__access::__as_const<_Tp>(__e));
	}
#endif
    };

    struct _CREnd
    {
#if __glibcxx_ranges_as_const // >= C++23
      template<__maybe_borrowed_range _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __t) const
	noexcept(noexcept(std::make_const_sentinel
			  (ranges::rend(__access::__possibly_const_range(__t)))))
	requires requires { std::make_const_sentinel
			    (ranges::rend(__access::__possibly_const_range(__t))); }
	{
	  auto& __r = __access::__possibly_const_range(__t);
	  return const_sentinel<decltype(ranges::rend(__r))>(ranges::rend(__r));
	}
#else
      template<typename _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __e) const
	noexcept(noexcept(_REnd{}(__access::__as_const<_Tp>(__e))))
	requires requires { _REnd{}(__access::__as_const<_Tp>(__e)); }
	{
	  return _REnd{}(__access::__as_const<_Tp>(__e));
	}
#endif
    };

    struct _CData
    {
#if __glibcxx_ranges_as_const // >= C++23
      template<__maybe_borrowed_range _Tp>
	[[nodiscard]]
	constexpr const auto*
	operator()(_Tp&& __t) const
	noexcept(noexcept(ranges::data(__access::__possibly_const_range(__t))))
	requires requires { ranges::data(__access::__possibly_const_range(__t)); }
	{ return ranges::data(__access::__possibly_const_range(__t)); }
#else
      template<typename _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __e) const
	noexcept(noexcept(_Data{}(__access::__as_const<_Tp>(__e))))
	requires requires { _Data{}(__access::__as_const<_Tp>(__e)); }
	{
	  return _Data{}(__access::__as_const<_Tp>(__e));
	}
#endif
    };
  } // namespace __access

  inline namespace _Cpo
  {
    inline constexpr ranges::__access::_CBegin cbegin{};
    inline constexpr ranges::__access::_CEnd cend{};
    inline constexpr ranges::__access::_CRBegin crbegin{};
    inline constexpr ranges::__access::_CREnd crend{};
    inline constexpr ranges::__access::_CData cdata{};
  }

  namespace __detail
  {
    template<typename _Tp>
      inline constexpr bool __is_initializer_list = false;

    template<typename _Tp>
      inline constexpr bool __is_initializer_list<initializer_list<_Tp>> = true;
  } // namespace __detail

  /// A range which can be safely converted to a view.
  template<typename _Tp>
    concept viewable_range = range<_Tp>
      && ((view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>)
	  || (!view<remove_cvref_t<_Tp>>
	      && (is_lvalue_reference_v<_Tp>
		  || (movable<remove_reference_t<_Tp>>
		      && !__detail::__is_initializer_list<remove_cvref_t<_Tp>>))));

  // [range.iter.ops] range iterator operations

  struct __advance_fn final
  {
    template<input_or_output_iterator _It>
      constexpr void
      operator()(_It& __it, iter_difference_t<_It> __n) const
      {
	if constexpr (random_access_iterator<_It>)
	  __it += __n;
	else if constexpr (bidirectional_iterator<_It>)
	  {
	    if (__n > 0)
	      {
		do
		  {
		    ++__it;
		  }
		while (--__n);
	      }
	    else if (__n < 0)
	      {
		do
		  {
		    --__it;
		  }
		while (++__n);
	      }
	  }
	else
	  {
	    // cannot decrement a non-bidirectional iterator
	    __glibcxx_assert(__n >= 0);
	    while (__n-- > 0)
	      ++__it;
	  }
      }

    template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
      constexpr void
      operator()(_It& __it, _Sent __bound) const
      {
	if constexpr (assignable_from<_It&, _Sent>)
	  __it = std::move(__bound);
	else if constexpr (sized_sentinel_for<_Sent, _It>)
	  (*this)(__it, __bound - __it);
	else
	  {
	    while (__it != __bound)
	      ++__it;
	  }
      }

    template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
      constexpr iter_difference_t<_It>
      operator()(_It& __it, iter_difference_t<_It> __n, _Sent __bound) const
      {
	if constexpr (sized_sentinel_for<_Sent, _It>)
	  {
	    const auto __diff = __bound - __it;

	    if (__diff == 0)
	      return __n;
	    else if (__diff > 0 ? __n >= __diff : __n <= __diff)
	      {
		(*this)(__it, __bound);
		return __n - __diff;
	      }
	    else if (__n != 0) [[likely]]
	      {
		// n and bound must not lead in opposite directions:
		__glibcxx_assert((__n < 0) == (__diff < 0));

		(*this)(__it, __n);
		return 0;
	      }
	    else
	      return 0;
	  }
	else if (__it == __bound || __n == 0)
	  return __n;
	else if (__n > 0)
	  {
	    iter_difference_t<_It> __m = 0;
	    do
	      {
		++__it;
		++__m;
	      }
	    while (__m != __n && __it != __bound);
	    return __n - __m;
	  }
	else if constexpr (bidirectional_iterator<_It> && same_as<_It, _Sent>)
	  {
	    iter_difference_t<_It> __m = 0;
	    do
	      {
		--__it;
		--__m;
	      }
	    while (__m != __n && __it != __bound);
	    return __n - __m;
	  }
	else
	  {
	    // cannot decrement a non-bidirectional iterator
	    __glibcxx_assert(__n >= 0);
	    return __n;
	  }
      }

    void operator&() const = delete;
  };

  inline constexpr __advance_fn advance{};

  struct __distance_fn final
  {
    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 3664. LWG 3392 broke std::ranges::distance(a, a+3)
    template<typename _It, sentinel_for<_It> _Sent>
      requires (!sized_sentinel_for<_Sent, _It>)
      constexpr iter_difference_t<_It>
      operator()[[nodiscard]](_It __first, _Sent __last) const
      {
	iter_difference_t<_It> __n = 0;
	while (__first != __last)
	  {
	    ++__first;
	    ++__n;
	  }
	return __n;
      }

    template<typename _It, sized_sentinel_for<decay_t<_It>> _Sent>
      [[nodiscard]]
      constexpr iter_difference_t<decay_t<_It>>
      operator()(_It&& __first, _Sent __last) const
      { return __last - static_cast<const decay_t<_It>&>(__first); }

    template<range _Range>
      [[nodiscard]]
      constexpr range_difference_t<_Range>
      operator()(_Range&& __r) const
      {
	if constexpr (sized_range<_Range>)
	  return static_cast<range_difference_t<_Range>>(ranges::size(__r));
	else
	  return (*this)(ranges::begin(__r), ranges::end(__r));
      }

    void operator&() const = delete;
  };

  inline constexpr __distance_fn distance{};

  struct __next_fn final
  {
    template<input_or_output_iterator _It>
      [[nodiscard]]
      constexpr _It
      operator()(_It __x) const
      {
	++__x;
	return __x;
      }

    template<input_or_output_iterator _It>
      [[nodiscard]]
      constexpr _It
      operator()(_It __x, iter_difference_t<_It> __n) const
      {
	ranges::advance(__x, __n);
	return __x;
      }

    template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
      [[nodiscard]]
      constexpr _It
      operator()(_It __x, _Sent __bound) const
      {
	ranges::advance(__x, __bound);
	return __x;
      }

    template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
      [[nodiscard]]
      constexpr _It
      operator()(_It __x, iter_difference_t<_It> __n, _Sent __bound) const
      {
	ranges::advance(__x, __n, __bound);
	return __x;
      }

    void operator&() const = delete;
  };

  inline constexpr __next_fn next{};

  struct __prev_fn final
  {
    template<bidirectional_iterator _It>
      [[nodiscard]]
      constexpr _It
      operator()(_It __x) const
      {
	--__x;
	return __x;
      }

    template<bidirectional_iterator _It>
      [[nodiscard]]
      constexpr _It
      operator()(_It __x, iter_difference_t<_It> __n) const
      {
	ranges::advance(__x, -__n);
	return __x;
      }

    template<bidirectional_iterator _It>
      [[nodiscard]]
      constexpr _It
      operator()(_It __x, iter_difference_t<_It> __n, _It __bound) const
      {
	ranges::advance(__x, -__n, __bound);
	return __x;
      }

    void operator&() const = delete;
  };

  inline constexpr __prev_fn prev{};

  /// Type returned by algorithms instead of a dangling iterator or subrange.
  struct dangling
  {
    constexpr dangling() noexcept = default;
    template<typename... _Args>
      constexpr dangling(_Args&&...) noexcept { }
  };

  template<range _Range>
    using borrowed_iterator_t = __conditional_t<borrowed_range<_Range>,
						iterator_t<_Range>,
						dangling>;
} // namespace ranges

#if __glibcxx_ranges_to_container // C++ >= 23
  struct from_range_t { explicit from_range_t() = default; };
  inline constexpr from_range_t from_range{};

/// @cond undocumented
  template<typename _T1, typename _T2>
    struct pair;

namespace __detail
{
  template<typename _Rg, typename _Tp>
    concept __container_compatible_range
      = ranges::input_range<_Rg>
	  && convertible_to<ranges::range_reference_t<_Rg>, _Tp>;

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 4223. Deduction guides for maps are mishandling tuples and references
  template<ranges::input_range _Range>
    using __range_key_type
      = remove_const_t<tuple_element_t<0, ranges::range_value_t<_Range>>>;

  template<ranges::input_range _Range>
    using __range_mapped_type
      = tuple_element_t<1, ranges::range_value_t<_Range>>;

  // The allocator's value_type for map-like containers.
  template<ranges::input_range _Range>
    using __range_to_alloc_type
      = pair<const __range_key_type<_Range>, __range_mapped_type<_Range>>;
}
/// @endcond
#endif

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // library concepts
#pragma GCC diagnostic pop
#endif // C++20
#endif // _GLIBCXX_RANGES_BASE_H
