9 Iterators library [iterators]

9.7 Iterator adaptors [iterators.predef]

9.7.1 Reverse iterators [iterators.reverse]

Class template reverse_iterator is an iterator adaptor that iterates from the end of the sequence defined by its underlying iterator to the beginning of that sequence. The fundamental relation between a reverse iterator and its corresponding underlying iterator i is established by the identity: *make_reverse_iterator(i) == *prev(i).

9.7.1.1 Class template reverse_iterator [reverse.iterator]

namespace std { namespace experimental { namespace ranges { inline namespace v1 {
  template <BidirectionalIterator I>
  class reverse_iterator {
  public:
    using iterator_type = I;
    using difference_type = difference_type_t<I>;
    using value_type = value_type_t<I>;
    using iterator_category = iterator_category_t<I>;
    using reference = reference_t<I>;
    using pointer = I;

    constexpr reverse_iterator();
    explicit constexpr reverse_iterator(I x);
    constexpr reverse_iterator(const reverse_iterator<ConvertibleTo<I>>& i);
    constexpr reverse_iterator& operator=(const reverse_iterator<ConvertibleTo<I>>& i);

    constexpr I base() const;
    constexpr reference operator*() const;
    constexpr pointer operator->() const;

    constexpr reverse_iterator& operator++();
    constexpr reverse_iterator  operator++(int);
    constexpr reverse_iterator& operator--();
    constexpr reverse_iterator  operator--(int);

    constexpr reverse_iterator  operator+ (difference_type n) const
      requires RandomAccessIterator<I>;
    constexpr reverse_iterator& operator+=(difference_type n)
      requires RandomAccessIterator<I>;
    constexpr reverse_iterator  operator- (difference_type n) const
      requires RandomAccessIterator<I>;
    constexpr reverse_iterator& operator-=(difference_type n)
      requires RandomAccessIterator<I>;
    constexpr reference operator[](difference_type n) const
      requires RandomAccessIterator<I>;

    friend constexpr rvalue_reference_t<I> iter_move(const reverse_iterator& i)
      noexcept(see below);
    template <IndirectlySwappable<I> I2>
      friend constexpr void iter_swap(const reverse_iterator& x, const reverse_iterator<I2>& y)
        noexcept(see below);

  private:
    I current; // exposition only
  };

