//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef SUPPORT_TEST_ITERATORS_H
#define SUPPORT_TEST_ITERATORS_H

#include <cassert>
#include <concepts>
#include <cstdint>
#include <iterator>
#include <ranges>
#include <stdexcept>
#include <type_traits>
#include <utility>

#include "double_move_tracker.h"
#include "test_macros.h"
#include "type_algorithms.h"


// This iterator meets C++20's Cpp17OutputIterator requirements, as described
// in Table 90 ([output.iterators]).
template <class It>
class cpp17_output_iterator
{
    It it_;
    support::double_move_tracker tracker_;

    template <class U> friend class cpp17_output_iterator;
public:
    typedef          std::output_iterator_tag                  iterator_category;
    typedef void                                               value_type;
    typedef typename std::iterator_traits<It>::difference_type difference_type;
    typedef It                                                 pointer;
    typedef typename std::iterator_traits<It>::reference       reference;

    TEST_CONSTEXPR explicit cpp17_output_iterator(It it) : it_(std::move(it)) {}

    template <class U>
    TEST_CONSTEXPR cpp17_output_iterator(const cpp17_output_iterator<U>& u) : it_(u.it_), tracker_(u.tracker_) {}

    template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
    TEST_CONSTEXPR_CXX14 cpp17_output_iterator(cpp17_output_iterator<U>&& u)
        : it_(std::move(u.it_)), tracker_(std::move(u.tracker_)) {
      u.it_ = U();
    }

    TEST_CONSTEXPR reference operator*() const {return *it_;}

    TEST_CONSTEXPR_CXX14 cpp17_output_iterator& operator++() {++it_; return *this;}
    TEST_CONSTEXPR_CXX14 cpp17_output_iterator operator++(int) {return cpp17_output_iterator(it_++);}

    friend TEST_CONSTEXPR It base(const cpp17_output_iterator& i) { return i.it_; }

    template <class T>
    void operator,(T const &) = delete;
};
#if TEST_STD_VER > 14
template <class It>
cpp17_output_iterator(It) -> cpp17_output_iterator<It>;
#endif

#if TEST_STD_VER > 17
   static_assert(std::output_iterator<cpp17_output_iterator<int*>, int>);
#endif

// This iterator meets C++20's Cpp17InputIterator requirements, as described
// in Table 89 ([input.iterators]).
template <class It, class ItTraits = It>
class cpp17_input_iterator
{
    typedef std::iterator_traits<ItTraits> Traits;
    It it_;
    support::double_move_tracker tracker_;

    template <class U, class T> friend class cpp17_input_iterator;
public:
    typedef          std::input_iterator_tag                   iterator_category;
    typedef typename Traits::value_type                        value_type;
    typedef typename Traits::difference_type                   difference_type;
    typedef It                                                 pointer;
    typedef typename Traits::reference                         reference;

    TEST_CONSTEXPR explicit cpp17_input_iterator(It it) : it_(it) {}

    template <class U, class T>
    TEST_CONSTEXPR cpp17_input_iterator(const cpp17_input_iterator<U, T>& u) : it_(u.it_), tracker_(u.tracker_) {}

    template <class U, class T, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
    TEST_CONSTEXPR_CXX14 cpp17_input_iterator(cpp17_input_iterator<U, T>&& u)
        : it_(std::move(u.it_)), tracker_(std::move(u.tracker_)) {
      u.it_ = U();
    }

    TEST_CONSTEXPR reference operator*() const {return *it_;}

    TEST_CONSTEXPR_CXX14 cpp17_input_iterator& operator++() {++it_; return *this;}
    TEST_CONSTEXPR_CXX14 cpp17_input_iterator operator++(int) {return cpp17_input_iterator(it_++);}

    friend TEST_CONSTEXPR bool operator==(const cpp17_input_iterator& x, const cpp17_input_iterator& y) {return x.it_ == y.it_;}
    friend TEST_CONSTEXPR bool operator!=(const cpp17_input_iterator& x, const cpp17_input_iterator& y) {return x.it_ != y.it_;}

    friend TEST_CONSTEXPR It base(const cpp17_input_iterator& i) { return i.it_; }

    template <class T>
    void operator,(T const &) = delete;
};
#if TEST_STD_VER > 14
template <class It>
cpp17_input_iterator(It) -> cpp17_input_iterator<It>;
#endif

#if TEST_STD_VER > 17
   static_assert(std::input_iterator<cpp17_input_iterator<int*>>);
#endif

template <class It>
class forward_iterator
{
    It it_;
    support::double_move_tracker tracker_;

    template <class U> friend class forward_iterator;
public:
    typedef          std::forward_iterator_tag                 iterator_category;
    typedef typename std::iterator_traits<It>::value_type      value_type;
    typedef typename std::iterator_traits<It>::difference_type difference_type;
    typedef It                                                 pointer;
    typedef typename std::iterator_traits<It>::reference       reference;

    TEST_CONSTEXPR forward_iterator() : it_() {}
    TEST_CONSTEXPR explicit forward_iterator(It it) : it_(it) {}

    template <class U>
    TEST_CONSTEXPR forward_iterator(const forward_iterator<U>& u) : it_(u.it_), tracker_(u.tracker_) {}

    template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
    TEST_CONSTEXPR_CXX14 forward_iterator(forward_iterator<U>&& other)
        : it_(std::move(other.it_)), tracker_(std::move(other.tracker_)) {
      other.it_ = U();
    }

    TEST_CONSTEXPR reference operator*() const {return *it_;}

    TEST_CONSTEXPR_CXX14 forward_iterator& operator++() {++it_; return *this;}
    TEST_CONSTEXPR_CXX14 forward_iterator operator++(int) {return forward_iterator(it_++);}

    friend TEST_CONSTEXPR bool operator==(const forward_iterator& x, const forward_iterator& y) {return x.it_ == y.it_;}
    friend TEST_CONSTEXPR bool operator!=(const forward_iterator& x, const forward_iterator& y) {return x.it_ != y.it_;}

    friend TEST_CONSTEXPR It base(const forward_iterator& i) { return i.it_; }

    template <class T>
    void operator,(T const &) = delete;
};
#if TEST_STD_VER > 14
template <class It>
forward_iterator(It) -> forward_iterator<It>;
#endif

template <class It>
class bidirectional_iterator
{
    It it_;
    support::double_move_tracker tracker_;

    template <class U> friend class bidirectional_iterator;
public:
    typedef          std::bidirectional_iterator_tag           iterator_category;
    typedef typename std::iterator_traits<It>::value_type      value_type;
    typedef typename std::iterator_traits<It>::difference_type difference_type;
    typedef It                                                 pointer;
    typedef typename std::iterator_traits<It>::reference       reference;

    TEST_CONSTEXPR bidirectional_iterator() : it_() {}
    TEST_CONSTEXPR explicit bidirectional_iterator(It it) : it_(it) {}

    template <class U>
    TEST_CONSTEXPR bidirectional_iterator(const bidirectional_iterator<U>& u) : it_(u.it_), tracker_(u.tracker_) {}

    template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
    TEST_CONSTEXPR_CXX14 bidirectional_iterator(bidirectional_iterator<U>&& u)
        : it_(std::move(u.it_)), tracker_(std::move(u.tracker_)) {
      u.it_ = U();
    }

    TEST_CONSTEXPR reference operator*() const {return *it_;}

    TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator++() {++it_; return *this;}
    TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator--() {--it_; return *this;}
    TEST_CONSTEXPR_CXX14 bidirectional_iterator operator++(int) {return bidirectional_iterator(it_++);}
    TEST_CONSTEXPR_CXX14 bidirectional_iterator operator--(int) {return bidirectional_iterator(it_--);}

    friend TEST_CONSTEXPR bool operator==(const bidirectional_iterator& x, const bidirectional_iterator& y) {return x.it_ == y.it_;}
    friend TEST_CONSTEXPR bool operator!=(const bidirectional_iterator& x, const bidirectional_iterator& y) {return x.it_ != y.it_;}

    friend TEST_CONSTEXPR It base(const bidirectional_iterator& i) { return i.it_; }

    template <class T>
    void operator,(T const &) = delete;
};
#if TEST_STD_VER > 14
template <class It>
bidirectional_iterator(It) -> bidirectional_iterator<It>;
#endif

template <class It>
class random_access_iterator
{
    It it_;
    support::double_move_tracker tracker_;

    template <class U> friend class random_access_iterator;
public:
    typedef          std::random_access_iterator_tag           iterator_category;
    typedef typename std::iterator_traits<It>::value_type      value_type;
    typedef typename std::iterator_traits<It>::difference_type difference_type;
    typedef It                                                 pointer;
    typedef typename std::iterator_traits<It>::reference       reference;

    TEST_CONSTEXPR random_access_iterator() : it_() {}
    TEST_CONSTEXPR explicit random_access_iterator(It it) : it_(it) {}

    template <class U>
    TEST_CONSTEXPR random_access_iterator(const random_access_iterator<U>& u) : it_(u.it_), tracker_(u.tracker_) {}

    template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
    TEST_CONSTEXPR_CXX14 random_access_iterator(random_access_iterator<U>&& u)
        : it_(std::move(u.it_)), tracker_(std::move(u.tracker_)) {
      u.it_ = U();
    }

    TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
    TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return it_[n];}

    TEST_CONSTEXPR_CXX14 random_access_iterator& operator++() {++it_; return *this;}
    TEST_CONSTEXPR_CXX14 random_access_iterator& operator--() {--it_; return *this;}
    TEST_CONSTEXPR_CXX14 random_access_iterator operator++(int) {return random_access_iterator(it_++);}
    TEST_CONSTEXPR_CXX14 random_access_iterator operator--(int) {return random_access_iterator(it_--);}

    TEST_CONSTEXPR_CXX14 random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
    TEST_CONSTEXPR_CXX14 random_access_iterator& operator-=(difference_type n) {it_ -= n; return *this;}
    friend TEST_CONSTEXPR_CXX14 random_access_iterator operator+(random_access_iterator x, difference_type n) {x += n; return x;}
    friend TEST_CONSTEXPR_CXX14 random_access_iterator operator+(difference_type n, random_access_iterator x) {x += n; return x;}
    friend TEST_CONSTEXPR_CXX14 random_access_iterator operator-(random_access_iterator x, difference_type n) {x -= n; return x;}
    friend TEST_CONSTEXPR difference_type operator-(random_access_iterator x, random_access_iterator y) {return x.it_ - y.it_;}

    friend TEST_CONSTEXPR bool operator==(const random_access_iterator& x, const random_access_iterator& y) {return x.it_ == y.it_;}
    friend TEST_CONSTEXPR bool operator!=(const random_access_iterator& x, const random_access_iterator& y) {return x.it_ != y.it_;}
    friend TEST_CONSTEXPR bool operator< (const random_access_iterator& x, const random_access_iterator& y) {return x.it_ <  y.it_;}
    friend TEST_CONSTEXPR bool operator<=(const random_access_iterator& x, const random_access_iterator& y) {return x.it_ <= y.it_;}
    friend TEST_CONSTEXPR bool operator> (const random_access_iterator& x, const random_access_iterator& y) {return x.it_ >  y.it_;}
    friend TEST_CONSTEXPR bool operator>=(const random_access_iterator& x, const random_access_iterator& y) {return x.it_ >= y.it_;}

    friend TEST_CONSTEXPR It base(const random_access_iterator& i) { return i.it_; }

    template <class T>
    void operator,(T const &) = delete;
};
#if TEST_STD_VER > 14
template <class It>
random_access_iterator(It) -> random_access_iterator<It>;
#endif

#if TEST_STD_VER > 17

template <std::random_access_iterator It>
class cpp20_random_access_iterator {
  It it_;
  support::double_move_tracker tracker_;

  template <std::random_access_iterator>
  friend class cpp20_random_access_iterator;

public:
  using iterator_category = std::input_iterator_tag;
  using iterator_concept  = std::random_access_iterator_tag;
  using value_type        = typename std::iterator_traits<It>::value_type;
  using difference_type   = typename std::iterator_traits<It>::difference_type;

  constexpr cpp20_random_access_iterator() : it_() {}
  constexpr explicit cpp20_random_access_iterator(It it) : it_(it) {}

  template <class U>
  constexpr cpp20_random_access_iterator(const cpp20_random_access_iterator<U>& u) : it_(u.it_), tracker_(u.tracker_) {}

  template <class U>
  constexpr cpp20_random_access_iterator(cpp20_random_access_iterator<U>&& u)
      : it_(std::move(u.it_)), tracker_(std::move(u.tracker_)) {
    u.it_ = U();
  }

  constexpr decltype(auto) operator*() const { return *it_; }
  constexpr decltype(auto) operator[](difference_type n) const { return it_[n]; }

  constexpr cpp20_random_access_iterator& operator++() {
    ++it_;
    return *this;
  }
  constexpr cpp20_random_access_iterator& operator--() {
    --it_;
    return *this;
  }
  constexpr cpp20_random_access_iterator operator++(int) { return cpp20_random_access_iterator(it_++); }
  constexpr cpp20_random_access_iterator operator--(int) { return cpp20_random_access_iterator(it_--); }

  constexpr cpp20_random_access_iterator& operator+=(difference_type n) {
    it_ += n;
    return *this;
  }
  constexpr cpp20_random_access_iterator& operator-=(difference_type n) {
    it_ -= n;
    return *this;
  }
  friend constexpr cpp20_random_access_iterator operator+(cpp20_random_access_iterator x, difference_type n) {
    x += n;
    return x;
  }
  friend constexpr cpp20_random_access_iterator operator+(difference_type n, cpp20_random_access_iterator x) {
    x += n;
    return x;
  }
  friend constexpr cpp20_random_access_iterator operator-(cpp20_random_access_iterator x, difference_type n) {
    x -= n;
    return x;
  }
  friend constexpr difference_type operator-(cpp20_random_access_iterator x, cpp20_random_access_iterator y) {
    return x.it_ - y.it_;
  }

  friend constexpr bool operator==(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) {
    return x.it_ == y.it_;
  }
  friend constexpr bool operator!=(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) {
    return x.it_ != y.it_;
  }
  friend constexpr bool operator<(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) {
    return x.it_ < y.it_;
  }
  friend constexpr bool operator<=(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) {
    return x.it_ <= y.it_;
  }
  friend constexpr bool operator>(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) {
    return x.it_ > y.it_;
  }
  friend constexpr bool operator>=(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) {
    return x.it_ >= y.it_;
  }

  friend constexpr It base(const cpp20_random_access_iterator& i) { return i.it_; }

  template <class T>
  void operator,(T const&) = delete;
};
template <class It>
cpp20_random_access_iterator(It) -> cpp20_random_access_iterator<It>;

static_assert(std::random_access_iterator<cpp20_random_access_iterator<int*>>);

