// -*- C++ -*-
// Iterator Wrappers for the C++ library testsuite.
//
// Copyright (C) 2004-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// 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 <bits/move.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;

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

      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;

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

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

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

    public:
      OutputContainer<T>* SharedInfo;

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

#if __cplusplus >= 201103L
      template<class U>
      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>
      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
  : public std::iterator<std::output_iterator_tag, void, std::ptrdiff_t, void, void>
  {
  protected:
    output_iterator_wrapper() : ptr(0), SharedInfo(0)
    { }

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

    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

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

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

    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
  : public std::iterator<std::input_iterator_tag, typename remove_cv<T>::type,
			 std::ptrdiff_t, T*, T&>
  {
    struct post_inc_proxy
    {
      struct deref_proxy
      {
	T* ptr;
	operator const T&() const { return *ptr; }
      } p;

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

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

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

    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

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

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

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

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

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

    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;

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

    forward_iterator_wrapper()
    { }

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

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

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

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

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

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

#if __cplusplus >= 201402L
    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;
    }

    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;

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

    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

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

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

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

    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;

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

    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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


  /**
   * @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
  {
    typename ItType<T>::ContainerType bounds;

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

#if __cplusplus >= 201103L
    template<std::size_t N>
      explicit
      test_container(T (&arr)[N]) : test_container(arr, arr+N)
      { }
#endif

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

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

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

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

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

    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;

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

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

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

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

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

      friend contiguous_iterator_wrapper
      operator+(contiguous_iterator_wrapper iter, std::ptrdiff_t n)
      { return iter += n; }

      friend contiguous_iterator_wrapper
      operator+(std::ptrdiff_t n, contiguous_iterator_wrapper iter)
      { return iter += n; }

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

      friend contiguous_iterator_wrapper
      operator-(contiguous_iterator_wrapper iter, std::ptrdiff_t n)
      { return iter -= n; }
    };

  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;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      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 bool operator==(const sentinel& s, const I& i) noexcept
	  { return s.end == i.ptr; }

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

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

      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& obj) 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
