| Author: | David Abrahams, Jeremy Siek, Thomas Witt |
|---|---|
| Contact: | dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de |
| Organization: | Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction |
| Date: | 2004-01-13 |
| Copyright: | Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved |
| abstract: | The reverse iterator adaptor iterates through the adapted iterator range in the opposite direction. |
|---|
template <class Iterator>
class reverse_iterator
{
public:
typedef iterator_traits<Iterator>::value_type value_type;
typedef iterator_traits<Iterator>::reference reference;
typedef iterator_traits<Iterator>::pointer pointer;
typedef iterator_traits<Iterator>::difference_type difference_type;
typedef /* see below */ iterator_category;
reverse_iterator() {}
explicit reverse_iterator(Iterator x) ;
template<class OtherIterator>
reverse_iterator(
reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
Iterator base() const;
reference operator*() const;
reverse_iterator& operator++();
reverse_iterator& operator--();
private:
Iterator m_iterator; // exposition
};
The iterator_category member is a type convertible to the iterator tag given by the following algorithm. Let T be iterator_traits<Iterator>::value_type, R be iterator_traits<Iterator>::reference, and C be traveral_category<Iterator>::type.
if (R is a reference to T) then
if (C is convertible to random_access_traversal_tag) then
random_access_iterator_tag
else
bidirectional_iterator_tag
else
input_iterator_tag
The base Iterator must be a model of Bidirectional Traversal Iterator and Readable Iterator.
reverse_iterator models the same standard traversal and access iterator concepts that the Iterator argument models. In addition, reverse_iterator models the old iterator concepts specified in the following table, depnding on what the Iterator argument models.
| If Iterator models | then reverse_iterator models |
|---|---|
| Readable Lvalue Iterator, Bidirectional Traversal Iterator | Bidirectional Iterator |
| Writable Lvalue Iterator, Bidirectional Traversal Iterator | Mutable Bidirectional Iterator |
| Readable Lvalue Iterator, Random Access Traversal Iterator | Random Access Iterator |
| Writable Lvalue Iterator, Random Access Traversal Iterator | Mutable Random Access Iterator |
In addition to the operations required by the concepts modeled by reverse_iterator, reverse_iterator provides the following operations.
reverse_iterator();
| Requires: | Iterator must be Default Constructible. |
|---|---|
| Returns: | An instance of reverse_iterator with m_iterator default constructed. |
explicit reverse_iterator(Iterator x);
| Returns: | An instance of reverse_iterator with a m_iterator constructed from x. |
|---|
template<class OtherIterator>
reverse_iterator(
reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
| Requires: | OtherIterator is implicitly convertible to Iterator. |
|---|---|
| Returns: | An instance of reverse_iterator that is a copy of r. |
Iterator base() const;
| Returns: | m_iterator |
|---|
reference operator*() const;
| Effects: |
|---|
Iterator tmp = m_iterator; return *--tmp;
reverse_iterator& operator++();
| Effects: | --m_iterator |
|---|---|
| Returns: | *this |
reverse_iterator& operator--();
| Effects: | ++m_iterator |
|---|---|
| Returns: | *this |
template <class BidirectionalIterator> reverse_iterator<BidirectionalIterator>n make_reverse_iterator(BidirectionalIterator x);
| Returns: | An instance of reverse_iterator<BidirectionalIterator> with a current constructed from x. |
|---|
The following example prints an array of characters in reverse order using reverse_iterator.
char letters_[] = "hello world!";
const int N = sizeof(letters_)/sizeof(char) - 1;
typedef char* base_iterator;
base_iterator letters(letters_);
std::cout << "original sequence of letters:\t\t\t" << letters_ << std::endl;
boost::reverse_iterator<base_iterator>
reverse_letters_first(letters + N),
reverse_letters_last(letters);
std::cout << "sequence in reverse order:\t\t\t";
std::copy(reverse_letters_first, reverse_letters_last,
std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
std::cout << "sequence in double-reversed (normal) 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;
The output is:
original sequence of letters: hello world! sequence in reverse order: !dlrow olleh sequence in double-reversed (normal) order: hello world!
The source code for this example can be found here.