template <std::contiguous_iterator It>
class contiguous_iterator {
  It it_;
  support::double_move_tracker tracker_;

  template <std::contiguous_iterator U>
  friend class contiguous_iterator;

public:
  using iterator_category = std::contiguous_iterator_tag;
  using value_type        = typename std::iterator_traits<It>::value_type;
  using difference_type   = typename std::iterator_traits<It>::difference_type;
  using pointer           = typename std::iterator_traits<It>::pointer;
  using reference         = typename std::iterator_traits<It>::reference;
  using element_type      = value_type;

  constexpr It base() const { return it_; }

  constexpr contiguous_iterator() : it_() {}
  constexpr explicit contiguous_iterator(It it) : it_(it) {}

  template <class U>
  constexpr contiguous_iterator(const contiguous_iterator<U>& u) : it_(u.it_), tracker_(u.tracker_) {}

  template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
  constexpr contiguous_iterator(contiguous_iterator<U>&& u) : it_(std::move(u.it_)), tracker_(std::move(u.tracker_)) {
    u.it_ = U();
  }

  constexpr reference operator*() const { return *it_; }
  constexpr pointer operator->() const { return it_; }
  constexpr reference operator[](difference_type n) const { return it_[n]; }

  constexpr contiguous_iterator& operator++() {
    ++it_;
    return *this;
  }
  constexpr contiguous_iterator& operator--() {
    --it_;
    return *this;
  }
  constexpr contiguous_iterator operator++(int) { return contiguous_iterator(it_++); }
  constexpr contiguous_iterator operator--(int) { return contiguous_iterator(it_--); }

  constexpr contiguous_iterator& operator+=(difference_type n) {
    it_ += n;
    return *this;
  }
  constexpr contiguous_iterator& operator-=(difference_type n) {
    it_ -= n;
    return *this;
  }
  friend constexpr contiguous_iterator operator+(contiguous_iterator x, difference_type n) {
    x += n;
    return x;
  }
  friend constexpr contiguous_iterator operator+(difference_type n, contiguous_iterator x) {
    x += n;
    return x;
  }
  friend constexpr contiguous_iterator operator-(contiguous_iterator x, difference_type n) {
    x -= n;
    return x;
  }
  friend constexpr difference_type operator-(contiguous_iterator x, contiguous_iterator y) { return x.it_ - y.it_; }

  friend constexpr bool operator==(const contiguous_iterator& x, const contiguous_iterator& y) {
    return x.it_ == y.it_;
  }
  friend constexpr bool operator!=(const contiguous_iterator& x, const contiguous_iterator& y) {
    return x.it_ != y.it_;
  }
  friend constexpr bool operator<(const contiguous_iterator& x, const contiguous_iterator& y) { return x.it_ < y.it_; }
  friend constexpr bool operator<=(const contiguous_iterator& x, const contiguous_iterator& y) {
    return x.it_ <= y.it_;
  }
  friend constexpr bool operator>(const contiguous_iterator& x, const contiguous_iterator& y) { return x.it_ > y.it_; }
  friend constexpr bool operator>=(const contiguous_iterator& x, const contiguous_iterator& y) {
    return x.it_ >= y.it_;
  }

    // Note no operator<=>, use three_way_contiguous_iterator for testing operator<=>

  friend constexpr It base(const contiguous_iterator& i) { return i.it_; }

  template <class T>
  void operator,(T const&) = delete;
};
template <class It>
contiguous_iterator(It) -> contiguous_iterator<It>;

template <class It>
class three_way_contiguous_iterator
{
    static_assert(std::is_pointer_v<It>, "Things probably break in this case");

    It it_;
    support::double_move_tracker tracker_;

    template <class U> friend class three_way_contiguous_iterator;
public:
    typedef          std::contiguous_iterator_tag              iterator_category;
    typedef typename std::iterator_traits<It>::value_type      value_type;
    typedef typename std::iterator_traits<It>::difference_type difference_type;
    typedef It                                                 pointer;
    typedef typename std::iterator_traits<It>::reference       reference;
    typedef typename std::remove_pointer<It>::type             element_type;

    constexpr It base() const {return it_;}

    constexpr three_way_contiguous_iterator() : it_() {}
    constexpr explicit three_way_contiguous_iterator(It it) : it_(it) {}

    template <class U>
    constexpr three_way_contiguous_iterator(const three_way_contiguous_iterator<U>& u)
        : it_(u.it_), tracker_(u.tracker_) {}

    template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
    constexpr three_way_contiguous_iterator(three_way_contiguous_iterator<U>&& u)
        : it_(std::move(u.it_)), tracker_(std::move(u.tracker_)) {
      u.it_ = U();
    }

    constexpr reference operator*() const {return *it_;}
    constexpr pointer operator->() const {return it_;}
    constexpr reference operator[](difference_type n) const {return it_[n];}

    constexpr three_way_contiguous_iterator& operator++() {++it_; return *this;}
    constexpr three_way_contiguous_iterator& operator--() {--it_; return *this;}
    constexpr three_way_contiguous_iterator operator++(int) {return three_way_contiguous_iterator(it_++);}
    constexpr three_way_contiguous_iterator operator--(int) {return three_way_contiguous_iterator(it_--);}

    constexpr three_way_contiguous_iterator& operator+=(difference_type n) {it_ += n; return *this;}
    constexpr three_way_contiguous_iterator& operator-=(difference_type n) {it_ -= n; return *this;}
    friend constexpr three_way_contiguous_iterator operator+(three_way_contiguous_iterator x, difference_type n) {x += n; return x;}
    friend constexpr three_way_contiguous_iterator operator+(difference_type n, three_way_contiguous_iterator x) {x += n; return x;}
    friend constexpr three_way_contiguous_iterator operator-(three_way_contiguous_iterator x, difference_type n) {x -= n; return x;}
    friend constexpr difference_type operator-(three_way_contiguous_iterator x, three_way_contiguous_iterator y) {return x.it_ - y.it_;}

    friend constexpr auto operator<=>(const three_way_contiguous_iterator& x, const three_way_contiguous_iterator& y) {return x.it_ <=> y.it_;}
    friend constexpr bool operator==(const three_way_contiguous_iterator& x, const three_way_contiguous_iterator& y) {return x.it_ == y.it_;}

    template <class T>
    void operator,(T const &) = delete;
};
template <class It>
three_way_contiguous_iterator(It) -> three_way_contiguous_iterator<It>;
#endif // TEST_STD_VER > 17

template <class Iter> // ADL base() for everything else (including pointers)
TEST_CONSTEXPR Iter base(Iter i) { return i; }

template <typename T>
struct ThrowingIterator {
    typedef std::bidirectional_iterator_tag iterator_category;
    typedef std::ptrdiff_t                       difference_type;
    typedef const T                         value_type;
    typedef const T *                       pointer;
    typedef const T &                       reference;

    enum ThrowingAction { TAIncrement, TADecrement, TADereference, TAAssignment, TAComparison };

