A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://en.cppreference.com/w/cpp/language/../header/../iterator/reverse_iterator.html below:

std::reverse_iterator - cppreference.com

template< class Iter >
class reverse_iterator;

std::reverse_iterator is an iterator adaptor that reverses the direction of a given iterator, which must be at least a LegacyBidirectionalIterator or model bidirectional_iterator(since C++20). In other words, when provided with a bidirectional iterator, std::reverse_iterator produces a new iterator that moves from the end to the beginning of the sequence defined by the underlying bidirectional iterator.

For a reverse iterator r constructed from an iterator i, the relationship &*r == &*(i - 1) is always true (as long as r is dereferenceable); thus a reverse iterator constructed from a one-past-the-end iterator dereferences to the last element in a sequence.

This is the iterator returned by member functions rbegin() and rend() of the standard library containers.

[edit] Nested types (until C++20) (since C++20)
  1. ↑ 1.0 1.1 The definition is provided by the base std::iterator specialization until C++17.
[edit] Data members Member Description Iter current the underlying iterator
(protected member object) [edit] Member functions [edit] Non-member functions [edit] Helper templates template< class Iterator1, class Iterator2 >

    requires (!std::sized_sentinel_for<Iterator1, Iterator2>)
inline constexpr bool disable_sized_sentinel_for

    <std::reverse_iterator<Iterator1>, std::reverse_iterator<Iterator2>> = true;
(since C++20)

This partial specialization of std::disable_sized_sentinel_for prevents specializations of reverse_iterator from satisfying sized_sentinel_for if their underlying iterators do not satisfy the concept.

[edit] Possible implementation

Below is a partial implementation focusing on the way the inner iterator is stored, calling std::prev only when the content is fetched via operator*.

template<class It>
class reverse_iterator
{
protected:
    It current = It();
public:
    reverse_iterator() = default;
    constexpr explicit reverse_iterator(It itr) : current(itr) {}
    template<class U>
        requires (!std::is_same_v<U, It> && std::convertible_to<const U&, It>)
    constexpr explicit reverse_iterator(const U& other) : current(other.base()) {}
 
    constexpr decltype(auto) operator*() const
    {
        return *std::prev(current); // <== returns the content of prev
    }
 
    constexpr reverse_iterator& operator++() { --current; return *this; }
    constexpr reverse_iterator operator++(int) { auto tmp = *this; ++(*this); return tmp; }
 
    constexpr reverse_iterator& operator--() { ++current; return *this; }
    constexpr reverse_iterator operator--(int) { auto tmp = *this; --(*this); return tmp; }
 
    constexpr It base() const { return current; }
 
    // Other member functions, friend functions, and member typedefs are not shown here.
};
[edit] Notes

std::reverse_iterator does not work with iterators whose dereference returns a reference to a member of *this (so-called “stashing iterators”). An example of a stashing iterator is MSVC STL's std::filesystem::path::iterator.

[edit] Example
#include <cstddef>
#include <iostream>
#include <iterator>
 
template<typename T, std::size_t SIZE>
class Stack
{
    T arr[SIZE];
    std::size_t pos = 0;
public:
    T pop()
    {
        return arr[--pos];
    }
 
    Stack& push(const T& t)
    {
        arr[pos++] = t;
        return *this;
    }
 
    // we wish that looping on Stack would be in LIFO order
    // thus we use std::reverse_iterator as an adaptor to existing iterators
    // (which are in this case the simple pointers: [arr, arr + pos)
    auto begin() { return std::reverse_iterator(arr + pos); }
    auto end() { return std::reverse_iterator(arr); }
};
 
int main()
{
    Stack<int, 8> s;
    s.push(5).push(15).push(25).push(35);
    for (int val : s)
        std::cout << val << ' ';
    std::cout << '\n';
}

Output:

[edit] See also creates a std::reverse_iterator of type inferred from the argument
(function template) [edit] base class to ease the definition of required types for simple iterators
(class template) [edit]

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4