// -*- C++ -*-
// Iterator Wrappers for the C++ library testsuite.
//
// Copyright (C) 2004-2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.
//

// This file provides the following:
//
// input_iterator_wrapper, output_iterator_wrapper
// forward_iterator_wrapper, bidirectional_iterator_wrapper and
// random_access_wrapper, which attempt to exactly perform the requirements
// of these types of iterators. These are constructed from the class
// test_container, which is given two pointers to T and an iterator type.

#include <testsuite_hooks.h>
#include <bits/stl_iterator_base_types.h>

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

#if __cplusplus > 201703L
#include <bits/max_size_type.h>
#endif

#ifndef _TESTSUITE_ITERATORS
#define _TESTSUITE_ITERATORS

#ifdef DISABLE_ITERATOR_DEBUG
#define ITERATOR_VERIFY(x)
#else
#define ITERATOR_VERIFY(x) VERIFY(x)
#endif

namespace __gnu_test
{
  /**
   * @brief Simple container for holding two pointers.
   *
   * Note that input_iterator_wrapper changes first to denote
   * how the valid range of == , ++, etc. change as the iterators are used.
   */
  template<typename T>
    struct BoundsContainer
    {
      T* first;
      T* last;

      _GLIBCXX_CONSTEXPR
      BoundsContainer(T* _first, T* _last) : first(_first), last(_last)
      { }

      _GLIBCXX_CONSTEXPR std::size_t
      size() const { return last - first; }
    };

  // Simple container for holding state of a set of output iterators.
  template<typename T>
    struct OutputContainer : public BoundsContainer<T>
    {
      T* incrementedto;
      bool* writtento;

      _GLIBCXX20_CONSTEXPR
      OutputContainer(T* _first, T* _last)
      : BoundsContainer<T>(_first, _last), incrementedto(_first),
	writtento(new bool[this->size()]())
      { }

      _GLIBCXX20_CONSTEXPR
      ~OutputContainer()
      { delete[] writtento; }
    };

  // Produced by output_iterator to allow limited writing to pointer
  template<class T>
    class WritableObject
    {
      T* ptr;

    public:
      OutputContainer<T>* SharedInfo;

      _GLIBCXX_CONSTEXPR
      WritableObject(T* ptr_in, OutputContainer<T>* SharedInfo_in):
	ptr(ptr_in), SharedInfo(SharedInfo_in)
      { }

#if __cplusplus >= 201103L
      template<class U>
      _GLIBCXX14_CONSTEXPR
      typename std::enable_if<std::is_assignable<T&, U>::value>::type
      operator=(U&& new_val) const
      {
	ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
	SharedInfo->writtento[ptr - SharedInfo->first] = 1;
	*ptr = std::forward<U>(new_val);
      }
#else
      template<class U>
      _GLIBCXX14_CONSTEXPR
      void
      operator=(const U& new_val)
      {
	ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
	SharedInfo->writtento[ptr - SharedInfo->first] = 1;
	*ptr = new_val;
      }
#endif
    };

  /**
   * @brief output_iterator wrapper for pointer
   *
   * This class takes a pointer and wraps it to provide exactly
   * the requirements of a output_iterator. It should not be
   * instantiated directly, but generated from a test_container
   */
  template<class T>
  struct output_iterator_wrapper
  {
  protected:
    _GLIBCXX_CONSTEXPR
    output_iterator_wrapper() : ptr(0), SharedInfo(0)
    { }

  public:
    typedef std::output_iterator_tag iterator_category;
    typedef T value_type;
    typedef std::ptrdiff_t difference_type;
    typedef T* pointer;
    typedef T& reference;

    typedef OutputContainer<T> ContainerType;
    T* ptr;
    ContainerType* SharedInfo;

    _GLIBCXX14_CONSTEXPR
    output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
    : ptr(_ptr), SharedInfo(SharedInfo_in)
    {
      ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last);
    }

#if __cplusplus >= 201103L
    output_iterator_wrapper(const output_iterator_wrapper&) = default;

    output_iterator_wrapper&
    operator=(const output_iterator_wrapper&) = default;
#endif