    TEST_CONSTEXPR ThrowingIterator()
        : begin_(nullptr), end_(nullptr), current_(nullptr), action_(TADereference), index_(0) {}
    TEST_CONSTEXPR explicit ThrowingIterator(const T* first, const T* last, int index = 0,
                                                   ThrowingAction action = TADereference)
        : begin_(first), end_(last), current_(first), action_(action), index_(index) {}
    TEST_CONSTEXPR ThrowingIterator(const ThrowingIterator &rhs)
        : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_), action_(rhs.action_), index_(rhs.index_) {}

    TEST_CONSTEXPR_CXX14 ThrowingIterator& operator=(const ThrowingIterator& rhs) {
        if (action_ == TAAssignment && --index_ < 0) {
#ifndef TEST_HAS_NO_EXCEPTIONS
            throw std::runtime_error("throw from iterator assignment");
#else
            assert(false);
#endif
        }
        begin_ = rhs.begin_;
        end_ = rhs.end_;
        current_ = rhs.current_;
        action_ = rhs.action_;
        index_ = rhs.index_;
        return *this;
    }

    TEST_CONSTEXPR_CXX14 reference operator*() const {
        if (action_ == TADereference && --index_ < 0) {
#ifndef TEST_HAS_NO_EXCEPTIONS
            throw std::runtime_error("throw from iterator dereference");
#else
            assert(false);
#endif
        }
        return *current_;
    }

    TEST_CONSTEXPR_CXX14 ThrowingIterator& operator++() {
        if (action_ == TAIncrement && --index_ < 0) {
#ifndef TEST_HAS_NO_EXCEPTIONS
            throw std::runtime_error("throw from iterator increment");
#else
            assert(false);
#endif
        }
        ++current_;
        return *this;
    }

    TEST_CONSTEXPR_CXX14 ThrowingIterator operator++(int) {
        ThrowingIterator temp = *this;
        ++(*this);
        return temp;
    }

    TEST_CONSTEXPR_CXX14 ThrowingIterator& operator--() {
        if (action_ == TADecrement && --index_ < 0) {
#ifndef TEST_HAS_NO_EXCEPTIONS
            throw std::runtime_error("throw from iterator decrement");
#else
            assert(false);
#endif
        }
        --current_;
        return *this;
    }

    TEST_CONSTEXPR_CXX14 ThrowingIterator operator--(int) {
        ThrowingIterator temp = *this;
        --(*this);
        return temp;
    }

    TEST_CONSTEXPR_CXX14 friend bool operator==(const ThrowingIterator& a, const ThrowingIterator& b) {
        if (a.action_ == TAComparison && --a.index_ < 0) {
#ifndef TEST_HAS_NO_EXCEPTIONS
            throw std::runtime_error("throw from iterator comparison");
#else
            assert(false);
#endif
        }
        bool atEndL = a.current_ == a.end_;
        bool atEndR = b.current_ == b.end_;
        if (atEndL != atEndR) return false;  // one is at the end (or empty), the other is not.
        if (atEndL) return true;             // both are at the end (or empty)
        return a.current_ == b.current_;
    }

    TEST_CONSTEXPR friend bool operator!=(const ThrowingIterator& a, const ThrowingIterator& b) {
        return !(a == b);
    }

    template <class T2>
    void operator,(T2 const &) = delete;

private:
    const T* begin_;
    const T* end_;
    const T* current_;
    ThrowingAction action_;
    mutable int index_;
};

template <typename T>
struct NonThrowingIterator {
    typedef std::bidirectional_iterator_tag iterator_category;
    typedef std::ptrdiff_t                       difference_type;
    typedef const T                         value_type;
    typedef const T *                       pointer;
    typedef const T &                       reference;

    NonThrowingIterator()
        : begin_(nullptr), end_(nullptr), current_(nullptr) {}
    explicit NonThrowingIterator(const T *first, const T *last)
        : begin_(first), end_(last), current_(first) {}
    NonThrowingIterator(const NonThrowingIterator& rhs)
        : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_) {}

    NonThrowingIterator& operator=(const NonThrowingIterator& rhs) TEST_NOEXCEPT {
        begin_ = rhs.begin_;
        end_ = rhs.end_;
        current_ = rhs.current_;
        return *this;
    }

    reference operator*() const TEST_NOEXCEPT {
        return *current_;
    }

    NonThrowingIterator& operator++() TEST_NOEXCEPT {
        ++current_;
        return *this;
    }

    NonThrowingIterator operator++(int) TEST_NOEXCEPT {
        NonThrowingIterator temp = *this;
        ++(*this);
        return temp;
    }

    NonThrowingIterator & operator--() TEST_NOEXCEPT {
        --current_;
        return *this;
    }

    NonThrowingIterator operator--(int) TEST_NOEXCEPT {
        NonThrowingIterator temp = *this;
        --(*this);
        return temp;
    }

    friend bool operator==(const NonThrowingIterator& a, const NonThrowingIterator& b) TEST_NOEXCEPT {
        bool atEndL = a.current_ == a.end_;
        bool atEndR = b.current_ == b.end_;
        if (atEndL != atEndR) return false;  // one is at the end (or empty), the other is not.
        if (atEndL) return true;             // both are at the end (or empty)
        return a.current_ == b.current_;
    }

    friend bool operator!=(const NonThrowingIterator& a, const NonThrowingIterator& b) TEST_NOEXCEPT {
        return !(a == b);
    }

    template <class T2>
    void operator,(T2 const &) = delete;

private:
    const T *begin_;
    const T *end_;
    const T *current_;
};

#if TEST_STD_VER > 17

template <class It>
class cpp20_input_iterator
{
    It it_;
    support::double_move_tracker tracker_;

public:
    using value_type = std::iter_value_t<It>;
    using difference_type = std::iter_difference_t<It>;
    using iterator_concept = std::input_iterator_tag;

    constexpr explicit cpp20_input_iterator(It it) : it_(it) {}
    cpp20_input_iterator(cpp20_input_iterator&&) = default;
    cpp20_input_iterator& operator=(cpp20_input_iterator&&) = default;
    constexpr decltype(auto) operator*() const { return *it_; }
    constexpr cpp20_input_iterator& operator++() { ++it_; return *this; }
    constexpr void operator++(int) { ++it_; }

    friend constexpr It base(const cpp20_input_iterator& i) { return i.it_; }

    template <class T>
    void operator,(T const &) = delete;
};
template <class It>
cpp20_input_iterator(It) -> cpp20_input_iterator<It>;

static_assert(std::input_iterator<cpp20_input_iterator<int*>>);

template<std::input_or_output_iterator>
struct iter_value_or_void { using type = void; };

template<std::input_iterator I>
struct iter_value_or_void<I> {
    using type = std::iter_value_t<I>;
};

template <class It>
class cpp20_output_iterator {
  It it_;
  support::double_move_tracker tracker_;

public:
  using difference_type = std::iter_difference_t<It>;

  constexpr explicit cpp20_output_iterator(It it) : it_(it) {}
  cpp20_output_iterator(cpp20_output_iterator&&) = default;
  cpp20_output_iterator& operator=(cpp20_output_iterator&&) = default;

  constexpr decltype(auto) operator*() const { return *it_; }
  constexpr cpp20_output_iterator& operator++() {
    ++it_;
    return *this;
  }
  constexpr cpp20_output_iterator operator++(int) { return cpp20_output_iterator(it_++); }

  friend constexpr It base(const cpp20_output_iterator& i) { return i.it_; }

  template <class T>
  void operator,(T const&) = delete;
};
template <class It>
cpp20_output_iterator(It) -> cpp20_output_iterator<It>;

static_assert(std::output_iterator<cpp20_output_iterator<int*>, int>);

#  if TEST_STD_VER >= 20

// An `input_iterator` that can be used in a `std::ranges::common_range`
template <class Base>
struct common_input_iterator {
  Base it_;

  using value_type       = std::iter_value_t<Base>;
  using difference_type  = std::intptr_t;
  using iterator_concept = std::input_iterator_tag;

