Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Function templates next() and prior()

Certain data types, such as the C++ Standard Library's forward and bidirectional iterators, do not provide addition and subtraction via operator+() or operator-(). This means that non-modifying computation of the next or prior value requires a temporary, even though operator++() or operator--() is provided. It also means that writing code like itr+1 inside a template restricts the iterator category to random access iterators.

The next() and prior() functions defined in boost/next_prior.hpp provide a simple way around these problems.

Synopsis
template <class T>
T next(T x)
{
    return ++x;
}

template <class T, class Distance>
T next(T x, Distance n)
{
    std::advance(x, n);
    return x;
}

template <class T>
T prior(T x)
{
    return --x;
}

template <class T, class Distance>
T prior(T x, Distance n)
{
    std::advance(x, -n);
    return x;
}
[Note] Note

Function implementations above are given for exposition only. The actual implementation has the same effect for iterators, but has different properties, as documented later.

Usage

Usage is simple:

const std::list<T>::iterator p = get_some_iterator();
const std::list<T>::iterator prev = boost::prior(p);
const std::list<T>::iterator next = boost::next(prev, 2);

The distance from the given iterator should be supplied as an absolute value. For example, the iterator four iterators prior to the given iterator p may be obtained by prior(p, 4).

With C++11, the Standard Library provides std::next() and std::prev() function templates, which serve the same purpose. However, there are advantages to boost::next() and boost::prior().

First, boost::next() and boost::prior() are compatible not only with iterators but with any type that provides arithmetic operators operator++(), operator--(), operator+(), operator-(), operator+=() or operator-=(). For example, this is possible:

int x = 10;
int y = boost::next(x, 5);
assert(y == 15);

Second, boost::next() and boost::prior() use traversal categories to select the most efficient implementation. For some kinds of iterators, such as transform iterators, the standard iterator category does not reflect the traversal category correctly and therefore std::next() and std::prev() will fall back to linear complexity.

Acknowledgements

Contributed by Dave Abrahams. Two-argument versions by Daniel Walker.


PrevUpHomeNext