    _GLIBCXX14_CONSTEXPR
    WritableObject<T>
    operator*() const
    {
      ITERATOR_VERIFY(ptr < SharedInfo->last);
      ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false);
      return WritableObject<T>(ptr, SharedInfo);
    }

    _GLIBCXX14_CONSTEXPR
    output_iterator_wrapper&
    operator++()
    {
      ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
      ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto);
      ptr++;
      SharedInfo->incrementedto=ptr;
      return *this;
    }

    _GLIBCXX14_CONSTEXPR
    output_iterator_wrapper
    operator++(int)
    {
      output_iterator_wrapper<T> tmp = *this;
      ++*this;
      return tmp;
    }

#if __cplusplus >= 201103L
    template<typename U>
      void operator,(const U&) const = delete;

    void operator&() const = delete;
#else
  private:
    template<typename U>
      void operator,(const U&) const;

    void operator&() const;
#endif
  };

#if __cplusplus >= 201103L
  template<typename T, typename U>
    void operator,(const T&, const output_iterator_wrapper<U>&) = delete;
#endif

#if __cplusplus >= 201103L
  using std::remove_cv;
#else
  template<typename T> struct remove_cv { typedef T type; };
  template<typename T> struct remove_cv<const T> { typedef T type; };
  template<typename T> struct remove_cv<volatile T> { typedef T type; };
  template<typename T> struct remove_cv<const volatile T> { typedef T type; };
#endif

  /**
   * @brief input_iterator wrapper for pointer
   *
   * This class takes a pointer and wraps it to provide exactly
   * the requirements of a input_iterator. It should not be
   * instantiated directly, but generated from a test_container
   */
  template<class T>
  class input_iterator_wrapper
  {
    struct post_inc_proxy
    {
      struct deref_proxy
      {
	T* ptr;

	_GLIBCXX_CONSTEXPR
	operator const T&() const
	{ return *ptr; }
      } p;

      _GLIBCXX_CONSTEXPR
      deref_proxy operator*() const
      { return p; }
    };

  protected:
    _GLIBCXX_CONSTEXPR
    input_iterator_wrapper() : ptr(0), SharedInfo(0)
    { }

  public:
    typedef std::input_iterator_tag iterator_category;
    typedef typename remove_cv<T>::type value_type;
    typedef std::ptrdiff_t difference_type;
    typedef T* pointer;
    typedef T& reference;

    typedef BoundsContainer<T> ContainerType;
    T* ptr;
    ContainerType* SharedInfo;

    _GLIBCXX14_CONSTEXPR
    input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
    : ptr(_ptr), SharedInfo(SharedInfo_in)
    { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }

#if __cplusplus >= 201103L
    input_iterator_wrapper(const input_iterator_wrapper&) = default;

    input_iterator_wrapper&
    operator=(const input_iterator_wrapper&) = default;
#endif

    _GLIBCXX14_CONSTEXPR
    bool
    operator==(const input_iterator_wrapper& in) const
    {
      ITERATOR_VERIFY(SharedInfo && SharedInfo == in.SharedInfo);
      ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
      return ptr == in.ptr;
    }

    _GLIBCXX14_CONSTEXPR
    bool
    operator!=(const input_iterator_wrapper& in) const
    {
      return !(*this == in);
    }

    _GLIBCXX_CONSTEXPR
    T* base() const
    {
      return ptr;
    }

    _GLIBCXX14_CONSTEXPR
    T& operator*() const
    {
      ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
      ITERATOR_VERIFY(ptr >= SharedInfo->first);
      return *ptr;
    }

    _GLIBCXX14_CONSTEXPR
    T* operator->() const
    {
      return &**this;
    }

    _GLIBCXX14_CONSTEXPR
    input_iterator_wrapper&
    operator++()
    {
      ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
      ITERATOR_VERIFY(ptr>=SharedInfo->first);
      ptr++;
      SharedInfo->first=ptr;
      return *this;
    }

    _GLIBCXX14_CONSTEXPR
    post_inc_proxy
    operator++(int)
    {
      post_inc_proxy tmp = { { ptr } };
      ++*this;
      return tmp;
    }

#if __cplusplus >= 201103L
    template<typename U>
      void operator,(const U&) const = delete;

    void operator&() const = delete;
#else
  private:
    template<typename U>
      void operator,(const U&) const;

    void operator&() const;
#endif
  };