  template <class I1, class I2>
      requires EqualityComparableWith<I1, I2>
    constexpr bool operator==(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires EqualityComparableWith<I1, I2>
    constexpr bool operator!=(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator<(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator>(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator>=(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator<=(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires SizedSentinel<I1, I2>
    constexpr difference_type_t<I2> operator-(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <RandomAccessIterator I>
    constexpr reverse_iterator<I> operator+(
      difference_type_t<I> n,
      const reverse_iterator<I>& x);

  template <BidirectionalIterator I>
    constexpr reverse_iterator<I> make_reverse_iterator(I i);
}}}}

9.7.1.2 reverse_iterator operations [reverse.iter.ops]

9.7.1.2.1 reverse_iterator constructor [reverse.iter.cons]

constexpr reverse_iterator();

Effects: Value-initializes current. Iterator operations applied to the resulting iterator have defined behavior if and only if the corresponding operations are defined on a value-initialized iterator of type I.

explicit constexpr reverse_iterator(I x);

Effects: Initializes current with x.

constexpr reverse_iterator(const reverse_iterator<ConvertibleTo<I>>& i);

Effects: Initializes current with i.current.

9.7.1.2.2 reverse_iterator::operator= [reverse.iter.op=]

constexpr reverse_iterator& operator=(const reverse_iterator<ConvertibleTo<I>>& i);

Effects: Assigns i.current to current.

Returns: *this.

9.7.1.2.3 Conversion [reverse.iter.conv]

constexpr I base() const;

Returns: current.

9.7.1.2.4 operator* [reverse.iter.op.star]

constexpr reference operator*() const;

Effects: Equivalent to: return *prev(current);

9.7.1.2.5 operator-> [reverse.iter.opref]

constexpr pointer operator->() const;

Effects: Equivalent to: return prev(current);

9.7.1.2.6 operator++ [reverse.iter.op++]

constexpr reverse_iterator& operator++();

Effects: -- current;

Returns: *this.

constexpr reverse_iterator operator++(int);

Effects:

reverse_iterator tmp = *this;
--current;
return tmp;

9.7.1.2.7 operator-- [reverse.iter.op--]

constexpr reverse_iterator& operator--();

Effects: ++current

Returns: *this.

constexpr reverse_iterator operator--(int);

Effects:

reverse_iterator tmp = *this;
++current;
return tmp;

9.7.1.2.8 operator+ [reverse.iter.op+]

constexpr reverse_iterator operator+(difference_type n) const requires RandomAccessIterator<I>;

Returns: reverse_iterator(current-n).

9.7.1.2.9 operator+= [reverse.iter.op+=]

constexpr reverse_iterator& operator+=(difference_type n) requires RandomAccessIterator<I>;

Effects: current -= n;

Returns: *this.

9.7.1.2.10 operator- [reverse.iter.op-]

constexpr reverse_iterator operator-(difference_type n) const requires RandomAccessIterator<I>;

Returns: reverse_iterator(current+n).

9.7.1.2.11 operator-= [reverse.iter.op-=]

constexpr reverse_iterator& operator-=(difference_type n) requires RandomAccessIterator<I>;

Effects: current += n;

Returns: *this.

9.7.1.2.12 operator[] [reverse.iter.opindex]

constexpr reference operator[]( difference_type n) const requires RandomAccessIterator<I>;

Returns: current[-n-1].

9.7.1.2.13 operator== [reverse.iter.op==]

template <class I1, class I2> requires EqualityComparableWith<I1, I2> constexpr bool operator==( const reverse_iterator<I1>& x, const reverse_iterator<I2>& y);

Effects: Equivalent to: return x.current == y.current;

9.7.1.2.14 operator!= [reverse.iter.op!=]

template <class I1, class I2> requires EqualityComparableWith<I1, I2> constexpr bool operator!=( const reverse_iterator<I1>& x, const reverse_iterator<I2>& y);

Effects: Equivalent to: return x.current != y.current;

9.7.1.2.15 operator< [reverse.iter.op<]

template <class I1, class I2> requires StrictTotallyOrderedWith<I1, I2> constexpr bool operator<( const reverse_iterator<I1>& x, const reverse_iterator<I2>& y);

Effects: Equivalent to: return x.current > y.current;

9.7.1.2.16 operator> [reverse.iter.op>]

template <class I1, class I2> requires StrictTotallyOrderedWith<I1, I2> constexpr bool operator>( const reverse_iterator<I1>& x, const reverse_iterator<I2>& y);

Effects: Equivalent to: return x.current < y.current;

9.7.1.2.17 operator>= [reverse.iter.op>=]

template <class I1, class I2> requires StrictTotallyOrderedWith<I1, I2> constexpr bool operator>=( const reverse_iterator<I1>& x, const reverse_iterator<I2>& y);

Effects: Equivalent to: return x.current <= y.current;

9.7.1.2.18 operator<= [reverse.iter.op<=]

template <class I1, class I2> requires StrictTotallyOrderedWith<I1, I2> constexpr bool operator<=( const reverse_iterator<I1>& x, const reverse_iterator<I2>& y);

Effects: Equivalent to: return x.current >= y.current;

9.7.1.2.19 operator- [reverse.iter.opdiff]

template <class I1, class I2> requires SizedSentinel<I1, I2> constexpr difference_type_t<I2> operator-( const reverse_iterator<I1>& x, const reverse_iterator<I2>& y);

Effects: Equivalent to: return y.current - x.current;

9.7.1.2.20 operator+ [reverse.iter.opsum]

template <RandomAccessIterator I> constexpr reverse_iterator<I> operator+( difference_type_t<I> n, const reverse_iterator<I>& x);

Effects: Equivalent to: return reverse_iterator<I>(x.current - n);

9.7.1.2.21 iter_move [reverse.iter.iter_move]

friend constexpr rvalue_reference_t<I> iter_move(const reverse_iterator& i) noexcept(see below);

Effects: Equivalent to: return ranges::iter_move(prev(i.current));

Remarks: The expression in noexcept is equivalent to:

   noexcept(ranges::iter_move(declval<I&>())) && noexcept(--declval<I&>()) &&
     is_nothrow_copy_constructible<I>::value

9.7.1.2.22 iter_swap [reverse.iter.iter_swap]

template <IndirectlySwappable<I> I2> friend constexpr void iter_swap(const reverse_iterator& x, const reverse_iterator<I2>& y) noexcept(see below);

Effects: Equivalent to ranges::iter_swap(prev(x.current), prev(y.current)).

Remarks: The expression in noexcept is equivalent to:

  noexcept(ranges::iter_swap(declval<I>(), declval<I>())) && noexcept(--declval<I&>())

9.7.1.2.23 Non-member function make_reverse_iterator() [reverse.iter.make]

template <BidirectionalIterator I> constexpr reverse_iterator<I> make_reverse_iterator(I i);

Returns: reverse_iterator<I>(i).