  constexpr common_input_iterator() = default;
  constexpr explicit common_input_iterator(Base it) : it_(it) {}

  constexpr common_input_iterator& operator++() {
    ++it_;
    return *this;
  }
  constexpr void operator++(int) { ++it_; }

  constexpr decltype(auto) operator*() const { return *it_; }

  friend constexpr bool operator==(common_input_iterator const&, common_input_iterator const&) = default;
};

#  endif // TEST_STD_VER >= 20

struct IteratorOpCounts {
  std::size_t increments = 0; ///< Number of times the iterator moved forward (++it, it++, it+=positive, it-=negative).
  std::size_t decrements = 0; ///< Number of times the iterator moved backward (--it, it--, it-=positive, it+=negative).
  std::size_t zero_moves = 0; ///< Number of times a call was made to move the iterator by 0 positions (it+=0, it-=0).
  std::size_t equal_cmps = 0; ///< Total number of calls to op== or op!=. If compared against a sentinel object, that
                              ///  sentinel object must call the `record_equality_comparison` function so that the
                              ///  comparison is counted correctly.
};

// Iterator adaptor that records its operation counts in a IteratorOpCounts
template <class It>
class operation_counting_iterator {
public:
    using value_type = typename iter_value_or_void<It>::type;
    using difference_type = std::iter_difference_t<It>;
    using iterator_concept =
        std::conditional_t<std::contiguous_iterator<It>,    std::contiguous_iterator_tag,
        std::conditional_t<std::random_access_iterator<It>, std::random_access_iterator_tag,
        std::conditional_t<std::bidirectional_iterator<It>, std::bidirectional_iterator_tag,
        std::conditional_t<std::forward_iterator<It>,       std::forward_iterator_tag,
        std::conditional_t<std::input_iterator<It>,         std::input_iterator_tag,
        /* else */                                          std::output_iterator_tag
    >>>>>;
    using iterator_category = iterator_concept;

    operation_counting_iterator()
      requires std::default_initializable<It>
    = default;

    constexpr explicit operation_counting_iterator(It const& it, IteratorOpCounts* counts = nullptr)
        : base_(base(it)), counts_(counts) {}

    constexpr operation_counting_iterator(const operation_counting_iterator& o) { *this = o; }
    constexpr operation_counting_iterator(operation_counting_iterator&& o) { *this = o; }

    constexpr operation_counting_iterator& operator=(const operation_counting_iterator& o) = default;
    constexpr operation_counting_iterator& operator=(operation_counting_iterator&& o) { return *this = o; }

    friend constexpr It base(operation_counting_iterator const& it) { return It(it.base_); }

    constexpr decltype(auto) operator*() const { return *It(base_); }

    constexpr decltype(auto) operator[](difference_type n) const { return It(base_)[n]; }

    constexpr operation_counting_iterator& operator++() {
      It tmp(base_);
      base_ = base(++tmp);
      moved_by(1);
      return *this;
    }

    constexpr void operator++(int) { ++*this; }

    constexpr operation_counting_iterator operator++(int)
      requires std::forward_iterator<It>
    {
      auto temp = *this;
      ++*this;
      return temp;
    }

    constexpr operation_counting_iterator& operator--()
      requires std::bidirectional_iterator<It>
    {
      It tmp(base_);
      base_ = base(--tmp);
      moved_by(-1);
      return *this;
    }

    constexpr operation_counting_iterator operator--(int)
      requires std::bidirectional_iterator<It>
    {
      auto temp = *this;
      --*this;
      return temp;
    }

    constexpr operation_counting_iterator& operator+=(difference_type const n)
      requires std::random_access_iterator<It>
    {
      It tmp(base_);
      base_ = base(tmp += n);
      moved_by(n);
      return *this;
    }

    constexpr operation_counting_iterator& operator-=(difference_type const n)
      requires std::random_access_iterator<It>
    {
      It tmp(base_);
      base_ = base(tmp -= n);
      moved_by(-n);
      return *this;
    }

    friend constexpr operation_counting_iterator operator+(operation_counting_iterator it, difference_type n)
      requires std::random_access_iterator<It>
    {
      return it += n;
    }

    friend constexpr operation_counting_iterator operator+(difference_type n, operation_counting_iterator it)
      requires std::random_access_iterator<It>
    {
      return it += n;
    }

    friend constexpr operation_counting_iterator operator-(operation_counting_iterator it, difference_type n)
      requires std::random_access_iterator<It>
    {
      return it -= n;
    }

    friend constexpr difference_type
    operator-(operation_counting_iterator const& x, operation_counting_iterator const& y)
      requires std::sized_sentinel_for<It, It>
    {
      return base(x) - base(y);
    }

    constexpr void record_equality_comparison() const {
      if (counts_ != nullptr)
        ++counts_->equal_cmps;
    }

    constexpr bool operator==(operation_counting_iterator const& other) const
      requires std::sentinel_for<It, It>
    {
      record_equality_comparison();
      return It(base_) == It(other.base_);
    }

    friend constexpr bool operator<(operation_counting_iterator const& x, operation_counting_iterator const& y)
      requires std::random_access_iterator<It>
    {
      return It(x.base_) < It(y.base_);
    }

    friend constexpr bool operator>(operation_counting_iterator const& x, operation_counting_iterator const& y)
      requires std::random_access_iterator<It>
    {
      return It(x.base_) > It(y.base_);
    }

    friend constexpr bool operator<=(operation_counting_iterator const& x, operation_counting_iterator const& y)
      requires std::random_access_iterator<It>
    {
      return It(x.base_) <= It(y.base_);
    }

    friend constexpr bool operator>=(operation_counting_iterator const& x, operation_counting_iterator const& y)
      requires std::random_access_iterator<It>
    {
      return It(x.base_) >= It(y.base_);
    }

    template <class T>
    void operator,(T const &) = delete;

private:
  constexpr void moved_by(difference_type n) {
    if (counts_ == nullptr)
      return;
    if (n > 0)
      ++counts_->increments;
    else if (n < 0)
      ++counts_->decrements;
    else
      ++counts_->zero_moves;
  }

    decltype(base(std::declval<It>())) base_;
    IteratorOpCounts* counts_ = nullptr;
};
template <class It>
operation_counting_iterator(It) -> operation_counting_iterator<It>;

#endif // TEST_STD_VER > 17

#if TEST_STD_VER > 17
template <class It>
class sentinel_wrapper {
public:
    explicit sentinel_wrapper() = default;
    constexpr explicit sentinel_wrapper(const It& it) : base_(base(it)) {}
    constexpr bool operator==(const It& other) const {
      // If supported, record statistics about the equality operator call
      // inside `other`.
      if constexpr (requires { other.record_equality_comparison(); }) {
        other.record_equality_comparison();
      }
      return base_ == base(other);
    }
    friend constexpr It base(const sentinel_wrapper& s) { return It(s.base_); }
private:
    decltype(base(std::declval<It>())) base_;
};
template <class It>
sentinel_wrapper(It) -> sentinel_wrapper<It>;

template <class It>
class sized_sentinel {
public:
    explicit sized_sentinel() = default;
    constexpr explicit sized_sentinel(const It& it) : base_(base(it)) {}
    constexpr bool operator==(const It& other) const { return base_ == base(other); }
    friend constexpr auto operator-(const sized_sentinel& s, const It& i) { return s.base_ - base(i); }
    friend constexpr auto operator-(const It& i, const sized_sentinel& s) { return base(i) - s.base_; }
    friend constexpr It base(const sized_sentinel& s) { return It(s.base_); }
private:
    decltype(base(std::declval<It>())) base_;
};
template <class It>
sized_sentinel(It) -> sized_sentinel<It>;