#if __cplusplus >= 201103L
  template<typename T, typename U>
    void operator,(const T&, const input_iterator_wrapper<U>&) = delete;
#endif

  /**
   * @brief forward_iterator wrapper for pointer
   *
   * This class takes a pointer and wraps it to provide exactly
   * the requirements of a forward_iterator. It should not be
   * instantiated directly, but generated from a test_container
   */
  template<class T>
  struct forward_iterator_wrapper : public input_iterator_wrapper<T>
  {
    typedef BoundsContainer<T> ContainerType;
    typedef std::forward_iterator_tag iterator_category;

    _GLIBCXX14_CONSTEXPR
    forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
    : input_iterator_wrapper<T>(_ptr, SharedInfo_in)
    { }

    _GLIBCXX14_CONSTEXPR
    forward_iterator_wrapper()
    { }

#if __cplusplus >= 201103L
    forward_iterator_wrapper(const forward_iterator_wrapper&) = default;

    forward_iterator_wrapper&
    operator=(const forward_iterator_wrapper&) = default;
#endif

    _GLIBCXX14_CONSTEXPR
    T& operator*() const
    {
      ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
      return *(this->ptr);
    }

    _GLIBCXX14_CONSTEXPR
    T* operator->() const
    { return &**this; }

    _GLIBCXX14_CONSTEXPR
    forward_iterator_wrapper&
    operator++()
    {
      ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
      this->ptr++;
      return *this;
    }

    _GLIBCXX14_CONSTEXPR
    forward_iterator_wrapper
    operator++(int)
    {
      forward_iterator_wrapper<T> tmp = *this;
      ++*this;
      return tmp;
    }

#if __cplusplus >= 201402L
    constexpr
    bool operator==(const forward_iterator_wrapper& it) const noexcept
    {
      // Since C++14 value-initialized forward iterators are comparable.
      if (this->SharedInfo == nullptr || it.SharedInfo == nullptr)
	return this->SharedInfo == it.SharedInfo && this->ptr == it.ptr;

      const input_iterator_wrapper<T>& base_this = *this;
      const input_iterator_wrapper<T>& base_that = it;
      return base_this == base_that;
    }

    constexpr
    bool operator!=(const forward_iterator_wrapper& it) const noexcept
    {
      return !(*this == it);
    }
#endif
  };

  /**
   * @brief bidirectional_iterator wrapper for pointer
   *
   * This class takes a pointer and wraps it to provide exactly
   * the requirements of a bidirectional_iterator. It should not be
   * instantiated directly, but generated from a test_container
   */
  template<class T>
  struct bidirectional_iterator_wrapper : public forward_iterator_wrapper<T>
  {
    typedef BoundsContainer<T> ContainerType;
    typedef std::bidirectional_iterator_tag iterator_category;

    _GLIBCXX14_CONSTEXPR
    bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
    : forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
    { }

    _GLIBCXX14_CONSTEXPR
    bidirectional_iterator_wrapper()
    : forward_iterator_wrapper<T>()
    { }

#if __cplusplus >= 201103L
    bidirectional_iterator_wrapper(
	const bidirectional_iterator_wrapper&) = default;

    bidirectional_iterator_wrapper&
    operator=(const bidirectional_iterator_wrapper&) = default;
#endif

    _GLIBCXX14_CONSTEXPR
    bidirectional_iterator_wrapper&
    operator++()
    {
      ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
      this->ptr++;
      return *this;
    }

    _GLIBCXX14_CONSTEXPR
    bidirectional_iterator_wrapper
    operator++(int)
    {
      bidirectional_iterator_wrapper<T> tmp = *this;
      ++*this;
      return tmp;
    }

    _GLIBCXX14_CONSTEXPR
    bidirectional_iterator_wrapper&
    operator--()
    {
      ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
      this->ptr--;
      return *this;
    }

    _GLIBCXX14_CONSTEXPR
    bidirectional_iterator_wrapper
    operator--(int)
    {
      bidirectional_iterator_wrapper<T> tmp = *this;
      --*this;
      return tmp;
    }
  };

  /**
   * @brief random_access_iterator wrapper for pointer
   *
   * This class takes a pointer and wraps it to provide exactly
   * the requirements of a random_access_iterator. It should not be
   * instantiated directly, but generated from a test_container
   */
  template<class T>
  struct random_access_iterator_wrapper
  : public bidirectional_iterator_wrapper<T>
  {
    typedef BoundsContainer<T> ContainerType;
    typedef std::random_access_iterator_tag iterator_category;

    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
    : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
    { }

    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper()
    : bidirectional_iterator_wrapper<T>()
    { }

#if __cplusplus >= 201103L
    random_access_iterator_wrapper(
	const random_access_iterator_wrapper&) = default;

    random_access_iterator_wrapper&
    operator=(const random_access_iterator_wrapper&) = default;
#endif

    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper&
    operator++()
    {
      ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
      this->ptr++;
      return *this;
    }

    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper
    operator++(int)
    {
      random_access_iterator_wrapper<T> tmp = *this;
      ++*this;
      return tmp;
    }

    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper&
    operator--()
    {
      ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
      this->ptr--;
      return *this;
    }

    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper
    operator--(int)
    {
      random_access_iterator_wrapper<T> tmp = *this;
      --*this;
      return tmp;
    }

    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper&
    operator+=(std::ptrdiff_t n)
    {
      if(n > 0)
	{
	  ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
	  this->ptr += n;
	}
      else
	{
	  ITERATOR_VERIFY(-n <= this->ptr - this->SharedInfo->first);
	  this->ptr += n;
	}
      return *this;
    }

    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper&
    operator-=(std::ptrdiff_t n)
    { return *this += -n; }

    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper
    operator-(std::ptrdiff_t n) const
    {
      random_access_iterator_wrapper<T> tmp = *this;
      return tmp -= n;
    }

    _GLIBCXX14_CONSTEXPR
    std::ptrdiff_t
    operator-(const random_access_iterator_wrapper<T>& in) const
    {
      ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
      return this->ptr - in.ptr;
    }

    _GLIBCXX14_CONSTEXPR
    T& operator[](std::ptrdiff_t n) const
    { return *(*this + n); }

#if __cplusplus >= 201103L
    // Ensure that the iterator's difference_type is always used.
    template<typename D> void operator+=(D) = delete;
    template<typename D> void operator-=(D) = delete;
    template<typename D> void operator[](D) const = delete;
    template<typename D>
      typename std::enable_if<std::is_integral<D>::value>::type
      operator-(D) const = delete;
#endif

    _GLIBCXX14_CONSTEXPR
    bool operator<(const random_access_iterator_wrapper<T>& in) const
    {
      ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
      return this->ptr < in.ptr;
    }

    _GLIBCXX14_CONSTEXPR
    bool operator>(const random_access_iterator_wrapper<T>& in) const
    {
      return in < *this;
    }

    _GLIBCXX14_CONSTEXPR
    bool operator>=(const random_access_iterator_wrapper<T>& in) const
    {
      return !(*this < in);
    }

    _GLIBCXX14_CONSTEXPR
    bool operator<=(const random_access_iterator_wrapper<T>& in) const
    {
      return !(*this > in);
    }
  };

  template<typename T>
    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper<T>
    operator+(random_access_iterator_wrapper<T> it, std::ptrdiff_t n)
    { return it += n; }

  template<typename T>
    _GLIBCXX14_CONSTEXPR
    random_access_iterator_wrapper<T>
    operator+(std::ptrdiff_t n, random_access_iterator_wrapper<T> it)
    { return it += n; }

