// Core concepts and definitions for <ranges> -*- C++ -*-

// Copyright (C) 2019-2021 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

#pragma GCC system_header

#if __cplusplus > 201703L
#include <bits/iterator_concepts.h>
#include <ext/numeric_traits.h>
#include <bits/max_size_type.h>

#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 __cust_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 pills so that unqualified lookup doesn't find std::end.
    void end(auto&) = delete;
    void end(const auto&) = 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);
	}
    };

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

    struct _CBegin
    {
      template<typename _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __e) const
	noexcept(noexcept(_Begin{}(__cust_access::__as_const<_Tp>(__e))))
	requires requires { _Begin{}(__cust_access::__as_const<_Tp>(__e)); }
	{
	  return _Begin{}(__cust_access::__as_const<_Tp>(__e));
	}
    };

    struct _CEnd final
    {
      template<typename _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __e) const
	noexcept(noexcept(_End{}(__cust_access::__as_const<_Tp>(__e))))
	requires requires { _End{}(__cust_access::__as_const<_Tp>(__e)); }
	{
	  return _End{}(__cust_access::__as_const<_Tp>(__e));
	}
    };

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

    void rbegin(auto&) = delete;
    void rbegin(const auto&) = 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(auto&) = delete;
    void rend(const auto&) = 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));
	}
    };

    struct _CRBegin
    {
      template<typename _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __e) const
	noexcept(noexcept(_RBegin{}(__cust_access::__as_const<_Tp>(__e))))
	requires requires { _RBegin{}(__cust_access::__as_const<_Tp>(__e)); }
	{
	  return _RBegin{}(__cust_access::__as_const<_Tp>(__e));
	}
    };

    struct _CREnd
    {
      template<typename _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __e) const
	noexcept(noexcept(_REnd{}(__cust_access::__as_const<_Tp>(__e))))
	requires requires { _REnd{}(__cust_access::__as_const<_Tp>(__e)); }
	{
	  return _REnd{}(__cust_access::__as_const<_Tp>(__e));
	}
    };

    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(auto&) = delete;
    void size(const auto&) = 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)
	{
	  { _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)
	{
	  { _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));
	}
    };

    struct _CData
    {
      template<typename _Tp>
	[[nodiscard]]
	constexpr auto
	operator()(_Tp&& __e) const
	noexcept(noexcept(_Data{}(__cust_access::__as_const<_Tp>(__e))))
	requires requires { _Data{}(__cust_access::__as_const<_Tp>(__e)); }
	{
	  return _Data{}(__cust_access::__as_const<_Tp>(__e));
	}
    };

  } // namespace __cust_access

  inline namespace __cust
  {
    inline constexpr __cust_access::_Begin begin{};
    inline constexpr __cust_access::_End end{};
    inline constexpr __cust_access::_CBegin cbegin{};
    inline constexpr __cust_access::_CEnd cend{};
    inline constexpr __cust_access::_RBegin rbegin{};
    inline constexpr __cust_access::_REnd rend{};
    inline constexpr __cust_access::_CRBegin crbegin{};
    inline constexpr __cust_access::_CREnd crend{};
    inline constexpr __cust_access::_Size size{};
    inline constexpr __cust_access::_SSize ssize{};
    inline constexpr __cust_access::_Empty empty{};
    inline constexpr __cust_access::_Data data{};
    inline constexpr __cust_access::_CData cdata{};
  }

  /// [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&>()));

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

  /// [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&>()));

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

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

  /// A range which can be safely converted to a view.
  template<typename _Tp>
    concept viewable_range = range<_Tp>
      && (borrowed_range<_Tp> || view<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;

	    // n and bound must not lead in opposite directions:
	    __glibcxx_assert(__n == 0 || __diff == 0 || (__n < 0 == __diff < 0));
	    const auto __absdiff = __diff < 0 ? -__diff : __diff;
	    const auto __absn = __n < 0 ? -__n : __n;;
	    if (__absn >= __absdiff)
	      {
		(*this)(__it, __bound);
		return __n - __diff;
	      }
	    else
	      {
		(*this)(__it, __n);
		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
  {
    template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
      [[nodiscard]]
      constexpr iter_difference_t<_It>
      operator()(_It __first, _Sent __last) const
      {
	if constexpr (sized_sentinel_for<_Sent, _It>)
	  return __last - __first;
	else
	  {
	    iter_difference_t<_It> __n = 0;
	    while (__first != __last)
	      {
		++__first;
		++__n;
	      }
	    return __n;
	  }
      }

    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
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // library concepts
#endif // C++20
#endif // _GLIBCXX_RANGES_BASE_H