namespace adl {

class Iterator {
 public:
  using value_type = int;
  using reference = int&;
  using difference_type = std::ptrdiff_t;

 private:
  value_type* ptr_ = nullptr;
  int* iter_moves_ = nullptr;
  int* iter_swaps_ = nullptr;

  constexpr Iterator(int* p, int* iter_moves, int* iter_swaps)
    : ptr_(p)
    , iter_moves_(iter_moves)
    , iter_swaps_(iter_swaps) {}

 public:
  constexpr Iterator() = default;
  static constexpr Iterator TrackMoves(int* p, int& iter_moves) {
    return Iterator(p, &iter_moves, /*iter_swaps=*/nullptr);
  }
  static constexpr Iterator TrackSwaps(int& iter_swaps) {
    return Iterator(/*p=*/nullptr, /*iter_moves=*/nullptr, &iter_swaps);
  }
  static constexpr Iterator TrackSwaps(int* p, int& iter_swaps) {
    return Iterator(p, /*iter_moves=*/nullptr, &iter_swaps);
  }

  constexpr int iter_moves() const { assert(iter_moves_); return *iter_moves_; }
  constexpr int iter_swaps() const { assert(iter_swaps_); return *iter_swaps_; }

  constexpr value_type& operator*() const { return *ptr_; }
  constexpr reference operator[](difference_type n) const { return ptr_[n]; }

  friend constexpr Iterator operator+(Iterator i, difference_type n) {
    return Iterator(i.ptr_ + n, i.iter_moves_, i.iter_swaps_);
  }
  friend constexpr Iterator operator+(difference_type n, Iterator i) {
    return i + n;
  }
  constexpr Iterator operator-(difference_type n) const {
    return Iterator(ptr_ - n, iter_moves_, iter_swaps_);
  }
  constexpr difference_type operator-(Iterator rhs) const {
    return ptr_ - rhs.ptr_;
  }
  constexpr Iterator& operator+=(difference_type n) {
    ptr_ += n;
    return *this;
  }
  constexpr Iterator& operator-=(difference_type n) {
    ptr_ -= n;
    return *this;
  }

  constexpr Iterator& operator++() { ++ptr_; return *this; }
  constexpr Iterator operator++(int) {
    Iterator prev = *this;
    ++ptr_;
    return prev;
  }

  constexpr Iterator& operator--() { --ptr_; return *this; }
  constexpr Iterator operator--(int) {
    Iterator prev = *this;
    --ptr_;
    return prev;
  }

  constexpr friend void iter_swap(Iterator a, Iterator b) {
    std::swap(a.ptr_, b.ptr_);
    if (a.iter_swaps_) {
      ++(*a.iter_swaps_);
    }
  }

  constexpr friend value_type&& iter_move(Iterator iter) {
    if (iter.iter_moves_) {
      ++(*iter.iter_moves_);
    }
    return std::move(*iter);
  }

  constexpr friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
    return lhs.ptr_ == rhs.ptr_;
  }
  constexpr friend auto operator<=>(const Iterator& lhs, const Iterator& rhs) {
    return lhs.ptr_ <=> rhs.ptr_;
  }
};

} // namespace adl

template <class T>
class rvalue_iterator {
public:
  using iterator_category = std::input_iterator_tag;
  using iterator_concept  = std::random_access_iterator_tag;
  using difference_type   = std::ptrdiff_t;
  using reference         = T&&;
  using value_type        = T;

  rvalue_iterator() = default;
  constexpr rvalue_iterator(T* it) : it_(it) {}

  constexpr reference operator*() const { return std::move(*it_); }

  constexpr rvalue_iterator& operator++() {
    ++it_;
    return *this;
  }

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

  constexpr rvalue_iterator& operator--() {
    --it_;
    return *this;
  }

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

  constexpr rvalue_iterator operator+(difference_type n) const {
    auto tmp = *this;
    tmp.it += n;
    return tmp;
  }

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

  constexpr rvalue_iterator operator-(difference_type n) const {
    auto tmp = *this;
    tmp.it -= n;
    return tmp;
  }

  constexpr difference_type operator-(const rvalue_iterator& other) const { return it_ - other.it_; }

  constexpr rvalue_iterator& operator+=(difference_type n) {
    it_ += n;
    return *this;
  }

  constexpr rvalue_iterator& operator-=(difference_type n) {
    it_ -= n;
    return *this;
  }

  constexpr reference operator[](difference_type n) const { return std::move(it_[n]); }

  auto operator<=>(const rvalue_iterator&) const noexcept = default;

private:
  T* it_;
};

template <class T>
rvalue_iterator(T*) -> rvalue_iterator<T>;

static_assert(std::random_access_iterator<rvalue_iterator<int*>>);

// Proxy
// ======================================================================
// Proxy that can wrap a value or a reference. It simulates C++23's tuple
// but simplified to just hold one argument.
// Note that unlike tuple, this class deliberately doesn't have special handling
// of swap to cause a compilation error if it's used in an algorithm that relies
// on plain swap instead of ranges::iter_swap.
// This class is useful for testing that if algorithms support proxy iterator
// properly, i.e. calling ranges::iter_swap and ranges::iter_move instead of
// plain swap and std::move.
template <class T>
struct Proxy;

template <class T>
inline constexpr bool IsProxy = false;

template <class T>
inline constexpr bool IsProxy<Proxy<T>> = true;

template <class T>
struct Proxy {
  T data;

  constexpr T& getData() & { return data; }

  constexpr const T& getData() const& { return data; }

  constexpr T&& getData() && { return static_cast<T&&>(data); }

  constexpr const T&& getData() const&& { return static_cast<const T&&>(data); }

  template <class U>
    requires std::constructible_from<T, U&&>
  constexpr Proxy(U&& u) : data{std::forward<U>(u)} {}

  // This constructor covers conversion from cvref of Proxy<U>, including non-const/const versions of copy/move constructor
  template <class Other>
    requires(IsProxy<std::decay_t<Other>> && std::constructible_from<T, decltype(std::declval<Other>().getData())>)
  constexpr Proxy(Other&& other) : data{std::forward<Other>(other).getData()} {}

  template <class Other>
    requires(IsProxy<std::decay_t<Other>> && std::assignable_from<T&, decltype(std::declval<Other>().getData())>)
  constexpr Proxy& operator=(Other&& other) {
    data = std::forward<Other>(other).getData();
    return *this;
  }

  // const assignment required to make ProxyIterator model std::indirectly_writable
  template <class Other>
    requires(IsProxy<std::decay_t<Other>> && std::assignable_from<const T&, decltype(std::declval<Other>().getData())>)
  constexpr const Proxy& operator=(Other&& other) const {
    data = std::forward<Other>(other).getData();
    return *this;
  }

  // If `T` is a reference type, the implicitly-generated assignment operator will be deleted (and would take precedence
  // over the templated `operator=` above because it's a better match).
  constexpr Proxy& operator=(const Proxy& rhs) {
    data = rhs.data;
    return *this;
  }

  // no specialised swap function that takes const Proxy& and no specialised const member swap
  // Calling swap(Proxy<T>{}, Proxy<T>{}) would fail (pass prvalues)