#if __cplusplus >= 201103L
    // Ensure that the iterator's difference_type is always used.
    template<typename T, typename D>
      void operator+(random_access_iterator_wrapper<T>, D) = delete;
    template<typename T, typename D>
      void operator+(D, random_access_iterator_wrapper<T>) = delete;
#endif


  /**
   * @brief A container-type class for holding iterator wrappers
   * test_container takes two parameters, a class T and an iterator
   * wrapper templated by T (for example forward_iterator_wrapper<T>.
   * It takes two pointers representing a range and presents them as
   * a container of iterators.
   */
  template <class T, template<class TT> class ItType>
  struct test_container
  {
    typedef ItType<T> iterator;
    typedef typename iterator::value_type value_type;

    typename ItType<T>::ContainerType bounds;

    _GLIBCXX_CONSTEXPR
    test_container(T* _first, T* _last) : bounds(_first, _last)
    { }

    template<std::size_t N>
      explicit
      _GLIBCXX_CONSTEXPR
      test_container(T (&arr)[N]) : bounds(arr, arr+N)
      { }

    _GLIBCXX14_CONSTEXPR
    ItType<T>
    it(int pos)
    {
      ITERATOR_VERIFY(pos >= 0 && (unsigned)pos <= size());
      return ItType<T>(bounds.first + pos, &bounds);
    }

    _GLIBCXX14_CONSTEXPR
    ItType<T>
    it(T* pos)
    {
      ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
      return ItType<T>(pos, &bounds);
    }

    _GLIBCXX_CONSTEXPR
    const T&
    val(int pos)
    { return (bounds.first)[pos]; }

    _GLIBCXX14_CONSTEXPR
    ItType<T>
    begin()
    { return it(bounds.first); }

    _GLIBCXX14_CONSTEXPR
    ItType<T>
    end()
    { return it(bounds.last); }

    _GLIBCXX_CONSTEXPR
    std::size_t
    size() const
    { return bounds.size(); }
  };

