// Iterators -*- C++ -*-

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

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

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

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

/*
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Hewlett-Packard Company makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 *
 * Copyright (c) 1996-1998
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

/** @file bits/stl_iterator.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{iterator}
 *
 *  This file implements reverse_iterator, back_insert_iterator,
 *  front_insert_iterator, insert_iterator, __normal_iterator, and their
 *  supporting functions and overloaded operators.
 */

#ifndef _STL_ITERATOR_H
#define _STL_ITERATOR_H 1

#include <bits/cpp_type_traits.h>
#include <bits/stl_iterator_base_types.h>
#include <ext/type_traits.h>
#include <bits/move.h>
#include <bits/ptr_traits.h>

#if __cplusplus >= 201103L
# include <type_traits>
#endif

#if __cplusplus >= 202002L
# include <compare>
# include <new>
# include <bits/exception_defines.h>
# include <bits/iterator_concepts.h>
# include <bits/stl_construct.h>
#endif

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

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * @addtogroup iterators
   * @{
   */

#ifdef __glibcxx_concepts
  /// @cond undocumented
  namespace __detail
  {
    // Weaken iterator_category _Cat to _Limit if it is derived from that,
    // otherwise use _Otherwise.
    template<typename _Cat, typename _Limit, typename _Otherwise = _Cat>
      using __clamp_iter_cat
	= __conditional_t<derived_from<_Cat, _Limit>, _Limit, _Otherwise>;
  }
  /// @endcond
#endif

// Ignore warnings about std::iterator.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

  // 24.4.1 Reverse iterators
  /**
   *  Bidirectional and random access iterators have corresponding reverse
   *  %iterator adaptors that iterate through the data structure in the
   *  opposite direction.  They have the same signatures as the corresponding
   *  iterators.  The fundamental relation between a reverse %iterator and its
   *  corresponding %iterator @c i is established by the identity:
   *  @code
   *      &*(reverse_iterator(i)) == &*(i - 1)
   *  @endcode
   *
   *  <em>This mapping is dictated by the fact that while there is always a
   *  pointer past the end of an array, there might not be a valid pointer
   *  before the beginning of an array.</em> [24.4.1]/1,2
   *
   *  Reverse iterators can be tricky and surprising at first.  Their
   *  semantics make sense, however, and the trickiness is a side effect of
   *  the requirement that the iterators must be safe.
  */
  template<typename _Iterator>
    class reverse_iterator
    : public iterator<typename iterator_traits<_Iterator>::iterator_category,
		      typename iterator_traits<_Iterator>::value_type,
		      typename iterator_traits<_Iterator>::difference_type,
		      typename iterator_traits<_Iterator>::pointer,
                      typename iterator_traits<_Iterator>::reference>
    {
      template<typename _Iter>
	friend class reverse_iterator;

#ifdef __glibcxx_concepts
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3435. three_way_comparable_with<reverse_iterator<int*>, [...]>
      template<typename _Iter>
	static constexpr bool __convertible = !is_same_v<_Iter, _Iterator>
	    && convertible_to<const _Iter&, _Iterator>;
#endif

    protected:
      _Iterator current;

      typedef iterator_traits<_Iterator>		__traits_type;

    public:
      typedef _Iterator					iterator_type;
      typedef typename __traits_type::pointer		pointer;
#ifndef __glibcxx_concepts
      typedef typename __traits_type::difference_type	difference_type;
      typedef typename __traits_type::reference		reference;
#else
      using iterator_concept
	= __conditional_t<random_access_iterator<_Iterator>,
			  random_access_iterator_tag,
			  bidirectional_iterator_tag>;
      using iterator_category
	= __detail::__clamp_iter_cat<typename __traits_type::iterator_category,
				     random_access_iterator_tag>;
      using value_type = iter_value_t<_Iterator>;
      using difference_type = iter_difference_t<_Iterator>;
      using reference = iter_reference_t<_Iterator>;
#endif

      /**
       *  The default constructor value-initializes member @p current.
       *  If it is a pointer, that means it is zero-initialized.
      */
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 235 No specification of default ctor for reverse_iterator
      // 1012. reverse_iterator default ctor should value initialize
      _GLIBCXX17_CONSTEXPR
      reverse_iterator()
      _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator()))
      : current()
      { }

      /**
       *  This %iterator will move in the opposite direction that @p x does.
      */
      explicit _GLIBCXX17_CONSTEXPR
      reverse_iterator(iterator_type __x)
      _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x)))
      : current(__x)
      { }

      /**
       *  The copy constructor is normal.
      */
      _GLIBCXX17_CONSTEXPR
      reverse_iterator(const reverse_iterator& __x)
      _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x.current)))
      : current(__x.current)
      { }

#if __cplusplus >= 201103L
      reverse_iterator& operator=(const reverse_iterator&) = default;
#endif

      /**
       *  A %reverse_iterator across other types can be copied if the
       *  underlying %iterator can be converted to the type of @c current.
      */
      template<typename _Iter>
#ifdef __glibcxx_concepts
	requires __convertible<_Iter>
#endif
	_GLIBCXX17_CONSTEXPR
        reverse_iterator(const reverse_iterator<_Iter>& __x)
	_GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x.current)))
	: current(__x.current)
	{ }

#if __cplusplus >= 201103L
      template<typename _Iter>
# ifdef __glibcxx_concepts
	requires __convertible<_Iter>
	  && assignable_from<_Iterator&, const _Iter&>
# endif
	_GLIBCXX17_CONSTEXPR
	reverse_iterator&
	operator=(const reverse_iterator<_Iter>& __x)
	_GLIBCXX_NOEXCEPT_IF(noexcept(current = __x.current))
	{
	  current = __x.current;
	  return *this;
	}
#endif // C++11

      /**
       *  @return  @c current, the %iterator used for underlying work.
      */
      _GLIBCXX_NODISCARD
      _GLIBCXX17_CONSTEXPR iterator_type
      base() const
      _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(current)))
      { return current; }

      /**
       *  @return  A reference to the value at @c --current
       *
       *  This requires that @c --current is dereferenceable.
       *
       *  @warning This implementation requires that for an iterator of the
       *           underlying iterator type, @c x, a reference obtained by
       *           @c *x remains valid after @c x has been modified or
       *           destroyed. This is a bug: http://gcc.gnu.org/PR51823
      */
      _GLIBCXX_NODISCARD
      _GLIBCXX17_CONSTEXPR reference
      operator*() const
      {
	_Iterator __tmp = current;
	return *--__tmp;
      }

      /**
       *  @return  A pointer to the value at @c --current
       *
       *  This requires that @c --current is dereferenceable.
      */
      _GLIBCXX_NODISCARD
      _GLIBCXX17_CONSTEXPR pointer
      operator->() const
#ifdef __glibcxx_concepts
      requires is_pointer_v<_Iterator>
	|| requires(const _Iterator __i) { __i.operator->(); }
#endif
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 1052. operator-> should also support smart pointers
	_Iterator __tmp = current;
	--__tmp;
	return _S_to_pointer(__tmp);
      }

      /**
       *  @return  @c *this
       *
       *  Decrements the underlying iterator.
      */
      _GLIBCXX17_CONSTEXPR reverse_iterator&
      operator++()
      {
	--current;
	return *this;
      }

      /**
       *  @return  The original value of @c *this
       *
       *  Decrements the underlying iterator.
      */
      _GLIBCXX17_CONSTEXPR reverse_iterator
      operator++(int)
      {
	reverse_iterator __tmp = *this;
	--current;
	return __tmp;
      }

      /**
       *  @return  @c *this
       *
       *  Increments the underlying iterator.
      */
      _GLIBCXX17_CONSTEXPR reverse_iterator&
      operator--()
      {
	++current;
	return *this;
      }

      /**
       *  @return  A reverse_iterator with the previous value of @c *this
       *
       *  Increments the underlying iterator.
      */
      _GLIBCXX17_CONSTEXPR reverse_iterator
      operator--(int)
      {
	reverse_iterator __tmp = *this;
	++current;
	return __tmp;
      }

      /**
       *  @return  A reverse_iterator that refers to @c current - @a __n
       *
       *  The underlying iterator must be a Random Access Iterator.
      */
      _GLIBCXX_NODISCARD
      _GLIBCXX17_CONSTEXPR reverse_iterator
      operator+(difference_type __n) const
      { return reverse_iterator(current - __n); }

      /**
       *  @return  *this
       *
       *  Moves the underlying iterator backwards @a __n steps.
       *  The underlying iterator must be a Random Access Iterator.
      */
      _GLIBCXX17_CONSTEXPR reverse_iterator&
      operator+=(difference_type __n)
      {
	current -= __n;
	return *this;
      }

      /**
       *  @return  A reverse_iterator that refers to @c current - @a __n
       *
       *  The underlying iterator must be a Random Access Iterator.
      */
      _GLIBCXX_NODISCARD
      _GLIBCXX17_CONSTEXPR reverse_iterator
      operator-(difference_type __n) const
      { return reverse_iterator(current + __n); }

      /**
       *  @return  *this
       *
       *  Moves the underlying iterator forwards @a __n steps.
       *  The underlying iterator must be a Random Access Iterator.
      */
      _GLIBCXX17_CONSTEXPR reverse_iterator&
      operator-=(difference_type __n)
      {
	current += __n;
	return *this;
      }

      /**
       *  @return  The value at @c current - @a __n - 1
       *
       *  The underlying iterator must be a Random Access Iterator.
      */
      _GLIBCXX_NODISCARD
      _GLIBCXX17_CONSTEXPR reference
      operator[](difference_type __n) const
      { return *(*this + __n); }

#ifdef __glibcxx_ranges
      [[nodiscard]]
      friend constexpr iter_rvalue_reference_t<_Iterator>
      iter_move(const reverse_iterator& __i)
      noexcept(is_nothrow_copy_constructible_v<_Iterator>
	       && noexcept(ranges::iter_move(--std::declval<_Iterator&>())))
      {
	auto __tmp = __i.base();
	return ranges::iter_move(--__tmp);
      }

      template<indirectly_swappable<_Iterator> _Iter2>
	friend constexpr void
	iter_swap(const reverse_iterator& __x,
		  const reverse_iterator<_Iter2>& __y)
	noexcept(is_nothrow_copy_constructible_v<_Iterator>
		 && is_nothrow_copy_constructible_v<_Iter2>
		 && noexcept(ranges::iter_swap(--std::declval<_Iterator&>(),
					       --std::declval<_Iter2&>())))
	{
	  auto __xtmp = __x.base();
	  auto __ytmp = __y.base();
	  ranges::iter_swap(--__xtmp, --__ytmp);
	}
#endif // ranges

    private:
      template<typename _Tp>
	static _GLIBCXX17_CONSTEXPR _Tp*
	_S_to_pointer(_Tp* __p)
        { return __p; }

      template<typename _Tp>
	static _GLIBCXX17_CONSTEXPR pointer
	_S_to_pointer(_Tp __t)
        { return __t.operator->(); }
    };

  ///@{
  /**
   *  @param  __x  A %reverse_iterator.
   *  @param  __y  A %reverse_iterator.
   *  @return  A simple bool.
   *
   *  Reverse iterators forward comparisons to their underlying base()
   *  iterators.
   *
  */