  // Compare operators are defined for the convenience of the tests
  friend constexpr bool operator==(const Proxy&, const Proxy&)
    requires (std::equality_comparable<T> && !std::is_reference_v<T>)
  = default;

  // Helps compare e.g. `Proxy<int>` and `Proxy<int&>`. Note that the default equality comparison operator is deleted
  // when `T` is a reference type.
  template <class U>
  friend constexpr bool operator==(const Proxy& lhs, const Proxy<U>& rhs)
    requires std::equality_comparable_with<std::decay_t<T>, std::decay_t<U>> {
    return lhs.data == rhs.data;
  }

  friend constexpr auto operator<=>(const Proxy&, const Proxy&)
    requires (std::three_way_comparable<T> && !std::is_reference_v<T>)
  = default;

  // Helps compare e.g. `Proxy<int>` and `Proxy<int&>`. Note that the default 3-way comparison operator is deleted when
  // `T` is a reference type.
  template <class U>
  friend constexpr auto operator<=>(const Proxy& lhs, const Proxy<U>& rhs)
    requires std::three_way_comparable_with<std::decay_t<T>, std::decay_t<U>> {
    return lhs.data <=> rhs.data;
  }
};

// This is to make ProxyIterator model `std::indirectly_readable`
template <class T, class U, template <class> class TQual, template <class> class UQual>
  requires requires { typename std::common_reference_t<TQual<T>, UQual<U>>; }
struct std::basic_common_reference<Proxy<T>, Proxy<U>, TQual, UQual> {
  using type = Proxy<std::common_reference_t<TQual<T>, UQual<U>>>;
};

template <class T, class U>
  requires requires { typename std::common_type_t<T, U>; }
struct std::common_type<Proxy<T>, Proxy<U>> {
  using type = Proxy<std::common_type_t<T, U>>;
};

// ProxyIterator
// ======================================================================
// It wraps `Base` iterator and when dereferenced it returns a Proxy<ref>
// It simulates C++23's zip_view::iterator but simplified to just wrap
// one base iterator.
// Note it forwards value_type, iter_move, iter_swap. e.g if the base
// iterator is int*,
// operator*    -> Proxy<int&>
// iter_value_t -> Proxy<int>
// iter_move    -> Proxy<int&&>
template <class Base>
struct ProxyIteratorBase {};

template <class Base>
  requires std::derived_from<
      typename std::iterator_traits<Base>::iterator_category,
      std::input_iterator_tag>
struct ProxyIteratorBase<Base> {
  using iterator_category = std::input_iterator_tag;
};

template <std::input_iterator Base>
consteval auto get_iterator_concept() {
  if constexpr (std::random_access_iterator<Base>) {
    return std::random_access_iterator_tag{};
  } else if constexpr (std::bidirectional_iterator<Base>) {
    return std::bidirectional_iterator_tag{};
  } else if constexpr (std::forward_iterator<Base>) {
    return std::forward_iterator_tag{};
  } else {
    return std::input_iterator_tag{};
  }
}

template <std::input_iterator Base>
struct ProxyIterator : ProxyIteratorBase<Base> {
  Base base_;

  using iterator_concept = decltype(get_iterator_concept<Base>());
  using value_type       = Proxy<std::iter_value_t<Base>>;
  using difference_type  = std::iter_difference_t<Base>;

  ProxyIterator()
    requires std::default_initializable<Base>
  = default;

  constexpr ProxyIterator(Base base) : base_{std::move(base)} {}

  template <class T>
    requires std::constructible_from<Base, T&&>
  constexpr ProxyIterator(T&& t) : base_{std::forward<T>(t)} {}

  friend constexpr decltype(auto) base(const ProxyIterator& p) { return base(p.base_); }

  // Specialization of iter_move
  // If operator* returns Proxy<Foo&>, iter_move will return Proxy<Foo&&>
  // Note std::move(*it) returns Proxy<Foo&>&&, which is not what we want as
  // it will likely result in a copy rather than a move
  friend constexpr Proxy<std::iter_rvalue_reference_t<Base>> iter_move(const ProxyIterator& p) noexcept {
    return {std::ranges::iter_move(p.base_)};
  }

  // Specialization of iter_swap
  // Note std::swap(*x, *y) would fail to compile as operator* returns prvalues
  // and std::swap takes non-const lvalue references
  friend constexpr void iter_swap(const ProxyIterator& x, const ProxyIterator& y) noexcept {
    std::ranges::iter_swap(x.base_, y.base_);
  }

  // to satisfy input_iterator
  constexpr Proxy<std::iter_reference_t<Base>> operator*() const { return {*base_}; }

  constexpr ProxyIterator& operator++() {
    ++base_;
    return *this;
  }

  constexpr void operator++(int) { ++*this; }

  friend constexpr bool operator==(const ProxyIterator& x, const ProxyIterator& y)
    requires std::equality_comparable<Base> {
    return x.base_ == y.base_;
  }

  // to satisfy forward_iterator
  constexpr ProxyIterator operator++(int)
    requires std::forward_iterator<Base> {
    auto tmp = *this;
    ++*this;
    return tmp;
  }

  // to satisfy bidirectional_iterator
  constexpr ProxyIterator& operator--()
    requires std::bidirectional_iterator<Base> {
    --base_;
    return *this;
  }

  constexpr ProxyIterator operator--(int)
    requires std::bidirectional_iterator<Base> {
    auto tmp = *this;
    --*this;
    return tmp;
  }

  // to satisfy random_access_iterator
  constexpr ProxyIterator& operator+=(difference_type n)
    requires std::random_access_iterator<Base> {
    base_ += n;
    return *this;
  }

  constexpr ProxyIterator& operator-=(difference_type n)
    requires std::random_access_iterator<Base> {
    base_ -= n;
    return *this;
  }

  constexpr Proxy<std::iter_reference_t<Base>> operator[](difference_type n) const
    requires std::random_access_iterator<Base> {
    return {base_[n]};
  }

  friend constexpr bool operator<(const ProxyIterator& x, const ProxyIterator& y)
    requires std::random_access_iterator<Base> {
    return x.base_ < y.base_;
  }

  friend constexpr bool operator>(const ProxyIterator& x, const ProxyIterator& y)
    requires std::random_access_iterator<Base> {
    return x.base_ > y.base_;
  }

  friend constexpr bool operator<=(const ProxyIterator& x, const ProxyIterator& y)
    requires std::random_access_iterator<Base> {
    return x.base_ <= y.base_;
  }

  friend constexpr bool operator>=(const ProxyIterator& x, const ProxyIterator& y)
    requires std::random_access_iterator<Base> {
    return x.base_ >= y.base_;
  }

  friend constexpr auto operator<=>(const ProxyIterator& x, const ProxyIterator& y)
    requires(std::random_access_iterator<Base> && std::three_way_comparable<Base>) {
    return x.base_ <=> y.base_;
  }

  friend constexpr ProxyIterator operator+(const ProxyIterator& x, difference_type n)
    requires std::random_access_iterator<Base> {
    return ProxyIterator{x.base_ + n};
  }

  friend constexpr ProxyIterator operator+(difference_type n, const ProxyIterator& x)
    requires std::random_access_iterator<Base> {
    return ProxyIterator{n + x.base_};
  }

  friend constexpr ProxyIterator operator-(const ProxyIterator& x, difference_type n)
    requires std::random_access_iterator<Base> {
    return ProxyIterator{x.base_ - n};
  }

