23 Iterators library [iterators]

23.5 Iterator adaptors [predef.iterators]

23.5.1 Reverse iterators [reverse.iterators]

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.

23.5.1.1 Class template reverse_­iterator [reverse.iterator]

namespace std {
  template<class Iterator>
  class reverse_iterator {
  public:
    using iterator_type     = Iterator;
    using iterator_concept  = see below;
    using iterator_category = see below;
    using value_type        = iter_value_t<Iterator>;
    using difference_type   = iter_difference_t<Iterator>;
    using pointer           = typename iterator_traits<Iterator>::pointer;
    using reference         = iter_reference_t<Iterator>;

    constexpr reverse_iterator();
    constexpr explicit reverse_iterator(Iterator x);
    template<class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
    template<class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);

    constexpr Iterator base() const;
    constexpr reference operator*() const;
    constexpr pointer   operator->() const requires see below;

    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;
    constexpr reverse_iterator& operator+=(difference_type n);
    constexpr reverse_iterator  operator- (difference_type n) const;
    constexpr reverse_iterator& operator-=(difference_type n);
    constexpr unspecified operator[](difference_type n) const;

    friend constexpr iter_rvalue_reference_t<Iterator>
      iter_move(const reverse_iterator& i) noexcept(see below);
    template<indirectly_swappable<Iterator> Iterator2>
      friend constexpr void
        iter_swap(const reverse_iterator& x,
                  const reverse_iterator<Iterator2>& y) noexcept(see below);

  protected:
    Iterator current;
  };
}
The member typedef-name iterator_­concept denotes
  • random_­access_­iterator_­tag if Iterator models random_­access_­iterator, and
  • bidirectional_­iterator_­tag otherwise.
The member typedef-name iterator_­category denotes
  • random_­access_­iterator_­tag if the type iterator_­traits<​Iterator>​::​iterator_­category models derived_­from<random_­access_­iterator_­tag>, and
  • iterator_­traits<​Iterator>​::​iterator_­category otherwise.

23.5.1.2 Requirements [reverse.iter.requirements]

The template parameter Iterator shall either meet the requirements of a Cpp17BidirectionalIterator ([bidirectional.iterators]) or model bidirectional_­iterator ([iterator.concept.bidir]).
Additionally, Iterator shall either meet the requirements of a Cpp17RandomAccessIterator ([random.access.iterators]) or model random_­access_­iterator ([iterator.concept.random.access]) if the definitions of any of the members or the non-member operators ([reverse.iter.cmp]) are instantiated ([temp.inst]).

23.5.1.3 Construction and assignment [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 Iterator.
constexpr explicit reverse_iterator(Iterator x);
Effects: Initializes current with x.
template<class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
Effects: Initializes current with u.current.
template<class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
Effects: Assigns u.base() to current.
Returns: *this.

23.5.1.4 Conversion [reverse.iter.conv]

constexpr Iterator base() const; // explicit
Returns: current.

23.5.1.5 Element access [reverse.iter.elem]

constexpr reference operator*() const;
Effects: As if by:
Iterator tmp = current;
return *--tmp;
constexpr pointer operator->() const requires (is_pointer_v<Iterator> || requires (const Iterator i) { i.operator->(); });
Effects:
  • If Iterator is a pointer type, equivalent to: return prev(current);
  • Otherwise, equivalent to: return prev(current).operator->();
constexpr unspecified operator[](difference_type n) const;
Returns: current[-n-1].

23.5.1.6 Navigation [reverse.iter.nav]

constexpr reverse_iterator operator+(difference_type n) const;
Returns: reverse_­iterator(current-n).
constexpr reverse_iterator operator-(difference_type n) const;
Returns: reverse_­iterator(current+n).
constexpr reverse_iterator& operator++();
Effects: As if by: --current;
Returns: *this.
constexpr reverse_iterator operator++(int);
Effects: As if by:
reverse_iterator tmp = *this;
--current;
return tmp;
constexpr reverse_iterator& operator--();
Effects: As if by ++current.
Returns: *this.
constexpr reverse_iterator operator--(int);
Effects: As if by:
reverse_iterator tmp = *this;
++current;
return tmp;
constexpr reverse_iterator& operator+=(difference_type n);
Effects: As if by: current -= n;
Returns: *this.
constexpr reverse_iterator& operator-=(difference_type n);
Effects: As if by: current += n;
Returns: *this.

23.5.1.7 Comparisons [reverse.iter.cmp]

template<class Iterator1, class Iterator2> constexpr bool operator==( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Constraints: x.base() == y.base() is well-formed and convertible to bool.
Returns: x.base() == y.base().
template<class Iterator1, class Iterator2> constexpr bool operator!=( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Constraints: x.base() != y.base() is well-formed and convertible to bool.
Returns: x.base() != y.base().
template<class Iterator1, class Iterator2> constexpr bool operator<( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Constraints: x.base() > y.base() is well-formed and convertible to bool.
Returns: x.base() > y.base().
template<class Iterator1, class Iterator2> constexpr bool operator>( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Constraints: x.base() < y.base() is well-formed and convertible to bool.
Returns: x.base() < y.base().
template<class Iterator1, class Iterator2> constexpr bool operator<=( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Constraints: x.base() >= y.base() is well-formed and convertible to bool.
Returns: x.base() >= y.base().
template<class Iterator1, class Iterator2> constexpr bool operator>=( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Constraints: x.base() <= y.base() is well-formed and convertible to bool.
Returns: x.base() <= y.base().
template<class Iterator1, three_­way_­comparable_­with<Iterator1> Iterator2> constexpr compare_three_way_result_t<Iterator1, Iterator2> operator<=>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Returns: y.base() <=> x.base().
Note
:
The argument order in the Returns: element is reversed because this is a reverse iterator.
— end note
 ]

23.5.1.8 Non-member functions [reverse.iter.nonmember]

template<class Iterator1, class Iterator2> constexpr auto operator-( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y) -> decltype(y.base() - x.base());
Returns: y.base() - x.base().
template<class Iterator> constexpr reverse_iterator<Iterator> operator+( typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& x);
Returns: reverse_­iterator<Iterator>(x.base() - n).
friend constexpr iter_rvalue_reference_t<Iterator> iter_move(const reverse_iterator& i) noexcept(see below);
Effects: Equivalent to:
auto tmp = i.base();
return ranges::iter_move(--tmp);
Remarks: The expression in noexcept is equivalent to:
is_nothrow_copy_constructible_v<Iterator> &&
noexcept(ranges::iter_move(--declval<Iterator&>()))
template<indirectly_­swappable<Iterator> Iterator2> friend constexpr void iter_swap(const reverse_iterator& x, const reverse_iterator<Iterator2>& y) noexcept(see below);
Effects: Equivalent to:
auto xtmp = x.base();
auto ytmp = y.base();
ranges::iter_swap(--xtmp, --ytmp);
Remarks: The expression in noexcept is equivalent to:
is_nothrow_copy_constructible_v<Iterator> &&
is_nothrow_copy_constructible_v<Iterator2> &&
noexcept(ranges::iter_swap(--declval<Iterator&>(), --declval<Iterator2&>()))
template<class Iterator> constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);
Returns: reverse_­iterator<Iterator>(i).