#ifndef __glibcxx_concepts
  template<typename _Iterator>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator==(const reverse_iterator<_Iterator>& __x,
	       const reverse_iterator<_Iterator>& __y)
    { return __x.base() == __y.base(); }

  template<typename _Iterator>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator<(const reverse_iterator<_Iterator>& __x,
	      const reverse_iterator<_Iterator>& __y)
    { return __y.base() < __x.base(); }

  template<typename _Iterator>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator!=(const reverse_iterator<_Iterator>& __x,
	       const reverse_iterator<_Iterator>& __y)
    { return !(__x == __y); }

  template<typename _Iterator>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator>(const reverse_iterator<_Iterator>& __x,
	      const reverse_iterator<_Iterator>& __y)
    { return __y < __x; }

  template<typename _Iterator>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator<=(const reverse_iterator<_Iterator>& __x,
	       const reverse_iterator<_Iterator>& __y)
    { return !(__y < __x); }

  template<typename _Iterator>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator>=(const reverse_iterator<_Iterator>& __x,
	       const reverse_iterator<_Iterator>& __y)
    { return !(__x < __y); }

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // DR 280. Comparison of reverse_iterator to const reverse_iterator.

  template<typename _IteratorL, typename _IteratorR>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator==(const reverse_iterator<_IteratorL>& __x,
	       const reverse_iterator<_IteratorR>& __y)
    { return __x.base() == __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator<(const reverse_iterator<_IteratorL>& __x,
	      const reverse_iterator<_IteratorR>& __y)
    { return __x.base() > __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator!=(const reverse_iterator<_IteratorL>& __x,
	       const reverse_iterator<_IteratorR>& __y)
    { return __x.base() != __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator>(const reverse_iterator<_IteratorL>& __x,
	      const reverse_iterator<_IteratorR>& __y)
    { return __x.base() < __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    inline _GLIBCXX17_CONSTEXPR bool
    operator<=(const reverse_iterator<_IteratorL>& __x,
	       const reverse_iterator<_IteratorR>& __y)
    { return __x.base() >= __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR bool
    operator>=(const reverse_iterator<_IteratorL>& __x,
	       const reverse_iterator<_IteratorR>& __y)
    { return __x.base() <= __y.base(); }
#else // C++20
  template<typename _IteratorL, typename _IteratorR>
    [[nodiscard]]
    constexpr bool
    operator==(const reverse_iterator<_IteratorL>& __x,
	       const reverse_iterator<_IteratorR>& __y)
    requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; }
    { return __x.base() == __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    [[nodiscard]]
    constexpr bool
    operator!=(const reverse_iterator<_IteratorL>& __x,
	       const reverse_iterator<_IteratorR>& __y)
    requires requires { { __x.base() != __y.base() } -> convertible_to<bool>; }
    { return __x.base() != __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    [[nodiscard]]
    constexpr bool
    operator<(const reverse_iterator<_IteratorL>& __x,
	      const reverse_iterator<_IteratorR>& __y)
    requires requires { { __x.base() > __y.base() } -> convertible_to<bool>; }
    { return __x.base() > __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    [[nodiscard]]
    constexpr bool
    operator>(const reverse_iterator<_IteratorL>& __x,
	      const reverse_iterator<_IteratorR>& __y)
    requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
    { return __x.base() < __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    [[nodiscard]]
    constexpr bool
    operator<=(const reverse_iterator<_IteratorL>& __x,
	       const reverse_iterator<_IteratorR>& __y)
    requires requires { { __x.base() >= __y.base() } -> convertible_to<bool>; }
    { return __x.base() >= __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    [[nodiscard]]
    constexpr bool
    operator>=(const reverse_iterator<_IteratorL>& __x,
	       const reverse_iterator<_IteratorR>& __y)
    requires requires { { __x.base() <= __y.base() } -> convertible_to<bool>; }
    { return __x.base() <= __y.base(); }

  template<typename _IteratorL,
	   three_way_comparable_with<_IteratorL> _IteratorR>
    [[nodiscard]]
    constexpr compare_three_way_result_t<_IteratorL, _IteratorR>
    operator<=>(const reverse_iterator<_IteratorL>& __x,
		const reverse_iterator<_IteratorR>& __y)
    { return __y.base() <=> __x.base(); }

  // Additional, non-standard overloads to avoid ambiguities with greedy,
  // unconstrained overloads in associated namespaces.

  template<typename _Iterator>
    [[nodiscard]]
    constexpr bool
    operator==(const reverse_iterator<_Iterator>& __x,
	       const reverse_iterator<_Iterator>& __y)
    requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; }
    { return __x.base() == __y.base(); }

  template<three_way_comparable _Iterator>
    [[nodiscard]]
    constexpr compare_three_way_result_t<_Iterator, _Iterator>
    operator<=>(const reverse_iterator<_Iterator>& __x,
		const reverse_iterator<_Iterator>& __y)
    { return __y.base() <=> __x.base(); }
#endif // C++20
  ///@}

#if __cplusplus < 201103L
  template<typename _Iterator>
    inline typename reverse_iterator<_Iterator>::difference_type
    operator-(const reverse_iterator<_Iterator>& __x,
	      const reverse_iterator<_Iterator>& __y)
    { return __y.base() - __x.base(); }

  template<typename _IteratorL, typename _IteratorR>
    inline typename reverse_iterator<_IteratorL>::difference_type
    operator-(const reverse_iterator<_IteratorL>& __x,
	      const reverse_iterator<_IteratorR>& __y)
    { return __y.base() - __x.base(); }
#else
  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // DR 685. reverse_iterator/move_iterator difference has invalid signatures
  template<typename _IteratorL, typename _IteratorR>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR auto
    operator-(const reverse_iterator<_IteratorL>& __x,
	      const reverse_iterator<_IteratorR>& __y)
    -> decltype(__y.base() - __x.base())
    { return __y.base() - __x.base(); }
#endif

  template<typename _Iterator>
    _GLIBCXX_NODISCARD
    inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
    operator+(typename reverse_iterator<_Iterator>::difference_type __n,
	      const reverse_iterator<_Iterator>& __x)
    { return reverse_iterator<_Iterator>(__x.base() - __n); }

#if __cplusplus >= 201103L
  // Same as C++14 make_reverse_iterator but used in C++11 mode too.
  template<typename _Iterator>
    inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
    __make_reverse_iterator(_Iterator __i)
    { return reverse_iterator<_Iterator>(__i); }

# ifdef __glibcxx_make_reverse_iterator // C++ >= 14
  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // DR 2285. make_reverse_iterator
  /// Generator function for reverse_iterator.
  template<typename _Iterator>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
    make_reverse_iterator(_Iterator __i)
    { return reverse_iterator<_Iterator>(__i); }

#  ifdef __glibcxx_ranges
  template<typename _Iterator1, typename _Iterator2>
    requires (!sized_sentinel_for<_Iterator1, _Iterator2>)
    inline constexpr bool
    disable_sized_sentinel_for<reverse_iterator<_Iterator1>,
			       reverse_iterator<_Iterator2>> = true;
#  endif // C++20
# endif // __glibcxx_make_reverse_iterator

  template<typename _Iterator>
    struct __is_move_iterator<reverse_iterator<_Iterator> >
      : __is_move_iterator<_Iterator>
    { };
#endif // C++11

  // 24.4.2.2.1 back_insert_iterator
  /**
   *  @brief  Turns assignment into insertion.
   *
   *  These are output iterators, constructed from a container-of-T.
   *  Assigning a T to the iterator appends it to the container using
   *  push_back.
   *
   *  Tip:  Using the back_inserter function to create these iterators can
   *  save typing.
  */
  template<typename _Container>
    class back_insert_iterator
    : public iterator<output_iterator_tag, void, void, void, void>
    {
    protected:
      _Container* container;

    public:
      /// A nested typedef for the type of whatever container you used.
      typedef _Container          container_type;
#ifdef __glibcxx_ranges
      using difference_type = ptrdiff_t;
#endif

      /// The only way to create this %iterator is with a container.
      explicit _GLIBCXX20_CONSTEXPR
      back_insert_iterator(_Container& __x)
      : container(std::__addressof(__x)) { }

      /**
       *  @param  __value  An instance of whatever type
       *                 container_type::const_reference is; presumably a
       *                 reference-to-const T for container<T>.
       *  @return  This %iterator, for chained operations.
       *
       *  This kind of %iterator doesn't really have a @a position in the
       *  container (you can think of the position as being permanently at
       *  the end, if you like).  Assigning a value to the %iterator will
       *  always append the value to the end of the container.
      */
#if __cplusplus < 201103L
      back_insert_iterator&
      operator=(typename _Container::const_reference __value)
      {
	container->push_back(__value);
	return *this;
      }
#else
      _GLIBCXX20_CONSTEXPR
      back_insert_iterator&
      operator=(const typename _Container::value_type& __value)
      {
	container->push_back(__value);
	return *this;
      }

      _GLIBCXX20_CONSTEXPR
      back_insert_iterator&
      operator=(typename _Container::value_type&& __value)
      {
	container->push_back(std::move(__value));
	return *this;
      }
#endif

      /// Simply returns *this.
      _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
      back_insert_iterator&
      operator*()
      { return *this; }

      /// Simply returns *this.  (This %iterator does not @a move.)
      _GLIBCXX20_CONSTEXPR
      back_insert_iterator&
      operator++()
      { return *this; }

      /// Simply returns *this.  (This %iterator does not @a move.)
      _GLIBCXX20_CONSTEXPR
      back_insert_iterator
      operator++(int)
      { return *this; }
    };

  /**
   *  @param  __x  A container of arbitrary type.
   *  @return  An instance of back_insert_iterator working on @p __x.
   *
   *  This wrapper function helps in creating back_insert_iterator instances.
   *  Typing the name of the %iterator requires knowing the precise full
   *  type of the container, which can be tedious and impedes generic
   *  programming.  Using this function lets you take advantage of automatic
   *  template parameter deduction, making the compiler match the correct
   *  types for you.
  */
  template<typename _Container>
    _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
    inline back_insert_iterator<_Container>
    back_inserter(_Container& __x)
    { return back_insert_iterator<_Container>(__x); }

  /**
   *  @brief  Turns assignment into insertion.
   *
   *  These are output iterators, constructed from a container-of-T.
   *  Assigning a T to the iterator prepends it to the container using
   *  push_front.
   *
   *  Tip:  Using the front_inserter function to create these iterators can
   *  save typing.
  */
  template<typename _Container>
    class front_insert_iterator
    : public iterator<output_iterator_tag, void, void, void, void>
    {
    protected:
      _Container* container;

    public:
      /// A nested typedef for the type of whatever container you used.
      typedef _Container          container_type;
#ifdef __glibcxx_ranges
      using difference_type = ptrdiff_t;
#endif

      /// The only way to create this %iterator is with a container.
      explicit _GLIBCXX20_CONSTEXPR
      front_insert_iterator(_Container& __x)
      : container(std::__addressof(__x)) { }

      /**
       *  @param  __value  An instance of whatever type
       *                 container_type::const_reference is; presumably a
       *                 reference-to-const T for container<T>.
       *  @return  This %iterator, for chained operations.
       *
       *  This kind of %iterator doesn't really have a @a position in the
       *  container (you can think of the position as being permanently at
       *  the front, if you like).  Assigning a value to the %iterator will
       *  always prepend the value to the front of the container.
      */
#if __cplusplus < 201103L
      front_insert_iterator&
      operator=(typename _Container::const_reference __value)
      {
	container->push_front(__value);
	return *this;
      }
#else
      _GLIBCXX20_CONSTEXPR
      front_insert_iterator&
      operator=(const typename _Container::value_type& __value)
      {
	container->push_front(__value);
	return *this;
      }

      _GLIBCXX20_CONSTEXPR
      front_insert_iterator&
      operator=(typename _Container::value_type&& __value)
      {
	container->push_front(std::move(__value));
	return *this;
      }
#endif

      /// Simply returns *this.
      _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
      front_insert_iterator&
      operator*()
      { return *this; }

      /// Simply returns *this.  (This %iterator does not @a move.)
      _GLIBCXX20_CONSTEXPR
      front_insert_iterator&
      operator++()
      { return *this; }

      /// Simply returns *this.  (This %iterator does not @a move.)
      _GLIBCXX20_CONSTEXPR
      front_insert_iterator
      operator++(int)
      { return *this; }
    };

  /**
   *  @param  __x  A container of arbitrary type.
   *  @return  An instance of front_insert_iterator working on @p x.
   *
   *  This wrapper function helps in creating front_insert_iterator instances.
   *  Typing the name of the %iterator requires knowing the precise full
   *  type of the container, which can be tedious and impedes generic
   *  programming.  Using this function lets you take advantage of automatic
   *  template parameter deduction, making the compiler match the correct
   *  types for you.
  */
  template<typename _Container>
    _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
    inline front_insert_iterator<_Container>
    front_inserter(_Container& __x)
    { return front_insert_iterator<_Container>(__x); }

  /**
   *  @brief  Turns assignment into insertion.
   *
   *  These are output iterators, constructed from a container-of-T.
   *  Assigning a T to the iterator inserts it in the container at the
   *  %iterator's position, rather than overwriting the value at that
   *  position.
   *
   *  (Sequences will actually insert a @e copy of the value before the
   *  %iterator's position.)
   *
   *  Tip:  Using the inserter function to create these iterators can
   *  save typing.
  */
  template<typename _Container>
    class insert_iterator
    : public iterator<output_iterator_tag, void, void, void, void>
    {
#ifdef __glibcxx_ranges
      using _Iter = std::__detail::__range_iter_t<_Container>;
#else
      typedef typename _Container::iterator		_Iter;
#endif
    protected:
      _Container* container;
      _Iter iter;

    public:
      /// A nested typedef for the type of whatever container you used.
      typedef _Container          container_type;

#ifdef __glibcxx_ranges
      using difference_type = ptrdiff_t;
#endif

      /**
       *  The only way to create this %iterator is with a container and an
       *  initial position (a normal %iterator into the container).
      */
      _GLIBCXX20_CONSTEXPR
      insert_iterator(_Container& __x, _Iter __i)
      : container(std::__addressof(__x)), iter(__i) {}

      /**
       *  @param  __value  An instance of whatever type
       *                 container_type::const_reference is; presumably a
       *                 reference-to-const T for container<T>.
       *  @return  This %iterator, for chained operations.
       *
       *  This kind of %iterator maintains its own position in the
       *  container.  Assigning a value to the %iterator will insert the
       *  value into the container at the place before the %iterator.
       *
       *  The position is maintained such that subsequent assignments will
       *  insert values immediately after one another.  For example,
       *  @code
       *     // vector v contains A and Z
       *
       *     insert_iterator i (v, ++v.begin());
       *     i = 1;
       *     i = 2;
       *     i = 3;
       *
       *     // vector v contains A, 1, 2, 3, and Z
       *  @endcode
      */
#if __cplusplus < 201103L
      insert_iterator&
      operator=(typename _Container::const_reference __value)
      {
	iter = container->insert(iter, __value);
	++iter;
	return *this;
      }
#else
      _GLIBCXX20_CONSTEXPR
      insert_iterator&
      operator=(const typename _Container::value_type& __value)
      {
	iter = container->insert(iter, __value);
	++iter;
	return *this;
      }

      _GLIBCXX20_CONSTEXPR
      insert_iterator&
      operator=(typename _Container::value_type&& __value)
      {
	iter = container->insert(iter, std::move(__value));
	++iter;
	return *this;
      }
#endif

      /// Simply returns *this.
      _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
      insert_iterator&
      operator*()
      { return *this; }

      /// Simply returns *this.  (This %iterator does not @a move.)
      _GLIBCXX20_CONSTEXPR
      insert_iterator&
      operator++()
      { return *this; }

      /// Simply returns *this.  (This %iterator does not @a move.)
      _GLIBCXX20_CONSTEXPR
      insert_iterator&
      operator++(int)
      { return *this; }
    };

#pragma GCC diagnostic pop

  /**
   *  @param __x  A container of arbitrary type.
   *  @param __i  An iterator into the container.
   *  @return  An instance of insert_iterator working on @p __x.
   *
   *  This wrapper function helps in creating insert_iterator instances.
   *  Typing the name of the %iterator requires knowing the precise full
   *  type of the container, which can be tedious and impedes generic
   *  programming.  Using this function lets you take advantage of automatic
   *  template parameter deduction, making the compiler match the correct
   *  types for you.
  */
#ifdef __glibcxx_ranges
  template<typename _Container>
    [[nodiscard]]
    constexpr insert_iterator<_Container>
    inserter(_Container& __x, std::__detail::__range_iter_t<_Container> __i)
    { return insert_iterator<_Container>(__x, __i); }
#else
  template<typename _Container>
    _GLIBCXX_NODISCARD
    inline insert_iterator<_Container>
    inserter(_Container& __x, typename _Container::iterator __i)
    { return insert_iterator<_Container>(__x, __i); }
#endif

  /// @} group iterators

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  // This iterator adapter is @a normal in the sense that it does not
  // change the semantics of any of the operators of its iterator
  // parameter.  Its primary purpose is to convert an iterator that is
  // not a class, e.g. a pointer, into an iterator that is a class.
  // The _Container parameter exists solely so that different containers
  // using this template can instantiate different types, even if the
  // _Iterator parameter is the same.
  template<typename _Iterator, typename _Container>
    class __normal_iterator
    {
    protected:
      _Iterator _M_current;

      typedef std::iterator_traits<_Iterator>		__traits_type;

#if __cplusplus >= 201103L && ! defined __glibcxx_concepts
      template<typename _Iter>
	using __convertible_from
	  = std::__enable_if_t<std::is_convertible<_Iter, _Iterator>::value>;
#endif

    public:
      typedef _Iterator					iterator_type;
      typedef typename __traits_type::iterator_category iterator_category;
      typedef typename __traits_type::value_type  	value_type;
      typedef typename __traits_type::difference_type 	difference_type;
      typedef typename __traits_type::reference 	reference;
      typedef typename __traits_type::pointer   	pointer;

#ifdef __glibcxx_ranges
      using iterator_concept = std::__detail::__iter_concept<_Iterator>;
#endif

      __attribute__((__always_inline__))
      _GLIBCXX_CONSTEXPR
      __normal_iterator() _GLIBCXX_NOEXCEPT
      : _M_current() { }

      __attribute__((__always_inline__))
      explicit _GLIBCXX_CONSTEXPR
      __normal_iterator(const _Iterator& __i) _GLIBCXX_NOEXCEPT
      : _M_current(__i) { }

      // Allow iterator to const_iterator conversion
#if __cplusplus >= 201103L
# ifdef __glibcxx_concepts
      template<typename _Iter> requires std::is_convertible_v<_Iter, _Iterator>
# else
      template<typename _Iter, typename = __convertible_from<_Iter>>
# endif
	[[__gnu__::__always_inline__]]
	constexpr
	__normal_iterator(const __normal_iterator<_Iter, _Container>& __i)
	noexcept
#else
      // N.B. _Container::pointer is not actually in container requirements,
      // but is present in std::vector and std::basic_string.
      template<typename _Iter>
	__attribute__((__always_inline__))
	__normal_iterator(const __normal_iterator<_Iter,
			  typename __enable_if<
	       (std::__are_same<_Iter, typename _Container::pointer>::__value),
		      _Container>::__type>& __i)
#endif
        : _M_current(__i.base()) { }

      // Forward iterator requirements

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      _GLIBCXX_CONSTEXPR
      reference
      operator*() const _GLIBCXX_NOEXCEPT
      { return *_M_current; }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      _GLIBCXX_CONSTEXPR
      pointer
      operator->() const _GLIBCXX_NOEXCEPT
      { return _M_current; }

      __attribute__((__always_inline__))
      _GLIBCXX14_CONSTEXPR
      __normal_iterator&
      operator++() _GLIBCXX_NOEXCEPT
      {
	++_M_current;
	return *this;
      }

      __attribute__((__always_inline__))
      _GLIBCXX14_CONSTEXPR
      __normal_iterator
      operator++(int) _GLIBCXX_NOEXCEPT
      { return __normal_iterator(_M_current++); }

      // Bidirectional iterator requirements

      __attribute__((__always_inline__))
      _GLIBCXX14_CONSTEXPR
      __normal_iterator&
      operator--() _GLIBCXX_NOEXCEPT
      {
	--_M_current;
	return *this;
      }

      __attribute__((__always_inline__))
      _GLIBCXX14_CONSTEXPR
      __normal_iterator
      operator--(int) _GLIBCXX_NOEXCEPT
      { return __normal_iterator(_M_current--); }

      // Random access iterator requirements

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      _GLIBCXX_CONSTEXPR
      reference
      operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
      { return _M_current[__n]; }

      __attribute__((__always_inline__))
      _GLIBCXX14_CONSTEXPR
      __normal_iterator&
      operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
      { _M_current += __n; return *this; }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      _GLIBCXX_CONSTEXPR
      __normal_iterator
      operator+(difference_type __n) const _GLIBCXX_NOEXCEPT
      { return __normal_iterator(_M_current + __n); }

      __attribute__((__always_inline__))
      _GLIBCXX14_CONSTEXPR
      __normal_iterator&
      operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
      { _M_current -= __n; return *this; }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      _GLIBCXX_CONSTEXPR
      __normal_iterator
      operator-(difference_type __n) const _GLIBCXX_NOEXCEPT
      { return __normal_iterator(_M_current - __n); }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      _GLIBCXX_CONSTEXPR
      const _Iterator&
      base() const _GLIBCXX_NOEXCEPT
      { return _M_current; }

    private:
      // Note: In what follows, the left- and right-hand-side iterators are
      // allowed to vary in types (conceptually in cv-qualification) so that
      // comparison between cv-qualified and non-cv-qualified iterators be
      // valid.  However, the greedy and unfriendly operators in std::rel_ops
      // will make overload resolution ambiguous (when in scope) if we don't
      // provide overloads whose operands are of the same type.  Can someone
      // remind me what generic programming is about? -- Gaby

#ifdef __cpp_lib_three_way_comparison
      template<typename _Iter>
	[[nodiscard, __gnu__::__always_inline__]]
	friend
	constexpr bool
	operator==(const __normal_iterator& __lhs,
		   const __normal_iterator<_Iter, _Container>& __rhs)
	noexcept(noexcept(__lhs.base() == __rhs.base()))
	requires requires {
	  { __lhs.base() == __rhs.base() } -> std::convertible_to<bool>;
	}
	{ return __lhs.base() == __rhs.base(); }

      [[nodiscard, __gnu__::__always_inline__]]
      friend
      constexpr bool
      operator==(const __normal_iterator& __lhs, const __normal_iterator& __rhs)
      noexcept(noexcept(__lhs.base() == __rhs.base()))
      requires requires {
	{ __lhs.base() == __rhs.base() } -> std::convertible_to<bool>;
      }
      { return __lhs.base() == __rhs.base(); }

      template<typename _Iter>
	[[nodiscard, __gnu__::__always_inline__]]
	friend
	constexpr std::__detail::__synth3way_t<_Iterator, _Iter>
	operator<=>(const __normal_iterator& __lhs,
		    const __normal_iterator<_Iter, _Container>& __rhs)
	noexcept(noexcept(std::__detail::__synth3way(__lhs.base(), __rhs.base())))
	requires requires {
	  std::__detail::__synth3way(__lhs.base(), __rhs.base());
	}
	{ return std::__detail::__synth3way(__lhs.base(), __rhs.base()); }
#else
       // Forward iterator requirements
      template<typename _Iter>
	_GLIBCXX_NODISCARD __attribute__((__always_inline__))
	friend
	_GLIBCXX_CONSTEXPR
	bool
	operator==(const __normal_iterator& __lhs,
		   const __normal_iterator<_Iter, _Container>& __rhs)
	_GLIBCXX_NOEXCEPT
	{ return __lhs.base() == __rhs.base(); }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      friend
      _GLIBCXX_CONSTEXPR
      bool
      operator==(const __normal_iterator& __lhs, const __normal_iterator& __rhs)
      _GLIBCXX_NOEXCEPT
      { return __lhs.base() == __rhs.base(); }

      template<typename _Iter>
	_GLIBCXX_NODISCARD __attribute__((__always_inline__))
	friend
	_GLIBCXX_CONSTEXPR
	bool
	operator!=(const __normal_iterator& __lhs,
		   const __normal_iterator<_Iter, _Container>& __rhs)
	_GLIBCXX_NOEXCEPT
	{ return __lhs.base() != __rhs.base(); }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      friend
      _GLIBCXX_CONSTEXPR
      bool
      operator!=(const __normal_iterator& __lhs, const __normal_iterator& __rhs)
      _GLIBCXX_NOEXCEPT
      { return __lhs.base() != __rhs.base(); }

      // Random access iterator requirements
      template<typename _Iter>
	_GLIBCXX_NODISCARD __attribute__((__always_inline__))
	friend
	_GLIBCXX_CONSTEXPR
	inline bool
	operator<(const __normal_iterator& __lhs,
		  const __normal_iterator<_Iter, _Container>& __rhs)
	_GLIBCXX_NOEXCEPT
	{ return __lhs.base() < __rhs.base(); }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      friend
      _GLIBCXX20_CONSTEXPR
      bool
      operator<(const __normal_iterator& __lhs, const __normal_iterator& __rhs)
      _GLIBCXX_NOEXCEPT
      { return __lhs.base() < __rhs.base(); }

      template<typename _Iter>
	_GLIBCXX_NODISCARD __attribute__((__always_inline__))
	friend
	_GLIBCXX_CONSTEXPR
	bool
	operator>(const __normal_iterator& __lhs,
		  const __normal_iterator<_Iter, _Container>& __rhs)
	_GLIBCXX_NOEXCEPT
	{ return __lhs.base() > __rhs.base(); }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      friend
      _GLIBCXX_CONSTEXPR
      bool
      operator>(const __normal_iterator& __lhs, const __normal_iterator& __rhs)
      _GLIBCXX_NOEXCEPT
      { return __lhs.base() > __rhs.base(); }

      template<typename _Iter>
	_GLIBCXX_NODISCARD __attribute__((__always_inline__))
	friend
	_GLIBCXX_CONSTEXPR
	bool
	operator<=(const __normal_iterator& __lhs,
		   const __normal_iterator<_Iter, _Container>& __rhs)
	_GLIBCXX_NOEXCEPT
	{ return __lhs.base() <= __rhs.base(); }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      friend
      _GLIBCXX_CONSTEXPR
      bool
      operator<=(const __normal_iterator& __lhs, const __normal_iterator& __rhs)
      _GLIBCXX_NOEXCEPT
      { return __lhs.base() <= __rhs.base(); }

      template<typename _Iter>
	_GLIBCXX_NODISCARD __attribute__((__always_inline__))
	friend
	_GLIBCXX_CONSTEXPR
	bool
	operator>=(const __normal_iterator& __lhs,
		   const __normal_iterator<_Iter, _Container>& __rhs)
	_GLIBCXX_NOEXCEPT
	{ return __lhs.base() >= __rhs.base(); }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      friend
      _GLIBCXX_CONSTEXPR
      bool
      operator>=(const __normal_iterator& __lhs, const __normal_iterator& __rhs)
      _GLIBCXX_NOEXCEPT
      { return __lhs.base() >= __rhs.base(); }
#endif // three-way comparison

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 179. Comparison of const_iterators to iterators doesn't work
      // According to the resolution of DR179 not only the various comparison
      // operators but also operator- must accept mixed iterator/const_iterator
      // parameters.
      template<typename _Iter>
#if __cplusplus >= 201103L
	[[__nodiscard__, __gnu__::__always_inline__]]
	friend
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 685. reverse_iterator/move_iterator difference has invalid signatures
	constexpr auto
	operator-(const __normal_iterator& __lhs,
		  const __normal_iterator<_Iter, _Container>& __rhs) noexcept
	-> decltype(__lhs.base() - __rhs.base())
#else
	friend
	difference_type
	operator-(const __normal_iterator& __lhs,
		  const __normal_iterator<_Iter, _Container>& __rhs)
#endif
	{ return __lhs.base() - __rhs.base(); }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      friend
      _GLIBCXX_CONSTEXPR
      difference_type
      operator-(const __normal_iterator& __lhs, const __normal_iterator& __rhs)
	_GLIBCXX_NOEXCEPT
      { return __lhs.base() - __rhs.base(); }

      _GLIBCXX_NODISCARD __attribute__((__always_inline__))
      friend
      _GLIBCXX_CONSTEXPR
      __normal_iterator
      operator+(difference_type __n, const __normal_iterator& __i)
	_GLIBCXX_NOEXCEPT
      { return __normal_iterator(__i.base() + __n); }
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __gnu_cxx

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#if __cplusplus >= 201103L
  /**
   * @addtogroup iterators
   * @{
   */

#ifdef __glibcxx_ranges
  /// A sentinel adaptor for use with std::move_iterator.
  template<semiregular _Sent>
    class move_sentinel
    {
    public:
      constexpr
      move_sentinel()
      noexcept(is_nothrow_default_constructible_v<_Sent>)
      : _M_last() { }

      constexpr explicit
      move_sentinel(_Sent __s)
      noexcept(is_nothrow_move_constructible_v<_Sent>)
      : _M_last(std::move(__s)) { }

      template<typename _S2> requires convertible_to<const _S2&, _Sent>
	constexpr
	move_sentinel(const move_sentinel<_S2>& __s)
	noexcept(is_nothrow_constructible_v<_Sent, const _S2&>)
	: _M_last(__s.base())
	{ }

      template<typename _S2> requires assignable_from<_Sent&, const _S2&>
	constexpr move_sentinel&
	operator=(const move_sentinel<_S2>& __s)
	noexcept(is_nothrow_assignable_v<_Sent, const _S2&>)
	{
	  _M_last = __s.base();
	  return *this;
	}

      [[nodiscard]]
      constexpr _Sent
      base() const
      noexcept(is_nothrow_copy_constructible_v<_Sent>)
      { return _M_last; }

    private:
      _Sent _M_last;
    };

  /// @cond undocumented
  namespace __detail
  {
    template<typename _Iterator>
      struct __move_iter_cat
      { };

    template<typename _Iterator>
      requires requires { typename __iter_category_t<_Iterator>; }
      struct __move_iter_cat<_Iterator>
      {
	using iterator_category
	  = __clamp_iter_cat<__iter_category_t<_Iterator>,
			     random_access_iterator_tag>;
      };
  }
  /// @endcond
#endif // ranges

  // 24.4.3  Move iterators
  /** @brief An iterator adaptor that yields an rvalue reference.
   *
   *  Class template move_iterator is an iterator adapter with the same
   *  behavior as the underlying iterator except that its dereference
   *  operator implicitly converts the value returned by the underlying
   *  iterator's dereference operator to an rvalue reference.  Some
   *  generic algorithms can be called with move iterators to replace
   *  copying with moving.
   */
  template<typename _Iterator>
    class move_iterator
#ifdef __glibcxx_ranges
      : public __detail::__move_iter_cat<_Iterator>
#endif
    {
      _Iterator _M_current;

      using __traits_type = iterator_traits<_Iterator>;
#ifndef __glibcxx_ranges
      using __base_ref = typename __traits_type::reference;
#endif

      template<typename _Iter2>
	friend class move_iterator;

#ifdef __glibcxx_concepts // C++20 && concepts
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3435. three_way_comparable_with<reverse_iterator<int*>, [...]>
      template<typename _Iter2>
	static constexpr bool __convertible = !is_same_v<_Iter2, _Iterator>
	    && convertible_to<const _Iter2&, _Iterator>;
#endif

#ifdef __glibcxx_ranges
      static auto
      _S_iter_concept()
      {
	if constexpr (random_access_iterator<_Iterator>)
	  return random_access_iterator_tag{};
	else if constexpr (bidirectional_iterator<_Iterator>)
	  return bidirectional_iterator_tag{};
	else if constexpr (forward_iterator<_Iterator>)
	  return forward_iterator_tag{};
	else
	  return input_iterator_tag{};
      }
#endif

    public:
      using iterator_type = _Iterator;

#ifdef __glibcxx_move_iterator_concept // C++ >= 20 && lib_concepts
      using iterator_concept = decltype(_S_iter_concept());

      // iterator_category defined in __move_iter_cat
      using value_type = iter_value_t<_Iterator>;
      using difference_type = iter_difference_t<_Iterator>;
      using pointer = _Iterator;
      using reference = iter_rvalue_reference_t<_Iterator>;
#else
      typedef typename __traits_type::iterator_category iterator_category;
      typedef typename __traits_type::value_type  	value_type;
      typedef typename __traits_type::difference_type	difference_type;
      // NB: DR 680.
      typedef _Iterator					pointer;
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2106. move_iterator wrapping iterators returning prvalues
      using reference
	= __conditional_t<is_reference<__base_ref>::value,
			  typename remove_reference<__base_ref>::type&&,
			  __base_ref>;
#endif

      _GLIBCXX17_CONSTEXPR
      move_iterator()
      : _M_current() { }

      explicit _GLIBCXX17_CONSTEXPR
      move_iterator(iterator_type __i)
      : _M_current(std::move(__i)) { }

      template<typename _Iter>
#ifdef __glibcxx_concepts
	requires __convertible<_Iter>
#endif
	_GLIBCXX17_CONSTEXPR
	move_iterator(const move_iterator<_Iter>& __i)
	: _M_current(__i._M_current) { }

      template<typename _Iter>
#ifdef __glibcxx_concepts
	requires __convertible<_Iter>
	  && assignable_from<_Iterator&, const _Iter&>
#endif
	_GLIBCXX17_CONSTEXPR
	move_iterator& operator=(const move_iterator<_Iter>& __i)
	{
	  _M_current = __i._M_current;
	  return *this;
	}

#if __cplusplus <= 201703L
      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR iterator_type
      base() const
      { return _M_current; }
#else
      [[nodiscard]]
      constexpr const iterator_type&
      base() const & noexcept
      { return _M_current; }

      [[nodiscard]]
      constexpr iterator_type
      base() &&
      { return std::move(_M_current); }
#endif

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR reference
      operator*() const
#ifdef __glibcxx_ranges
      { return ranges::iter_move(_M_current); }
#else
      { return static_cast<reference>(*_M_current); }
#endif

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR pointer
      operator->() const
      { return _M_current; }

      _GLIBCXX17_CONSTEXPR move_iterator&
      operator++()
      {
	++_M_current;
	return *this;
      }

      _GLIBCXX17_CONSTEXPR move_iterator
      operator++(int)
      {
	move_iterator __tmp = *this;
	++_M_current;
	return __tmp;
      }

#ifdef __glibcxx_concepts
      constexpr void
      operator++(int) requires (!forward_iterator<_Iterator>)
      { ++_M_current; }
#endif

      _GLIBCXX17_CONSTEXPR move_iterator&
      operator--()
      {
	--_M_current;
	return *this;
      }

      _GLIBCXX17_CONSTEXPR move_iterator
      operator--(int)
      {
	move_iterator __tmp = *this;
	--_M_current;
	return __tmp;
      }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR move_iterator
      operator+(difference_type __n) const
      { return move_iterator(_M_current + __n); }

      _GLIBCXX17_CONSTEXPR move_iterator&
      operator+=(difference_type __n)
      {
	_M_current += __n;
	return *this;
      }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR move_iterator
      operator-(difference_type __n) const
      { return move_iterator(_M_current - __n); }

      _GLIBCXX17_CONSTEXPR move_iterator&
      operator-=(difference_type __n)
      {
	_M_current -= __n;
	return *this;
      }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR reference
      operator[](difference_type __n) const
#ifdef __glibcxx_ranges
      { return ranges::iter_move(_M_current + __n); }
#else
      { return std::move(_M_current[__n]); }
#endif

#ifdef __glibcxx_ranges
      template<sentinel_for<_Iterator> _Sent>
	[[nodiscard]]
	friend constexpr bool
	operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
	{ return __x.base() == __y.base(); }

      template<sized_sentinel_for<_Iterator> _Sent>
	[[nodiscard]]
	friend constexpr iter_difference_t<_Iterator>
	operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y)
	{ return __x.base() - __y.base(); }

      template<sized_sentinel_for<_Iterator> _Sent>
	[[nodiscard]]
	friend constexpr iter_difference_t<_Iterator>
	operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y)
	{ return __x.base() - __y.base(); }

      [[nodiscard]]
      friend constexpr iter_rvalue_reference_t<_Iterator>
      iter_move(const move_iterator& __i)
      noexcept(noexcept(ranges::iter_move(__i._M_current)))
      { return ranges::iter_move(__i._M_current); }

      template<indirectly_swappable<_Iterator> _Iter2>
	friend constexpr void
	iter_swap(const move_iterator& __x, const move_iterator<_Iter2>& __y)
	noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
	{ return ranges::iter_swap(__x._M_current, __y._M_current); }
#endif // C++20
    };

  template<typename _IteratorL, typename _IteratorR>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator==(const move_iterator<_IteratorL>& __x,
	       const move_iterator<_IteratorR>& __y)
#ifdef __glibcxx_concepts
    requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; }
#endif
    { return __x.base() == __y.base(); }

#ifdef __cpp_lib_three_way_comparison
  template<typename _IteratorL,
	   three_way_comparable_with<_IteratorL> _IteratorR>
    [[__nodiscard__]]
    constexpr compare_three_way_result_t<_IteratorL, _IteratorR>
    operator<=>(const move_iterator<_IteratorL>& __x,
		const move_iterator<_IteratorR>& __y)
    { return __x.base() <=> __y.base(); }
#else
  template<typename _IteratorL, typename _IteratorR>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator!=(const move_iterator<_IteratorL>& __x,
	       const move_iterator<_IteratorR>& __y)
    { return !(__x == __y); }
#endif

  template<typename _IteratorL, typename _IteratorR>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator<(const move_iterator<_IteratorL>& __x,
	      const move_iterator<_IteratorR>& __y)
#ifdef __glibcxx_concepts
    requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
#endif
    { return __x.base() < __y.base(); }

  template<typename _IteratorL, typename _IteratorR>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator<=(const move_iterator<_IteratorL>& __x,
	       const move_iterator<_IteratorR>& __y)
#ifdef __glibcxx_concepts
    requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; }
#endif
    { return !(__y < __x); }

  template<typename _IteratorL, typename _IteratorR>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator>(const move_iterator<_IteratorL>& __x,
	      const move_iterator<_IteratorR>& __y)
#ifdef __glibcxx_concepts
    requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; }
#endif
    { return __y < __x; }

  template<typename _IteratorL, typename _IteratorR>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator>=(const move_iterator<_IteratorL>& __x,
	       const move_iterator<_IteratorR>& __y)
#ifdef __glibcxx_concepts
    requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
#endif
    { return !(__x < __y); }

  // Note: See __normal_iterator operators note from Gaby to understand
  // why we have these extra overloads for some move_iterator operators.

  template<typename _Iterator>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator==(const move_iterator<_Iterator>& __x,
	       const move_iterator<_Iterator>& __y)
    // N.B. No contraints, x.base() == y.base() is always well-formed.
    { return __x.base() == __y.base(); }

#ifdef __cpp_lib_three_way_comparison
  template<three_way_comparable _Iterator>
    [[__nodiscard__]]
    constexpr compare_three_way_result_t<_Iterator>
    operator<=>(const move_iterator<_Iterator>& __x,
		const move_iterator<_Iterator>& __y)
    { return __x.base() <=> __y.base(); }
#else
  template<typename _Iterator>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator!=(const move_iterator<_Iterator>& __x,
	       const move_iterator<_Iterator>& __y)
    { return !(__x == __y); }

  template<typename _Iterator>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator<(const move_iterator<_Iterator>& __x,
	      const move_iterator<_Iterator>& __y)
    { return __x.base() < __y.base(); }

  template<typename _Iterator>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator<=(const move_iterator<_Iterator>& __x,
	       const move_iterator<_Iterator>& __y)
    { return !(__y < __x); }

  template<typename _Iterator>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator>(const move_iterator<_Iterator>& __x,
	      const move_iterator<_Iterator>& __y)
    { return __y < __x; }

  template<typename _Iterator>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR bool
    operator>=(const move_iterator<_Iterator>& __x,
	       const move_iterator<_Iterator>& __y)
    { return !(__x < __y); }
#endif // ! C++20

  // DR 685.
  template<typename _IteratorL, typename _IteratorR>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR auto
    operator-(const move_iterator<_IteratorL>& __x,
	      const move_iterator<_IteratorR>& __y)
    -> decltype(__x.base() - __y.base())
    { return __x.base() - __y.base(); }

  template<typename _Iterator>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
    operator+(typename move_iterator<_Iterator>::difference_type __n,
	      const move_iterator<_Iterator>& __x)
#ifdef __glibcxx_concepts
    requires requires { { __x.base() + __n } -> same_as<_Iterator>; }
#endif
    { return __x + __n; }

  template<typename _Iterator>
    [[__nodiscard__]]
    inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
    make_move_iterator(_Iterator __i)
    { return move_iterator<_Iterator>(std::move(__i)); }

  template<typename _Iterator, typename _ReturnType
    = __conditional_t<__move_if_noexcept_cond
      <typename iterator_traits<_Iterator>::value_type>::value,
		_Iterator, move_iterator<_Iterator>>>
    [[__nodiscard__]]
    constexpr _ReturnType
    __make_move_if_noexcept_iterator(_Iterator __i)
    { return _ReturnType(__i); }

  // Overload for pointers that matches std::move_if_noexcept more closely,
  // returning a constant iterator when we don't want to move.
  template<typename _Tp, typename _ReturnType
    = __conditional_t<__move_if_noexcept_cond<_Tp>::value,
		      const _Tp*, move_iterator<_Tp*>>>
    [[__nodiscard__]]
    constexpr _ReturnType
    __make_move_if_noexcept_iterator(_Tp* __i)
    { return _ReturnType(__i); }

  template<typename _Iterator>
    struct __is_move_iterator<move_iterator<_Iterator> >
    {
      enum { __value = 1 };
      typedef __true_type __type;
    };

#define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) std::make_move_iterator(_Iter)
#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) \
  std::__make_move_if_noexcept_iterator(_Iter)
#else
#define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) (_Iter)
#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) (_Iter)
#endif // C++11

#ifdef __glibcxx_ranges
  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 3736.  move_iterator missing disable_sized_sentinel_for specialization
  template<typename _Iterator1, typename _Iterator2>
    requires (!sized_sentinel_for<_Iterator1, _Iterator2>)
    inline constexpr bool
    disable_sized_sentinel_for<move_iterator<_Iterator1>,
			       move_iterator<_Iterator2>> = true;

  // [iterators.common] Common iterators

  /// @cond undocumented
  namespace __detail
  {
    template<typename _It>
      concept __common_iter_has_arrow = indirectly_readable<const _It>
	&& (requires(const _It& __it) { __it.operator->(); }
	    || is_reference_v<iter_reference_t<_It>>
	    || constructible_from<iter_value_t<_It>, iter_reference_t<_It>>);

    template<typename _It>
      concept __common_iter_use_postfix_proxy
	= (!requires (_It& __i) { { *__i++ } -> __can_reference; })
	  && constructible_from<iter_value_t<_It>, iter_reference_t<_It>>
	  && move_constructible<iter_value_t<_It>>;
  } // namespace __detail
  /// @endcond

  /// An iterator/sentinel adaptor for representing a non-common range.
  template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
    requires (!same_as<_It, _Sent>) && copyable<_It>
  class common_iterator
  {
    template<typename _Tp, typename _Up>
      static constexpr bool
      _S_noexcept1()
      {
	if constexpr (is_trivially_default_constructible_v<_Tp>)
	  return is_nothrow_assignable_v<_Tp&, _Up>;
	else
	  return is_nothrow_constructible_v<_Tp, _Up>;
      }

    template<typename _It2, typename _Sent2>
      static constexpr bool
      _S_noexcept()
      { return _S_noexcept1<_It, _It2>() && _S_noexcept1<_Sent, _Sent2>(); }

    class __arrow_proxy
    {
      iter_value_t<_It> _M_keep;

      constexpr
      __arrow_proxy(iter_reference_t<_It>&& __x)
      : _M_keep(std::move(__x)) { }

      friend class common_iterator;

    public:
      constexpr const iter_value_t<_It>*
      operator->() const noexcept
      { return std::__addressof(_M_keep); }
    };

    class __postfix_proxy
    {
      iter_value_t<_It> _M_keep;

      constexpr
      __postfix_proxy(iter_reference_t<_It>&& __x)
      : _M_keep(std::forward<iter_reference_t<_It>>(__x)) { }

      friend class common_iterator;

    public:
      constexpr const iter_value_t<_It>&
      operator*() const noexcept
      { return _M_keep; }
    };

  public:
    constexpr
    common_iterator()
    noexcept(is_nothrow_default_constructible_v<_It>)
    requires default_initializable<_It>
    : _M_it(), _M_index(0)
    { }

    constexpr
    common_iterator(_It __i)
    noexcept(is_nothrow_move_constructible_v<_It>)
    : _M_it(std::move(__i)), _M_index(0)
    { }

    constexpr
    common_iterator(_Sent __s)
    noexcept(is_nothrow_move_constructible_v<_Sent>)
    : _M_sent(std::move(__s)), _M_index(1)
    { }

    template<typename _It2, typename _Sent2>
      requires convertible_to<const _It2&, _It>
	&& convertible_to<const _Sent2&, _Sent>
      constexpr
      common_iterator(const common_iterator<_It2, _Sent2>& __x)
      noexcept(_S_noexcept<const _It2&, const _Sent2&>())
      : _M_valueless(), _M_index(__x._M_index)
      {
	__glibcxx_assert(__x._M_has_value());
	if (_M_index == 0)
	  {
	    if constexpr (is_trivially_default_constructible_v<_It>)
	      _M_it = std::move(__x._M_it);
	    else
	      std::construct_at(std::__addressof(_M_it), __x._M_it);
	  }
	else if (_M_index == 1)
	  {
	    if constexpr (is_trivially_default_constructible_v<_Sent>)
	      _M_sent = std::move(__x._M_sent);
	    else
	      std::construct_at(std::__addressof(_M_sent), __x._M_sent);
	  }
      }

    common_iterator(const common_iterator&) = default;

    constexpr
    common_iterator(const common_iterator& __x)
    noexcept(_S_noexcept<const _It&, const _Sent&>())
    requires (!is_trivially_copyable_v<_It> || !is_trivially_copyable_v<_Sent>)
    : _M_valueless(), _M_index(__x._M_index)
    {
      if (_M_index == 0)
	{
	  if constexpr (is_trivially_default_constructible_v<_It>)
	    _M_it = __x._M_it;
	  else
	    std::construct_at(std::__addressof(_M_it), __x._M_it);
	}
      else if (_M_index == 1)
	{
	  if constexpr (is_trivially_default_constructible_v<_Sent>)
	    _M_sent = __x._M_sent;
	  else
	    std::construct_at(std::__addressof(_M_sent), __x._M_sent);
	}
    }

    common_iterator(common_iterator&&) = default;

    constexpr
    common_iterator(common_iterator&& __x)
    noexcept(_S_noexcept<_It, _Sent>())
    requires (!is_trivially_copyable_v<_It> || !is_trivially_copyable_v<_Sent>)
    : _M_valueless(), _M_index(__x._M_index)
    {
      if (_M_index == 0)
	{
	  if constexpr (is_trivially_default_constructible_v<_It>)
	    _M_it = std::move(__x._M_it);
	  else
	    std::construct_at(std::__addressof(_M_it), std::move(__x._M_it));
	}
      else if (_M_index == 1)
	{
	  if constexpr (is_trivially_default_constructible_v<_Sent>)
	    _M_sent = std::move(__x._M_sent);
	  else
	    std::construct_at(std::__addressof(_M_sent),
			      std::move(__x._M_sent));
	}
    }

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

    constexpr common_iterator&
    operator=(const common_iterator& __x)
    noexcept(is_nothrow_copy_assignable_v<_It>
	     && is_nothrow_copy_assignable_v<_Sent>
	     && is_nothrow_copy_constructible_v<_It>
	     && is_nothrow_copy_constructible_v<_Sent>)
    requires (!is_trivially_copy_assignable_v<_It>
		|| !is_trivially_copy_assignable_v<_Sent>)
    {
      _M_assign(__x);
      return *this;
    }

    constexpr common_iterator&
    operator=(common_iterator&&) = default;

    constexpr common_iterator&
    operator=(common_iterator&& __x)
    noexcept(is_nothrow_move_assignable_v<_It>
	     && is_nothrow_move_assignable_v<_Sent>
	     && is_nothrow_move_constructible_v<_It>
	     && is_nothrow_move_constructible_v<_Sent>)
    requires (!is_trivially_move_assignable_v<_It>
		|| !is_trivially_move_assignable_v<_Sent>)
    {
      _M_assign(std::move(__x));
      return *this;
    }

    template<typename _It2, typename _Sent2>
      requires convertible_to<const _It2&, _It>
	&& convertible_to<const _Sent2&, _Sent>
	&& assignable_from<_It&, const _It2&>
	&& assignable_from<_Sent&, const _Sent2&>
      constexpr common_iterator&
      operator=(const common_iterator<_It2, _Sent2>& __x)
      noexcept(is_nothrow_constructible_v<_It, const _It2&>
	       && is_nothrow_constructible_v<_Sent, const _Sent2&>
	       && is_nothrow_assignable_v<_It&, const _It2&>
	       && is_nothrow_assignable_v<_Sent&, const _Sent2&>)
      {
	__glibcxx_assert(__x._M_has_value());
	_M_assign(__x);
	return *this;
      }

#if __cpp_concepts >= 202002L // Constrained special member functions
    ~common_iterator() = default;

    constexpr
    ~common_iterator()
      requires (!is_trivially_destructible_v<_It>
		  || !is_trivially_destructible_v<_Sent>)
#else
    constexpr
    ~common_iterator()
#endif
    {
      if (_M_index == 0)
	_M_it.~_It();
      else if (_M_index == 1)
	_M_sent.~_Sent();
    }

    [[nodiscard]]
    constexpr decltype(auto)
    operator*()
    {
      __glibcxx_assert(_M_index == 0);
      return *_M_it;
    }

    [[nodiscard]]
    constexpr decltype(auto)
    operator*() const requires __detail::__dereferenceable<const _It>
    {
      __glibcxx_assert(_M_index == 0);
      return *_M_it;
    }

    [[nodiscard]]
    constexpr auto
    operator->() const requires __detail::__common_iter_has_arrow<_It>
    {
      __glibcxx_assert(_M_index == 0);
      if constexpr (is_pointer_v<_It> || requires { _M_it.operator->(); })
	return _M_it;
      else if constexpr (is_reference_v<iter_reference_t<_It>>)
	{
	  auto&& __tmp = *_M_it;
	  return std::__addressof(__tmp);
	}
      else
	return __arrow_proxy{*_M_it};
    }

    constexpr common_iterator&
    operator++()
    {
      __glibcxx_assert(_M_index == 0);
      ++_M_it;
      return *this;
    }

    constexpr decltype(auto)
    operator++(int)
    {
      __glibcxx_assert(_M_index == 0);
      if constexpr (forward_iterator<_It>)
	{
	  common_iterator __tmp = *this;
	  ++*this;
	  return __tmp;
	}
      else if constexpr (!__detail::__common_iter_use_postfix_proxy<_It>)
	return _M_it++;
      else
	{
	  __postfix_proxy __p(**this);
	  ++*this;
	  return __p;
	}
    }

    template<typename _It2, sentinel_for<_It> _Sent2>
      requires sentinel_for<_Sent, _It2>
      friend constexpr bool
      operator== [[nodiscard]] (const common_iterator& __x,
				const common_iterator<_It2, _Sent2>& __y)
      {
	switch(__x._M_index << 2 | __y._M_index)
	  {
	  case 0b0000:
	  case 0b0101:
	    return true;
	  case 0b0001:
	    return __x._M_it == __y._M_sent;
	  case 0b0100:
	    return __x._M_sent == __y._M_it;
	  default:
	    __glibcxx_assert(__x._M_has_value());
	    __glibcxx_assert(__y._M_has_value());
	    __builtin_unreachable();
	  }
      }

    template<typename _It2, sentinel_for<_It> _Sent2>
      requires sentinel_for<_Sent, _It2> && equality_comparable_with<_It, _It2>
      friend constexpr bool
      operator== [[nodiscard]] (const common_iterator& __x,
				const common_iterator<_It2, _Sent2>& __y)
      {
	switch(__x._M_index << 2 | __y._M_index)
	  {
	  case 0b0101:
	    return true;
	  case 0b0000:
	    return __x._M_it == __y._M_it;
	  case 0b0001:
	    return __x._M_it == __y._M_sent;
	  case 0b0100:
	    return __x._M_sent == __y._M_it;
	  default:
	    __glibcxx_assert(__x._M_has_value());
	    __glibcxx_assert(__y._M_has_value());
	    __builtin_unreachable();
	  }
      }

    template<sized_sentinel_for<_It> _It2, sized_sentinel_for<_It> _Sent2>
      requires sized_sentinel_for<_Sent, _It2>
      friend constexpr iter_difference_t<_It2>
      operator- [[nodiscard]] (const common_iterator& __x,
			       const common_iterator<_It2, _Sent2>& __y)
      {
	switch(__x._M_index << 2 | __y._M_index)
	  {
	  case 0b0101:
	    return 0;
	  case 0b0000:
	    return __x._M_it - __y._M_it;
	  case 0b0001:
	    return __x._M_it - __y._M_sent;
	  case 0b0100:
	    return __x._M_sent - __y._M_it;
	  default:
	    __glibcxx_assert(__x._M_has_value());
	    __glibcxx_assert(__y._M_has_value());
	    __builtin_unreachable();
	  }
      }

    [[nodiscard]]
    friend constexpr iter_rvalue_reference_t<_It>
    iter_move(const common_iterator& __i)
    noexcept(noexcept(ranges::iter_move(std::declval<const _It&>())))
    requires input_iterator<_It>
    {
      __glibcxx_assert(__i._M_index == 0);
      return ranges::iter_move(__i._M_it);
    }

    template<indirectly_swappable<_It> _It2, typename _Sent2>
      friend constexpr void
      iter_swap(const common_iterator& __x,
		const common_iterator<_It2, _Sent2>& __y)
      noexcept(noexcept(ranges::iter_swap(std::declval<const _It&>(),
					  std::declval<const _It2&>())))
      {
	__glibcxx_assert(__x._M_index == 0);
	__glibcxx_assert(__y._M_index == 0);
	return ranges::iter_swap(__x._M_it, __y._M_it);
      }

  private:
    template<input_or_output_iterator _It2, sentinel_for<_It2> _Sent2>
      requires (!same_as<_It2, _Sent2>) && copyable<_It2>
      friend class common_iterator;

    constexpr bool
    _M_has_value() const noexcept { return _M_index != _S_valueless; }

    template<typename _CIt>
      constexpr void
      _M_assign(_CIt&& __x)
      {
	if (_M_index == __x._M_index)
	  {
	    if (_M_index == 0)
	      _M_it = std::forward<_CIt>(__x)._M_it;
	    else if (_M_index == 1)
	      _M_sent = std::forward<_CIt>(__x)._M_sent;
	  }
	else
	  {
	    if (_M_index == 0)
	      _M_it.~_It();
	    else if (_M_index == 1)
	      _M_sent.~_Sent();
	    _M_index = _S_valueless;

	    if (__x._M_index == 0)
	      std::construct_at(std::__addressof(_M_it),
				std::forward<_CIt>(__x)._M_it);
	    else if (__x._M_index == 1)
	      std::construct_at(std::__addressof(_M_sent),
				std::forward<_CIt>(__x)._M_sent);
	    _M_index = __x._M_index;
	  }
      }

    union
    {
      _It _M_it;
      _Sent _M_sent;
      unsigned char _M_valueless;
    };
    unsigned char _M_index; // 0 == _M_it, 1 == _M_sent, 2 == valueless

    static constexpr unsigned char _S_valueless{2};
  };

  template<typename _It, typename _Sent>
    struct incrementable_traits<common_iterator<_It, _Sent>>
    {
      using difference_type = iter_difference_t<_It>;
    };

  template<input_iterator _It, typename _Sent>
    struct iterator_traits<common_iterator<_It, _Sent>>
    {
    private:
      template<typename _Iter>
	struct __ptr
	{
	  using type = void;
	};

      template<typename _Iter>
	requires __detail::__common_iter_has_arrow<_Iter>
	struct __ptr<_Iter>
	{
	  using _CIter = common_iterator<_Iter, _Sent>;
	  using type = decltype(std::declval<const _CIter&>().operator->());
	};

      static auto
      _S_iter_cat()
      {
	if constexpr (requires { requires derived_from<__iter_category_t<_It>,
						       forward_iterator_tag>; })
	  return forward_iterator_tag{};
	else
	  return input_iterator_tag{};
      }

    public:
      using iterator_concept = __conditional_t<forward_iterator<_It>,
					       forward_iterator_tag,
					       input_iterator_tag>;
      using iterator_category = decltype(_S_iter_cat());
      using value_type = iter_value_t<_It>;
      using difference_type = iter_difference_t<_It>;
      using pointer = typename __ptr<_It>::type;
      using reference = iter_reference_t<_It>;
    };

  // [iterators.counted] Counted iterators

  /// @cond undocumented
  namespace __detail
  {
    template<typename _It>
      struct __counted_iter_value_type
      { };

    template<indirectly_readable _It>
      struct __counted_iter_value_type<_It>
      { using value_type = iter_value_t<_It>; };

    template<typename _It>
      struct __counted_iter_concept
      { };

    template<typename _It>
      requires requires { typename _It::iterator_concept; }
      struct __counted_iter_concept<_It>
      { using iterator_concept = typename _It::iterator_concept; };

    template<typename _It>
      struct __counted_iter_cat
      { };

    template<typename _It>
      requires requires { typename _It::iterator_category; }
      struct __counted_iter_cat<_It>
      { using iterator_category = typename _It::iterator_category; };
  }
  /// @endcond

  /// An iterator adaptor that keeps track of the distance to the end.
  template<input_or_output_iterator _It>
    class counted_iterator
      : public __detail::__counted_iter_value_type<_It>,
	public __detail::__counted_iter_concept<_It>,
	public __detail::__counted_iter_cat<_It>
    {
    public:
      using iterator_type = _It;
      // value_type defined in __counted_iter_value_type
      using difference_type = iter_difference_t<_It>;
      // iterator_concept defined in __counted_iter_concept
      // iterator_category defined in __counted_iter_cat

      constexpr counted_iterator() requires default_initializable<_It> = default;

      constexpr
      counted_iterator(_It __i, iter_difference_t<_It> __n)
      : _M_current(std::move(__i)), _M_length(__n)
      { __glibcxx_assert(__n >= 0); }

      template<typename _It2>
	requires convertible_to<const _It2&, _It>
	constexpr
	counted_iterator(const counted_iterator<_It2>& __x)
	: _M_current(__x._M_current), _M_length(__x._M_length)
	{ }

      template<typename _It2>
	requires assignable_from<_It&, const _It2&>
	constexpr counted_iterator&
	operator=(const counted_iterator<_It2>& __x)
	{
	  _M_current = __x._M_current;
	  _M_length = __x._M_length;
	  return *this;
	}

      [[nodiscard]]
      constexpr const _It&
      base() const & noexcept
      { return _M_current; }

      [[nodiscard]]
      constexpr _It
      base() &&
      noexcept(is_nothrow_move_constructible_v<_It>)
      { return std::move(_M_current); }

      [[nodiscard]]
      constexpr iter_difference_t<_It>
      count() const noexcept { return _M_length; }

      [[nodiscard]]
      constexpr decltype(auto)
      operator*()
      noexcept(noexcept(*_M_current))
      {
	__glibcxx_assert( _M_length > 0 );
	return *_M_current;
      }

      [[nodiscard]]
      constexpr decltype(auto)
      operator*() const
      noexcept(noexcept(*_M_current))
      requires __detail::__dereferenceable<const _It>
      {
	__glibcxx_assert( _M_length > 0 );
	return *_M_current;
      }

      [[nodiscard]]
      constexpr auto
      operator->() const noexcept
      requires contiguous_iterator<_It>
      { return std::to_address(_M_current); }

      constexpr counted_iterator&
      operator++()
      {
	__glibcxx_assert(_M_length > 0);
	++_M_current;
	--_M_length;
	return *this;
      }

      constexpr decltype(auto)
      operator++(int)
      {
	__glibcxx_assert(_M_length > 0);
	--_M_length;
	__try
	  {
	    return _M_current++;
	  } __catch(...) {
	    ++_M_length;
	    __throw_exception_again;
	  }
      }

      constexpr counted_iterator
      operator++(int) requires forward_iterator<_It>
      {
	auto __tmp = *this;
	++*this;
	return __tmp;
      }

      constexpr counted_iterator&
      operator--() requires bidirectional_iterator<_It>
      {
	--_M_current;
	++_M_length;
	return *this;
      }

      constexpr counted_iterator
      operator--(int) requires bidirectional_iterator<_It>
      {
	auto __tmp = *this;
	--*this;
	return __tmp;
      }

      [[nodiscard]]
      constexpr counted_iterator
      operator+(iter_difference_t<_It> __n) const
	requires random_access_iterator<_It>
      { return counted_iterator(_M_current + __n, _M_length - __n); }

      [[nodiscard]]
      friend constexpr counted_iterator
      operator+(iter_difference_t<_It> __n, const counted_iterator& __x)
      requires random_access_iterator<_It>
      { return __x + __n; }

      constexpr counted_iterator&
      operator+=(iter_difference_t<_It> __n)
      requires random_access_iterator<_It>
      {
	__glibcxx_assert(__n <= _M_length);
	_M_current += __n;
	_M_length -= __n;
	return *this;
      }

      [[nodiscard]]
      constexpr counted_iterator
      operator-(iter_difference_t<_It> __n) const
      requires random_access_iterator<_It>
      { return counted_iterator(_M_current - __n, _M_length + __n); }

      template<common_with<_It> _It2>
	[[nodiscard]]
	friend constexpr iter_difference_t<_It2>
	operator-(const counted_iterator& __x,
		  const counted_iterator<_It2>& __y) noexcept
	{ return __y._M_length - __x._M_length; }

      [[nodiscard]]
      friend constexpr iter_difference_t<_It>
      operator-(const counted_iterator& __x, default_sentinel_t) noexcept
      { return -__x._M_length; }

      [[nodiscard]]
      friend constexpr iter_difference_t<_It>
      operator-(default_sentinel_t, const counted_iterator& __y) noexcept
      { return __y._M_length; }

      constexpr counted_iterator&
      operator-=(iter_difference_t<_It> __n)
      requires random_access_iterator<_It>
      {
	__glibcxx_assert(-__n <= _M_length);
	_M_current -= __n;
	_M_length += __n;
	return *this;
      }

      [[nodiscard]]
      constexpr decltype(auto)
      operator[](iter_difference_t<_It> __n) const
      noexcept(noexcept(_M_current[__n]))
      requires random_access_iterator<_It>
      {
	__glibcxx_assert(__n < _M_length);
	return _M_current[__n];
      }

      template<common_with<_It> _It2>
	[[nodiscard]]
	friend constexpr bool
	operator==(const counted_iterator& __x,
		   const counted_iterator<_It2>& __y) noexcept
	{ return __x._M_length == __y._M_length; }

      [[nodiscard]]
      friend constexpr bool
      operator==(const counted_iterator& __x, default_sentinel_t) noexcept
      { return __x._M_length == 0; }

      template<common_with<_It> _It2>
	[[nodiscard]]
	friend constexpr strong_ordering
	operator<=>(const counted_iterator& __x,
		    const counted_iterator<_It2>& __y) noexcept
	{ return __y._M_length <=> __x._M_length; }

      [[nodiscard]]
      friend constexpr iter_rvalue_reference_t<_It>
      iter_move(const counted_iterator& __i)
      noexcept(noexcept(ranges::iter_move(__i._M_current)))
      requires input_iterator<_It>
      {
	__glibcxx_assert( __i._M_length > 0 );
	return ranges::iter_move(__i._M_current);
      }

      template<indirectly_swappable<_It> _It2>
	friend constexpr void
	iter_swap(const counted_iterator& __x,
		  const counted_iterator<_It2>& __y)
	noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
	{
	  __glibcxx_assert( __x._M_length > 0 && __y._M_length > 0 );
	  ranges::iter_swap(__x._M_current, __y._M_current);
	}

    private:
      template<input_or_output_iterator _It2> friend class counted_iterator;

      _It _M_current = _It();
      iter_difference_t<_It> _M_length = 0;
    };

  template<input_iterator _It>
    requires same_as<__detail::__iter_traits<_It>, iterator_traits<_It>>
    struct iterator_traits<counted_iterator<_It>> : iterator_traits<_It>
    {
      using pointer = __conditional_t<contiguous_iterator<_It>,
				      add_pointer_t<iter_reference_t<_It>>,
				      void>;
    };

#ifdef __glibcxx_ranges_as_const // >= C++23
  template<indirectly_readable _It>
    using iter_const_reference_t
      = common_reference_t<const iter_value_t<_It>&&, iter_reference_t<_It>>;

  template<input_iterator _It> class basic_const_iterator;

  namespace __detail
  {
    template<typename _It>
      concept __constant_iterator = input_iterator<_It>
	&& same_as<iter_const_reference_t<_It>, iter_reference_t<_It>>;

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

    template<typename _It>
      inline constexpr bool __is_const_iterator<basic_const_iterator<_It>> = true;

    template<typename _Tp>
      concept __not_a_const_iterator = !__is_const_iterator<_Tp>;

    template<indirectly_readable _It>
      using __iter_const_rvalue_reference_t
	= common_reference_t<const iter_value_t<_It>&&, iter_rvalue_reference_t<_It>>;

    template<typename _It>
      struct __basic_const_iterator_iter_cat
      { };

    template<forward_iterator _It>
      struct __basic_const_iterator_iter_cat<_It>
      { using iterator_category = __iter_category_t<_It>; };
  } // namespace detail

  template<input_iterator _It>
    using const_iterator
      = __conditional_t<__detail::__constant_iterator<_It>, _It, basic_const_iterator<_It>>;

  namespace __detail
  {
    template<typename _Sent>
      struct __const_sentinel
      { using type = _Sent; };

    template<input_iterator _Sent>
      struct __const_sentinel<_Sent>
      { using type = const_iterator<_Sent>; };
  } // namespace __detail

  template<semiregular _Sent>
    using const_sentinel = typename __detail::__const_sentinel<_Sent>::type;

  template<input_iterator _It>
  class basic_const_iterator
  : public __detail::__basic_const_iterator_iter_cat<_It>
  {
    _It _M_current = _It();
    using __reference = iter_const_reference_t<_It>;
    using __rvalue_reference = __detail::__iter_const_rvalue_reference_t<_It>;

    static auto
    _S_iter_concept()
    {
      if constexpr (contiguous_iterator<_It>)
	return contiguous_iterator_tag{};
      else if constexpr (random_access_iterator<_It>)
	return random_access_iterator_tag{};
      else if constexpr (bidirectional_iterator<_It>)
	return bidirectional_iterator_tag{};
      else if constexpr (forward_iterator<_It>)
	return forward_iterator_tag{};
      else
	return input_iterator_tag{};
    }

    template<input_iterator _It2> friend class basic_const_iterator;

  public:
    using iterator_concept = decltype(_S_iter_concept());
    using value_type = iter_value_t<_It>;
    using difference_type = iter_difference_t<_It>;

    basic_const_iterator() requires default_initializable<_It> = default;

    constexpr
    basic_const_iterator(_It __current)
    noexcept(is_nothrow_move_constructible_v<_It>)
    : _M_current(std::move(__current))
    { }

    template<convertible_to<_It> _It2>
      constexpr
      basic_const_iterator(basic_const_iterator<_It2> __current)
      noexcept(is_nothrow_constructible_v<_It, _It2>)
      : _M_current(std::move(__current._M_current))
      { }

    template<__detail::__different_from<basic_const_iterator> _Tp>
      requires convertible_to<_Tp, _It>
      constexpr
      basic_const_iterator(_Tp&& __current)
      noexcept(is_nothrow_constructible_v<_It, _Tp>)
      : _M_current(std::forward<_Tp>(__current))
      { }

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

    constexpr _It
    base() &&
    noexcept(is_nothrow_move_constructible_v<_It>)
    { return std::move(_M_current); }

    constexpr __reference
    operator*() const
    noexcept(noexcept(static_cast<__reference>(*_M_current)))
    { return static_cast<__reference>(*_M_current); }

    constexpr const auto*
    operator->() const
    noexcept(contiguous_iterator<_It> || noexcept(*_M_current))
    requires is_lvalue_reference_v<iter_reference_t<_It>>
      && same_as<remove_cvref_t<iter_reference_t<_It>>, value_type>
    {
      if constexpr (contiguous_iterator<_It>)
	return std::to_address(_M_current);
      else
	return std::__addressof(*_M_current);
    }

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

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

    constexpr basic_const_iterator
    operator++(int)
    noexcept(noexcept(++*this) && is_nothrow_copy_constructible_v<basic_const_iterator>)
    requires forward_iterator<_It>
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    constexpr basic_const_iterator&
    operator--()
    noexcept(noexcept(--_M_current))
    requires bidirectional_iterator<_It>
    {
      --_M_current;
      return *this;
    }

    constexpr basic_const_iterator
    operator--(int)
    noexcept(noexcept(--*this) && is_nothrow_copy_constructible_v<basic_const_iterator>)
    requires bidirectional_iterator<_It>
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    constexpr basic_const_iterator&
    operator+=(difference_type __n)
    noexcept(noexcept(_M_current += __n))
    requires random_access_iterator<_It>
    {
      _M_current += __n;
      return *this;
    }

    constexpr basic_const_iterator&
    operator-=(difference_type __n)
    noexcept(noexcept(_M_current -= __n))
    requires random_access_iterator<_It>
    {
      _M_current -= __n;
      return *this;
    }

    constexpr __reference
    operator[](difference_type __n) const
    noexcept(noexcept(static_cast<__reference>(_M_current[__n])))
    requires random_access_iterator<_It>
    { return static_cast<__reference>(_M_current[__n]); }

    template<sentinel_for<_It> _Sent>
      constexpr bool
      operator==(const _Sent& __s) const
      noexcept(noexcept(_M_current == __s))
      { return _M_current == __s; }

    template<__detail::__not_a_const_iterator _CIt>
      requires __detail::__constant_iterator<_CIt> && convertible_to<_It, _CIt>
    constexpr
    operator _CIt() const&
    { return _M_current; }

    template<__detail::__not_a_const_iterator _CIt>
      requires __detail::__constant_iterator<_CIt> && convertible_to<_It, _CIt>
    constexpr
    operator _CIt() &&
    { return std::move(_M_current); }

    constexpr bool
    operator<(const basic_const_iterator& __y) const
    noexcept(noexcept(_M_current < __y._M_current))
    requires random_access_iterator<_It>
    { return _M_current < __y._M_current; }

    constexpr bool
    operator>(const basic_const_iterator& __y) const
    noexcept(noexcept(_M_current > __y._M_current))
    requires random_access_iterator<_It>
    { return _M_current > __y._M_current; }

    constexpr bool
    operator<=(const basic_const_iterator& __y) const
    noexcept(noexcept(_M_current <= __y._M_current))
    requires random_access_iterator<_It>
    { return _M_current <= __y._M_current; }

    constexpr bool
    operator>=(const basic_const_iterator& __y) const
    noexcept(noexcept(_M_current >= __y._M_current))
    requires random_access_iterator<_It>
    { return _M_current >= __y._M_current; }

    constexpr auto
    operator<=>(const basic_const_iterator& __y) const
    noexcept(noexcept(_M_current <=> __y._M_current))
    requires random_access_iterator<_It> && three_way_comparable<_It>
    { return _M_current <=> __y._M_current; }

    template<__detail::__different_from<basic_const_iterator> _It2>
      constexpr bool
      operator<(const _It2& __y) const
      noexcept(noexcept(_M_current < __y))
      requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
      { return _M_current < __y; }

    template<__detail::__different_from<basic_const_iterator> _It2>
      constexpr bool
      operator>(const _It2& __y) const
      noexcept(noexcept(_M_current > __y))
      requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
      { return _M_current > __y; }

    template<__detail::__different_from<basic_const_iterator> _It2>
      constexpr bool
      operator<=(const _It2& __y) const
      noexcept(noexcept(_M_current <= __y))
      requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
      { return _M_current <= __y; }

    template<__detail::__different_from<basic_const_iterator> _It2>
      constexpr bool
      operator>=(const _It2& __y) const
      noexcept(noexcept(_M_current >= __y))
      requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
      { return _M_current >= __y; }

    template<__detail::__different_from<basic_const_iterator> _It2>
      constexpr auto
      operator<=>(const _It2& __y) const
      noexcept(noexcept(_M_current <=> __y))
      requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
	&& three_way_comparable_with<_It, _It2>
      { return _M_current <=> __y; }

    template<__detail::__not_a_const_iterator _It2, same_as<_It> _It3>
      friend constexpr bool
      operator<(const _It2& __x, const basic_const_iterator<_It3>& __y)
      noexcept(noexcept(__x < __y._M_current))
      requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
      { return __x < __y._M_current; }

    template<__detail::__not_a_const_iterator _It2, same_as<_It> _It3>
      friend constexpr bool
      operator>(const _It2& __x, const basic_const_iterator<_It3>& __y)
      noexcept(noexcept(__x > __y._M_current))
      requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
      { return __x > __y._M_current; }

    template<__detail::__not_a_const_iterator _It2, same_as<_It> _It3>
      friend constexpr bool
      operator<=(const _It2& __x, const basic_const_iterator<_It3>& __y)
      noexcept(noexcept(__x <= __y._M_current))
      requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
      { return __x <= __y._M_current; }

    template<__detail::__not_a_const_iterator _It2, same_as<_It> _It3>
      friend constexpr bool
      operator>=(const _It2& __x, const basic_const_iterator<_It3>& __y)
      noexcept(noexcept(__x >= __y._M_current))
      requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
      { return __x >= __y._M_current; }

    friend constexpr basic_const_iterator
    operator+(const basic_const_iterator& __i, difference_type __n)
    noexcept(noexcept(basic_const_iterator(__i._M_current + __n)))
    requires random_access_iterator<_It>
    { return basic_const_iterator(__i._M_current + __n); }

    friend constexpr basic_const_iterator
    operator+(difference_type __n, const basic_const_iterator& __i)
    noexcept(noexcept(basic_const_iterator(__i._M_current + __n)))
    requires random_access_iterator<_It>
    { return basic_const_iterator(__i._M_current + __n); }

    friend constexpr basic_const_iterator
    operator-(const basic_const_iterator& __i, difference_type __n)
    noexcept(noexcept(basic_const_iterator(__i._M_current - __n)))
    requires random_access_iterator<_It>
    { return basic_const_iterator(__i._M_current - __n); }

    template<sized_sentinel_for<_It> _Sent>
      constexpr difference_type
      operator-(const _Sent& __y) const
      noexcept(noexcept(_M_current - __y))
      { return _M_current - __y; }

    template<__detail::__not_a_const_iterator _Sent, same_as<_It> _It2>
      requires sized_sentinel_for<_Sent, _It>
      friend constexpr difference_type
      operator-(const _Sent& __x, const basic_const_iterator<_It2>& __y)
      noexcept(noexcept(__x - __y._M_current))
      { return __x - __y._M_current; }

    friend constexpr __rvalue_reference
    iter_move(const basic_const_iterator& __i)
    noexcept(noexcept(static_cast<__rvalue_reference>(ranges::iter_move(__i._M_current))))
    { return static_cast<__rvalue_reference>(ranges::iter_move(__i._M_current)); }
  };

  template<typename _Tp, common_with<_Tp> _Up>
    requires input_iterator<common_type_t<_Tp, _Up>>
    struct common_type<basic_const_iterator<_Tp>, _Up>
    { using type = basic_const_iterator<common_type_t<_Tp, _Up>>; };

  template<typename _Tp, common_with<_Tp> _Up>
    requires input_iterator<common_type_t<_Tp, _Up>>
    struct common_type<_Up, basic_const_iterator<_Tp>>
    { using type = basic_const_iterator<common_type_t<_Tp, _Up>>; };

  template<typename _Tp, common_with<_Tp> _Up>
    requires input_iterator<common_type_t<_Tp, _Up>>
    struct common_type<basic_const_iterator<_Tp>, basic_const_iterator<_Up>>
    { using type = basic_const_iterator<common_type_t<_Tp, _Up>>; };

  template<input_iterator _It>
    constexpr const_iterator<_It>
    make_const_iterator(_It __it)
    noexcept(is_nothrow_convertible_v<_It, const_iterator<_It>>)
    { return __it; }

  template<semiregular _Sent>
    constexpr const_sentinel<_Sent>
    make_const_sentinel(_Sent __s)
    noexcept(is_nothrow_convertible_v<_Sent, const_sentinel<_Sent>>)
    { return __s; }
#endif // C++23 ranges_as_const
#endif // C++20 ranges

  /// @} group iterators

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

namespace __gnu_debug
{
  template<typename _Iterator, typename _Sequence, typename _Category>
    class _Safe_iterator;
}

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
  /// @cond undocumented

  // Unwrap a __normal_iterator to get the underlying iterator
  // (usually a pointer). See uses in std::copy, std::fill, etc.
  template<typename _Iterator, typename _Container>
    _GLIBCXX_NODISCARD __attribute__((__always_inline__))
    _GLIBCXX20_CONSTEXPR
    inline _Iterator
    __niter_base(__gnu_cxx::__normal_iterator<_Iterator, _Container> __it)
    _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value)
    { return __it.base(); }

  // Fallback implementation used for iterators that can't be unwrapped.
  template<typename _Iterator>
    _GLIBCXX_NODISCARD __attribute__((__always_inline__))
    _GLIBCXX20_CONSTEXPR
    inline _Iterator
    __niter_base(_Iterator __it)
    _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value)
    { return __it; }

  // Overload for _Safe_iterator needs to be declared before uses of
  // std::__niter_base because we call it qualified so isn't found by ADL.
#if __cplusplus < 201103L
  template<typename _Ite, typename _Seq>
    _Ite
    __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
		 std::random_access_iterator_tag>&);

 template<typename _Ite, typename _Cont, typename _Seq>
    _Ite
    __niter_base(const ::__gnu_debug::_Safe_iterator<
		 ::__gnu_cxx::__normal_iterator<_Ite, _Cont>, _Seq,
		 std::random_access_iterator_tag>&);
#else
  template<typename _Ite, typename _Seq>
    _GLIBCXX20_CONSTEXPR
    decltype(std::__niter_base(std::declval<_Ite>()))
    __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
		 std::random_access_iterator_tag>&)
    noexcept(std::is_nothrow_copy_constructible<_Ite>::value);
