Brian Silverman | 5962333 | 2018-08-04 23:36:56 -0700 | [diff] [blame^] | 1 | |
| 2 | [section:reverse Reverse Iterator] |
| 3 | |
| 4 | The reverse iterator adaptor iterates through the adapted iterator |
| 5 | range in the opposite direction. |
| 6 | |
| 7 | [h2 Example] |
| 8 | |
| 9 | The following example prints an array of characters in reverse order |
| 10 | using `reverse_iterator`. |
| 11 | |
| 12 | |
| 13 | char letters_[] = "hello world!"; |
| 14 | const int N = sizeof(letters_)/sizeof(char) - 1; |
| 15 | typedef char* base_iterator; |
| 16 | base_iterator letters(letters_); |
| 17 | std::cout << "original sequence of letters:\t\t\t" << letters_ << std::endl; |
| 18 | |
| 19 | boost::reverse_iterator<base_iterator> |
| 20 | reverse_letters_first(letters + N), |
| 21 | reverse_letters_last(letters); |
| 22 | |
| 23 | std::cout << "sequence in reverse order:\t\t\t"; |
| 24 | std::copy(reverse_letters_first, reverse_letters_last, |
| 25 | std::ostream_iterator<char>(std::cout)); |
| 26 | std::cout << std::endl; |
| 27 | |
| 28 | std::cout << "sequence in double-reversed (normal) order:\t"; |
| 29 | std::copy(boost::make_reverse_iterator(reverse_letters_last), |
| 30 | boost::make_reverse_iterator(reverse_letters_first), |
| 31 | std::ostream_iterator<char>(std::cout)); |
| 32 | std::cout << std::endl; |
| 33 | |
| 34 | |
| 35 | |
| 36 | The output is: |
| 37 | |
| 38 | original sequence of letters: hello world! |
| 39 | sequence in reverse order: !dlrow olleh |
| 40 | sequence in double-reversed (normal) order: hello world! |
| 41 | |
| 42 | |
| 43 | The source code for this example can be found |
| 44 | [@../example/reverse_iterator_example.cpp here]. |
| 45 | |
| 46 | [h2 Reference] |
| 47 | |
| 48 | [h3 Synopsis] |
| 49 | |
| 50 | template <class Iterator> |
| 51 | class reverse_iterator |
| 52 | { |
| 53 | public: |
| 54 | typedef iterator_traits<Iterator>::value_type value_type; |
| 55 | typedef iterator_traits<Iterator>::reference reference; |
| 56 | typedef iterator_traits<Iterator>::pointer pointer; |
| 57 | typedef iterator_traits<Iterator>::difference_type difference_type; |
| 58 | typedef /* see below */ iterator_category; |
| 59 | |
| 60 | reverse_iterator() {} |
| 61 | explicit reverse_iterator(Iterator x) ; |
| 62 | |
| 63 | template<class OtherIterator> |
| 64 | reverse_iterator( |
| 65 | reverse_iterator<OtherIterator> const& r |
| 66 | , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition |
| 67 | ); |
| 68 | Iterator const& base() const; |
| 69 | reference operator*() const; |
| 70 | reverse_iterator& operator++(); |
| 71 | reverse_iterator& operator--(); |
| 72 | private: |
| 73 | Iterator m_iterator; // exposition |
| 74 | }; |
| 75 | |
| 76 | |
| 77 | If `Iterator` models Random Access Traversal Iterator and Readable |
| 78 | Lvalue Iterator, then `iterator_category` is convertible to |
| 79 | `random_access_iterator_tag`. Otherwise, if |
| 80 | `Iterator` models Bidirectional Traversal Iterator and Readable |
| 81 | Lvalue Iterator, then `iterator_category` is convertible to |
| 82 | `bidirectional_iterator_tag`. Otherwise, `iterator_category` is |
| 83 | convertible to `input_iterator_tag`. |
| 84 | |
| 85 | [h3 Requirements] |
| 86 | |
| 87 | `Iterator` must be a model of Bidirectional Traversal Iterator. The |
| 88 | type `iterator_traits<Iterator>::reference` must be the type of |
| 89 | `*i`, where `i` is an object of type `Iterator`. |
| 90 | |
| 91 | [h3 Concepts] |
| 92 | |
| 93 | A specialization of `reverse_iterator` models the same iterator |
| 94 | traversal and iterator access concepts modeled by its `Iterator` |
| 95 | argument. In addition, it may model old iterator concepts |
| 96 | specified in the following table: |
| 97 | |
| 98 | [table Categories |
| 99 | [[If `I` models ][then `reverse_iterator<I>` models]] |
| 100 | [[Readable Lvalue Iterator, Bidirectional Traversal Iterator][Bidirectional Iterator]] |
| 101 | [[Writable Lvalue Iterator, Bidirectional Traversal Iterator][Mutable Bidirectional Iterator]] |
| 102 | [[Readable Lvalue Iterator, Random Access Traversal Iterator][Random Access Iterator]] |
| 103 | [[Writable Lvalue Iterator, Random Access Traversal Iterator][Mutable Random Access Iterator]] |
| 104 | ] |
| 105 | |
| 106 | `reverse_iterator<X>` is interoperable with |
| 107 | `reverse_iterator<Y>` if and only if `X` is interoperable with |
| 108 | `Y`. |
| 109 | |
| 110 | [h3 Operations] |
| 111 | |
| 112 | In addition to the operations required by the concepts modeled by |
| 113 | `reverse_iterator`, `reverse_iterator` provides the following |
| 114 | operations. |
| 115 | |
| 116 | reverse_iterator(); |
| 117 | |
| 118 | [*Requires: ] `Iterator` must be Default Constructible.[br] |
| 119 | [*Effects: ] Constructs an instance of `reverse_iterator` with `m_iterator` |
| 120 | default constructed. |
| 121 | |
| 122 | explicit reverse_iterator(Iterator x); |
| 123 | |
| 124 | [*Effects: ] Constructs an instance of `reverse_iterator` with |
| 125 | `m_iterator` copy constructed from `x`. |
| 126 | |
| 127 | |
| 128 | template<class OtherIterator> |
| 129 | reverse_iterator( |
| 130 | reverse_iterator<OtherIterator> const& r |
| 131 | , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition |
| 132 | ); |
| 133 | |
| 134 | [*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br] |
| 135 | [*Effects: ] Constructs instance of `reverse_iterator` whose |
| 136 | `m_iterator` subobject is constructed from `y.base()`. |
| 137 | |
| 138 | |
| 139 | |
| 140 | Iterator const& base() const; |
| 141 | |
| 142 | [*Returns: ] `m_iterator` |
| 143 | |
| 144 | |
| 145 | reference operator*() const; |
| 146 | |
| 147 | [*Effects: ] Iterator tmp = m_iterator; return *--tmp; |
| 148 | |
| 149 | |
| 150 | reverse_iterator& operator++(); |
| 151 | |
| 152 | [*Effects: ] `--m_iterator`[br] |
| 153 | [*Returns: ] `*this` |
| 154 | |
| 155 | reverse_iterator& operator--(); |
| 156 | |
| 157 | [*Effects: ] `++m_iterator`[br] |
| 158 | [*Returns: ] `*this` |
| 159 | |
| 160 | [endsect] |