  friend constexpr difference_type operator-(const ProxyIterator& x, const ProxyIterator& y)
    requires std::random_access_iterator<Base> {
    return x.base_ - y.base_;
  }
};
template <class Base>
ProxyIterator(Base) -> ProxyIterator<Base>;

static_assert(std::indirectly_readable<ProxyIterator<int*>>);
static_assert(std::indirectly_writable<ProxyIterator<int*>, Proxy<int>>);
static_assert(std::indirectly_writable<ProxyIterator<int*>, Proxy<int&>>);

template <class Iter>
using Cpp20InputProxyIterator = ProxyIterator<cpp20_input_iterator<Iter>>;

template <class Iter>
using ForwardProxyIterator = ProxyIterator<forward_iterator<Iter>>;

template <class Iter>
using BidirectionalProxyIterator = ProxyIterator<bidirectional_iterator<Iter>>;

template <class Iter>
using RandomAccessProxyIterator = ProxyIterator<random_access_iterator<Iter>>;

template <class Iter>
using ContiguousProxyIterator = ProxyIterator<contiguous_iterator<Iter>>;

template <class BaseSent>
struct ProxySentinel {
  BaseSent base_;

  ProxySentinel() = default;
  constexpr ProxySentinel(BaseSent base) : base_{std::move(base)} {}

  template <class Base>
    requires std::equality_comparable_with<Base, BaseSent>
  friend constexpr bool operator==(const ProxyIterator<Base>& p, const ProxySentinel& sent) {
    return p.base_ == sent.base_;
  }
};
template <class BaseSent>
ProxySentinel(BaseSent) -> ProxySentinel<BaseSent>;

template <std::ranges::input_range Base>
  requires std::ranges::view<Base>
struct ProxyRange {
  Base base_;

  constexpr auto begin() { return ProxyIterator{std::ranges::begin(base_)}; }

  constexpr auto end() { return ProxySentinel{std::ranges::end(base_)}; }

  constexpr auto begin() const
    requires std::ranges::input_range<const Base> {
    return ProxyIterator{std::ranges::begin(base_)};
  }

  constexpr auto end() const
    requires std::ranges::input_range<const Base> {
    return ProxySentinel{std::ranges::end(base_)};
  }
};

template <std::ranges::input_range R>
  requires std::ranges::viewable_range<R&&>
ProxyRange(R&&) -> ProxyRange<std::views::all_t<R&&>>;

#endif // TEST_STD_VER > 17

#if TEST_STD_VER >= 17

namespace util {
template <class Derived, class Iter>
class iterator_wrapper {
  Iter iter_;

  using iter_traits = std::iterator_traits<Iter>;

public:
  using iterator_category = typename iter_traits::iterator_category;
  using value_type        = typename iter_traits::value_type;
  using difference_type   = typename iter_traits::difference_type;
  using pointer           = typename iter_traits::pointer;
  using reference         = typename iter_traits::reference;

  constexpr iterator_wrapper() : iter_() {}
  constexpr explicit iterator_wrapper(Iter iter) : iter_(iter) {}

  decltype(*iter_) operator*() { return *iter_; }
  decltype(*iter_) operator*() const { return *iter_; }

  decltype(iter_[0]) operator[](difference_type v) const {
    return iter_[v];
  }

  Derived& operator++() {
    ++iter_;
    return static_cast<Derived&>(*this);
  }

  Derived operator++(int) {
    auto tmp = static_cast<Derived&>(*this);
    ++(*this);
    return tmp;
  }

  Derived& operator--() {
    --iter_;
    return static_cast<Derived&>(*this);
  }

  Derived operator--(int) {
    auto tmp = static_cast<Derived&>(*this);
    --(*this);
    return tmp;
  }

  Derived& operator+=(difference_type i) {
    iter_ += i;
    return static_cast<Derived&>(*this);
  }

  Derived& operator-=(difference_type i) {
    iter_ -= i;
    return static_cast<Derived&>(*this);
  }

  friend decltype(iter_ - iter_) operator-(const iterator_wrapper& lhs, const iterator_wrapper& rhs) {
    return lhs.iter_ - rhs.iter_;
  }

  friend Derived operator-(Derived iter, difference_type i) {
    iter.iter_ -= i;
    return iter;
  }

  friend Derived operator+(Derived iter, difference_type i) {
    iter.iter_ += i;
    return iter;
  }

  friend Derived operator+(difference_type i, Derived iter) { return iter + i; }

  friend bool operator==(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ == rhs.iter_; }
  friend bool operator!=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ != rhs.iter_; }

  friend bool operator>(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ > rhs.iter_; }
  friend bool operator<(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ < rhs.iter_; }
  friend bool operator<=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ <= rhs.iter_; }
  friend bool operator>=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ >= rhs.iter_; }
};

class iterator_error : std::runtime_error {
public:
  iterator_error(const char* what) : std::runtime_error(what) {}
};

#ifndef TEST_HAS_NO_EXCEPTIONS
template <class Iter>
class throw_on_move_iterator : public iterator_wrapper<throw_on_move_iterator<Iter>, Iter> {
  using base = iterator_wrapper<throw_on_move_iterator<Iter>, Iter>;

  int moves_until_throw_ = 0;

public:
  using difference_type   = typename base::difference_type;
  using value_type        = typename base::value_type;
  using iterator_category = typename base::iterator_category;

  throw_on_move_iterator() = default;
  throw_on_move_iterator(Iter iter, int moves_until_throw)
      : base(std::move(iter)), moves_until_throw_(moves_until_throw) {}

  throw_on_move_iterator(const throw_on_move_iterator& other) : base(other) {}
  throw_on_move_iterator& operator=(const throw_on_move_iterator& other) {
    static_cast<base&>(*this) = other;
    return *this;
  }

  throw_on_move_iterator(throw_on_move_iterator&& other)
      : base(std::move(other)), moves_until_throw_(other.moves_until_throw_ - 1) {
    if (moves_until_throw_ == -1)
      throw iterator_error("throw_on_move_iterator");
  }

  throw_on_move_iterator& operator=(throw_on_move_iterator&& other) {
    moves_until_throw_ = other.moves_until_throw_ - 1;
    if (moves_until_throw_ == -1)
      throw iterator_error("throw_on_move_iterator");
    return *this;
  }
};

template <class Iter>
throw_on_move_iterator(Iter) -> throw_on_move_iterator<Iter>;
#endif // TEST_HAS_NO_EXCEPTIONS
} // namespace util

#endif // TEST_STD_VER >= 17

namespace types {
template <class Ptr>
using random_access_iterator_list =
    type_list<Ptr,
#if TEST_STD_VER >= 20
              contiguous_iterator<Ptr>,
#endif
              random_access_iterator<Ptr> >;

template <class Ptr>
using bidirectional_iterator_list =
    concatenate_t<random_access_iterator_list<Ptr>, type_list<bidirectional_iterator<Ptr> > >;

template <class Ptr>
using forward_iterator_list = concatenate_t<bidirectional_iterator_list<Ptr>, type_list<forward_iterator<Ptr> > >;

template <class Ptr>
using cpp17_input_iterator_list = concatenate_t<forward_iterator_list<Ptr>, type_list<cpp17_input_iterator<Ptr> > >;

#if TEST_STD_VER >= 20
template <class Ptr>
using cpp20_input_iterator_list =
    concatenate_t<forward_iterator_list<Ptr>, type_list<cpp20_input_iterator<Ptr>, cpp17_input_iterator<Ptr>>>;
#endif
} // namespace types


#endif // SUPPORT_TEST_ITERATORS_H
