# Reverse Iterator Adaptor

Defined in header boost/iterator_adaptors.hpp

The reverse iterator adaptor flips the direction of a base iterator's motion. Invoking `operator++()` moves the base iterator backward and invoking `operator--()` moves the base iterator forward. The Boost reverse iterator adaptor is better to use than the `std::reverse_iterator` class in situations where pairs of mutable/constant iterators are needed (e.g., in containers) because comparisons and conversions between the mutable and const versions are implemented correctly.

## Synopsis

    namespace boost {
      template <class BidirectionalIterator,
                class Value, class Reference, class Pointer, class Category, class Distance>
      struct reverse_iterator_generator;

      template <class BidirectionalIterator>
      typename reverse_iterator_generator<BidirectionalIterator>::type
      make_reverse_iterator(BidirectionalIterator base)
    }

## The Reverse Iterator Type Generator

The `reverse_iterator_generator` template is a generator of reverse iterator types. The main template parameter for this class is the base `BidirectionalIterator` type that is being adapted. In most cases the associated types of the base iterator can be deduced using `std::iterator_traits`, but in some situations the user may want to override these types, so there are also template parameters for the base iterator's associated types.

>     template <class BidirectionalIterator,
>               class Value, class Reference, class Pointer, class Category, class Distance>
>     class reverse_iterator_generator
>     {
>     public:
>       typedef iterator_adaptor<...> type; // the resulting reverse iterator type
>     };

### Example

In this example we sort a sequence of letters and then output the sequence in descending order using reverse iterators.

>     #include <boost/config.hpp>
>     #include <iostream>
>     #include <algorithm>
>     #include <boost/iterator_adaptors.hpp>

>     int main(int, char*[])
>     {
>       char letters[] = "hello world!";
>       const int N = sizeof(letters)/sizeof(char) - 1;
>       std::cout << "original sequence of letters:\t"
>           << letters << std::endl;

>       std::sort(letters, letters + N);

>       // Use reverse_iterator_generator to print a sequence
>       // of letters in reverse order.

>       boost::reverse_iterator_generator<char*>::type
>         reverse_letters_first(letters + N),
>         reverse_letters_last(letters);

>       std::cout << "letters in descending order:\t";
>       std::copy(reverse_letters_first, reverse_letters_last,
>           std::ostream_iterator<char>(std::cout));
>       std::cout << std::endl;

>       // to be continued...

The output is:

>     original sequence of letters: hello world!
>     letters in descending order:  wroolllhed!

### Template Parameters

Parameter | Description
--- | ---
`BidirectionalIterator` | The iterator type being wrapped.
`Value` | The value-type of the base iterator and the resulting reverse iterator. Default:`std::iterator_traits<BidirectionalIterator>::value_type`
`Reference` | The `reference` type of the resulting iterator, and in particular, the result type of `operator*()`. Default: If `Value` is supplied, `Value&` is used. Otherwise `std::iterator_traits<BidirectionalIterator>::reference` is used.
`Pointer` | The `pointer` type of the resulting iterator, and in particular, the result type of `operator->()`. Default: If `Value` was supplied, then `Value*`, otherwise `std::iterator_traits<BidirectionalIterator>::pointer`.
`Category` | The `iterator_category` type for the resulting iterator. Default: `std::iterator_traits<BidirectionalIterator>::iterator_category`
`Distance` | The `difference_type` for the resulting iterator. Default: `std::iterator_traits<BidirectionalIterator&gt::difference_type`

### Concept Model

The indirect iterator will model whichever standard iterator concept category is modeled by the base iterator. Thus, if the base iterator is a model of Random Access Iterator then so is the resulting indirect iterator. If the base iterator models a more restrictive concept, the resulting indirect iterator will model the same concept. The base iterator must be at least a Bidirectional Iterator

### Members

The reverse iterator type implements the member functions and operators required of the Random Access Iterator concept. In addition it has the following constructor:

>     reverse_iterator_generator::type(const BidirectionalIterator& it)

## The Reverse Iterator Object Generator

The `make_reverse_iterator()` function provides a more convenient way to create reverse iterator objects. The function saves the user the trouble of explicitly writing out the iterator types.

>     template <class BidirectionalIterator>
>     typename reverse_iterator_generator<BidirectionalIterator>::type
>     make_reverse_iterator(BidirectionalIterator base);

### Example

In this part of the example we use `make_reverse_iterator()` to print the sequence of letters in reverse-reverse order, which is the original order.

>       // continuing from the previous example...

>       std::cout << "letters in ascending order:\t";
>       std::copy(boost::make_reverse_iterator(reverse_letters_last),
>           boost::make_reverse_iterator(reverse_letters_first),
>           std::ostream_iterator<char>(std::cout));
>       std::cout << std::endl;

>       return 0;
>     }

The output is:

>     letters in ascending order:  !dehllloorw

## Constant/Mutable Iterator Interactions

One failing of the standard `reverse_iterator` adaptor is that it doesn't properly support interactions between adapted `const` and non-`const` iterators. For example:

>     #include <vector>

>     template <class T> void convert(T x) {}

>     // Test interactions of a matched pair of random access iterators
>     template <class Iterator, class ConstIterator>
>     void test_interactions(Iterator i, ConstIterator ci)
>     {
>       bool eq = i == ci;               // comparisons
>       bool ne = i != ci;
>       bool lt = i < ci;
>       bool le = i <= ci;
>       bool gt = i > ci;
>       bool ge = i >= ci;
>       std::size_t distance = i - ci;   // difference
>       ci = i;                          // assignment
>       ConstIterator ci2(i);            // construction
>       convert<ConstIterator>(i);       // implicit conversion
>     }

>     void f()
>     {
>       typedef std::vector<int> vec;
>       vec v;
>       const vec& cv;

>       test_interactions(v.begin(), cv.begin());   // OK
>       test_interactions(v.rbegin(), cv.rbegin()); // ERRORS ON EVERY TEST!!

Reverse iterators created with `boost::reverse_iterator_generator` don't have this problem, though:

>       typedef boost::reverse_iterator_generator<vec::iterator>::type ri;
>       typedef boost::reverse_iterator_generator<vec::const_iterator>::type cri;
>       test_interactions(ri(v.begin()), cri(cv.begin()));   // OK!!

Or, more simply,

>       test_interactions(
>         boost::make_reverse_iterator(v.begin()),
>         boost::make_reverse_iterator(cv.begin()));   // OK!!
>     }

If you are wondering why there is no `reverse_iterator_pair_generator` in the manner of `projection_iterator_pair_generator`, the answer is simple: we tried it, but found that in practice it took more typing to use `reverse_iterator_pair_generator` than to simply use `reverse_iterator_generator` twice!

Revised 19 Aug 2001

© Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.