Function templates next() and prior()

| Home | Libraries | People | FAQ | More

### 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
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.