#endif

#if __cplusplus >= 201103L
  template<typename _Iterator>
    _GLIBCXX20_CONSTEXPR
    inline auto
    __niter_base(reverse_iterator<_Iterator> __it)
    -> decltype(__make_reverse_iterator(__niter_base(__it.base())))
    { return __make_reverse_iterator(__niter_base(__it.base())); }

  template<typename _Iterator>
    _GLIBCXX20_CONSTEXPR
    inline auto
    __niter_base(move_iterator<_Iterator> __it)
    -> decltype(make_move_iterator(__niter_base(__it.base())))
    { return make_move_iterator(__niter_base(__it.base())); }

  template<typename _Iterator>
    _GLIBCXX20_CONSTEXPR
    inline auto
    __miter_base(reverse_iterator<_Iterator> __it)
    -> decltype(__make_reverse_iterator(__miter_base(__it.base())))
    { return __make_reverse_iterator(__miter_base(__it.base())); }

  template<typename _Iterator>
    _GLIBCXX20_CONSTEXPR
    inline auto
    __miter_base(move_iterator<_Iterator> __it)
    -> decltype(__miter_base(__it.base()))
    { return __miter_base(__it.base()); }
#endif

  // Reverse the __niter_base transformation to get a __normal_iterator
  // back again (this assumes that __normal_iterator is only used to wrap
  // random access iterators, like pointers).
  // All overloads of std::__niter_base must be declared before this.
  template<typename _From, typename _To>
    _GLIBCXX_NODISCARD
    _GLIBCXX20_CONSTEXPR
    inline _From
    __niter_wrap(_From __from, _To __res)
    { return __from + (std::__niter_base(__res) - std::__niter_base(__from)); }

  // No need to wrap, iterator already has the right type.
  template<typename _Iterator>
    _GLIBCXX_NODISCARD __attribute__((__always_inline__))
    _GLIBCXX20_CONSTEXPR
    inline _Iterator
    __niter_wrap(const _Iterator&, _Iterator __res)
    { return __res; }

  /// @endcond

#if __cpp_deduction_guides >= 201606
  // These helper traits are used for deduction guides
  // of associative containers.

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 4223. Deduction guides for maps are mishandling tuples and references
  template<typename _InputIterator>
    using __iter_key_t = __remove_cvref_t<
#ifdef __glibcxx_tuple_like // >= C++23
      tuple_element_t<0, typename iterator_traits<_InputIterator>::value_type>>;
#else
      typename iterator_traits<_InputIterator>::value_type::first_type>;
#endif

  template<typename _InputIterator>
    using __iter_val_t = __remove_cvref_t<
#ifdef __glibcxx_tuple_like // >= C++23
      tuple_element_t<1, typename iterator_traits<_InputIterator>::value_type>>;
#else
      typename iterator_traits<_InputIterator>::value_type::second_type>;
#endif

  template<typename _T1, typename _T2>
    struct pair;

  template<typename _InputIterator>
    using __iter_to_alloc_t
      = pair<const __iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>>;
#endif // __cpp_deduction_guides

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#ifdef _GLIBCXX_DEBUG
# include <debug/stl_iterator.h>
#endif

#endif