#if __cplusplus >= 201103L
  template<typename T>
    using output_container
      = test_container<T, output_iterator_wrapper>;

  template<typename T>
    using input_container
      = test_container<T, input_iterator_wrapper>;

  template<typename T>
    using forward_container
      = test_container<T, forward_iterator_wrapper>;

  template<typename T>
    using bidirectional_container
      = test_container<T, bidirectional_iterator_wrapper>;

  template<typename T>
    using random_access_container
      = test_container<T, random_access_iterator_wrapper>;
#endif

#if __cplusplus > 201703L
  template<typename T>
    struct contiguous_iterator_wrapper
    : random_access_iterator_wrapper<T>
    {
      using random_access_iterator_wrapper<T>::random_access_iterator_wrapper;

      using iterator_concept = std::contiguous_iterator_tag;

      // Use an integer-class type to try and break the library code.
      using difference_type = std::ranges::__detail::__max_diff_type;

      constexpr
      contiguous_iterator_wrapper&
      operator++()
      {
	random_access_iterator_wrapper<T>::operator++();
	return *this;
      }

      constexpr
      contiguous_iterator_wrapper&
      operator--()
      {
	random_access_iterator_wrapper<T>::operator--();
	return *this;
      }

      constexpr
      contiguous_iterator_wrapper
      operator++(int)
      {
	auto tmp = *this;
	++*this;
	return tmp;
      }

      constexpr
      contiguous_iterator_wrapper
      operator--(int)
      {
	auto tmp = *this;
	--*this;
	return tmp;
      }

      constexpr
      contiguous_iterator_wrapper&
      operator+=(difference_type n)
      {
	auto d = static_cast<std::ptrdiff_t>(n);
	random_access_iterator_wrapper<T>::operator+=(d);
	return *this;
      }

      friend constexpr
      contiguous_iterator_wrapper
      operator+(contiguous_iterator_wrapper iter, difference_type n)
      { return iter += n; }

      friend constexpr
      contiguous_iterator_wrapper
      operator+(difference_type n, contiguous_iterator_wrapper iter)
      { return iter += n; }

      constexpr
      contiguous_iterator_wrapper&
      operator-=(difference_type n)
      { return *this += -n; }

      friend constexpr
      contiguous_iterator_wrapper
      operator-(contiguous_iterator_wrapper iter, difference_type n)
      { return iter -= n; }

      friend constexpr
      difference_type
      operator-(contiguous_iterator_wrapper l, contiguous_iterator_wrapper r)
      {
	const random_access_iterator_wrapper<T>& lbase = l;
	const random_access_iterator_wrapper<T>& rbase = r;
	return static_cast<difference_type>(lbase - rbase);
      }

      constexpr
      decltype(auto) operator[](difference_type n) const
      {
	auto d = static_cast<std::ptrdiff_t>(n);
	return random_access_iterator_wrapper<T>::operator[](d);
      }
    };

  template<typename T>
    using contiguous_container
      = test_container<T, contiguous_iterator_wrapper>;

  // A move-only input iterator type.
  template<typename T>
    struct input_iterator_wrapper_nocopy : input_iterator_wrapper<T>
    {
      using input_iterator_wrapper<T>::input_iterator_wrapper;

      constexpr
      input_iterator_wrapper_nocopy()
	: input_iterator_wrapper<T>(nullptr, nullptr)
      { }

      input_iterator_wrapper_nocopy(const input_iterator_wrapper_nocopy&) = delete;
      input_iterator_wrapper_nocopy&
      operator=(const input_iterator_wrapper_nocopy&) = delete;

      input_iterator_wrapper_nocopy(input_iterator_wrapper_nocopy&&) = default;
      input_iterator_wrapper_nocopy&
      operator=(input_iterator_wrapper_nocopy&&) = default;

      using input_iterator_wrapper<T>::operator++;

      constexpr
      input_iterator_wrapper_nocopy&
      operator++()
      {
	input_iterator_wrapper<T>::operator++();
	return *this;
      }
    };

  // An input iterator type with an rvalue reference type.
  template<typename T>
    struct input_iterator_wrapper_rval : input_iterator_wrapper<T>
    {
      using input_iterator_wrapper<T>::input_iterator_wrapper;

      using input_iterator_wrapper<T>::operator++;

      constexpr
      input_iterator_wrapper_rval&
      operator++()
      {
	input_iterator_wrapper<T>::operator++();
	return *this;
      }

      constexpr
      T&& operator*() const
      { return std::move(input_iterator_wrapper<T>::operator*()); }
    };

  // A type meeting the minimum std::range requirements
  template<typename T, template<typename> class Iter>
    class test_range
    {
      // Exposes the protected default constructor of Iter<T> if needed.  This
      // is needed only when Iter is input_iterator_wrapper or
      // output_iterator_wrapper, because legacy forward iterators and beyond
      // are already default constructible.
      struct iterator : Iter<T>
      {
	using Iter<T>::Iter;

	using Iter<T>::operator++;

	constexpr
	iterator& operator++()
       	{ Iter<T>::operator++(); return *this; }
      };

      template<typename I>
	struct sentinel
	{
	  T* end;

	  friend constexpr bool
	  operator==(const sentinel& s, const I& i) noexcept
	  { return s.end == i.ptr; }

	  friend constexpr
	  auto operator-(const sentinel& s, const I& i) noexcept
	    requires std::random_access_iterator<I>
	  { return std::iter_difference_t<I>(s.end - i.ptr); }

	  friend constexpr auto
	  operator-(const I& i, const sentinel& s) noexcept
	    requires std::random_access_iterator<I>
	  { return std::iter_difference_t<I>(i.ptr - s.end); }
	};

    protected:
      constexpr
      auto get_iterator(T* p)
      {
	if constexpr (std::default_initializable<Iter<T>>)
	  return Iter<T>(p, &bounds);
	else
	  return iterator(p, &bounds);
      }

    public:
      constexpr
      test_range(T* first, T* last) : bounds(first, last)
      { }

      template<std::size_t N>
	explicit constexpr
	test_range(T (&arr)[N]) : test_range(arr, arr+N)
	{ }

      constexpr auto begin() &
      { return get_iterator(bounds.first); }

      constexpr auto end() &
      {
	using I = decltype(get_iterator(bounds.last));
	return sentinel<I>{bounds.last};
      }

      typename Iter<T>::ContainerType bounds;
    };

  // A move-only type meeting the minimum std::range requirements
  template<typename T, template<typename> class Iter>
    struct test_range_nocopy : test_range<T, Iter>
    {
      constexpr
      test_range_nocopy(T* first, T* last)
      : test_range<T, Iter>(first, last)
      {}

      test_range_nocopy(test_range_nocopy&&) = default;
      test_range_nocopy& operator=(test_range_nocopy&&) = default;
    };

  template<typename T>
    using test_contiguous_range
      = test_range<T, contiguous_iterator_wrapper>;
  template<typename T>
    using test_random_access_range
      = test_range<T, random_access_iterator_wrapper>;
  template<typename T>
    using test_bidirectional_range
      = test_range<T, bidirectional_iterator_wrapper>;
  template<typename T>
    using test_forward_range
      = test_range<T, forward_iterator_wrapper>;
  template<typename T>
    using test_input_range
      = test_range<T, input_iterator_wrapper>;
  template<typename T>
    using test_input_range_nocopy
      = test_range_nocopy<T, input_iterator_wrapper_nocopy>;
  template<typename T>
    using test_output_range
      = test_range<T, output_iterator_wrapper>;

  // A type meeting the minimum std::sized_range requirements
  template<typename T, template<typename> class Iter>
    struct test_sized_range : test_range<T, Iter>
    {
      using test_range<T, Iter>::test_range;

      constexpr
      std::size_t size() const noexcept
      { return this->bounds.size(); }
    };

  template<typename T>
    using test_contiguous_sized_range
      = test_sized_range<T, contiguous_iterator_wrapper>;
  template<typename T>
    using test_random_access_sized_range
      = test_sized_range<T, random_access_iterator_wrapper>;
  template<typename T>
    using test_bidirectional_sized_range
      = test_sized_range<T, bidirectional_iterator_wrapper>;
  template<typename T>
    using test_forward_sized_range
      = test_sized_range<T, forward_iterator_wrapper>;
  template<typename T>
    using test_input_sized_range
      = test_sized_range<T, input_iterator_wrapper>;
  template<typename T>
    using test_output_sized_range
      = test_sized_range<T, output_iterator_wrapper>;

  // A type meeting the minimum std::sized_range requirements, and whose end()
  // returns a sized sentinel.
  template<typename T, template<typename> class Iter>
    struct test_sized_range_sized_sent : test_sized_range<T, Iter>
    {
      using test_sized_range<T, Iter>::test_sized_range;

      template<typename I>
	struct sentinel
	{
	  T* end;

	  friend constexpr
	  bool operator==(const sentinel& s, const I& i) noexcept
	  { return s.end == i.ptr; }

	  friend constexpr
	  std::iter_difference_t<I>
	  operator-(const sentinel& s, const I& i) noexcept
	  { return std::iter_difference_t<I>(s.end - i.ptr); }

	  friend constexpr
	  std::iter_difference_t<I>
	  operator-(const I& i, const sentinel& s) noexcept
	  { return std::iter_difference_t<I>(i.ptr - s.end); }
	};

      constexpr
      auto end() &
      {
	using I = decltype(this->get_iterator(this->bounds.last));
	return sentinel<I>{this->bounds.last};
      }
    };

// test_range and test_sized_range do not own their elements, so they model
// std::ranges::borrowed_range.  This file does not define specializations of
// std::ranges::enable_borrowed_range, so that individual tests can decide
// whether or not to do so.
// This is also true for test_container, although only when it has forward
// iterators (because output_iterator_wrapper and input_iterator_wrapper are
// not default constructible so do not model std::input_or_output_iterator).


  // Test for basic properties of C++20 16.3.3.6 [customization.point.object].
  template<typename T>
    constexpr bool
    is_customization_point_object(T&) noexcept
    {
      // A [CPO] is a function object with a literal class type.
      static_assert( std::is_class_v<T> || std::is_union_v<T> );
      static_assert( __is_literal_type(T) );
      // The type of a [CPO], ignoring cv-qualifiers, shall model semiregular.
      static_assert( std::semiregular<std::remove_cv_t<T>> );

      return true;
    }

#endif // C++20
} // namespace __gnu_test
#endif // _TESTSUITE_ITERATORS
