Brian Silverman | 5962333 | 2018-08-04 23:36:56 -0700 | [diff] [blame^] | 1 | |
| 2 | [section:transform Transform Iterator] |
| 3 | |
| 4 | The transform iterator adapts an iterator by modifying the |
| 5 | `operator*` to apply a function object to the result of |
| 6 | dereferencing the iterator and returning the result. |
| 7 | |
| 8 | |
| 9 | [h2 Example] |
| 10 | |
| 11 | |
| 12 | This is a simple example of using the transform_iterators class to |
| 13 | generate iterators that multiply (or add to) the value returned by |
| 14 | dereferencing the iterator. It would be cooler to use lambda library |
| 15 | in this example. |
| 16 | |
| 17 | int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; |
| 18 | const int N = sizeof(x)/sizeof(int); |
| 19 | |
| 20 | typedef boost::binder1st< std::multiplies<int> > Function; |
| 21 | typedef boost::transform_iterator<Function, int*> doubling_iterator; |
| 22 | |
| 23 | doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)), |
| 24 | i_end(x + N, boost::bind1st(std::multiplies<int>(), 2)); |
| 25 | |
| 26 | std::cout << "multiplying the array by 2:" << std::endl; |
| 27 | while (i != i_end) |
| 28 | std::cout << *i++ << " "; |
| 29 | std::cout << std::endl; |
| 30 | |
| 31 | std::cout << "adding 4 to each element in the array:" << std::endl; |
| 32 | std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)), |
| 33 | boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)), |
| 34 | std::ostream_iterator<int>(std::cout, " ")); |
| 35 | std::cout << std::endl; |
| 36 | |
| 37 | |
| 38 | The output is: |
| 39 | |
| 40 | multiplying the array by 2: |
| 41 | 2 4 6 8 10 12 14 16 |
| 42 | adding 4 to each element in the array: |
| 43 | 5 6 7 8 9 10 11 12 |
| 44 | |
| 45 | |
| 46 | The source code for this example can be found |
| 47 | [@../example/transform_iterator_example.cpp here]. |
| 48 | |
| 49 | [h2 Reference] |
| 50 | |
| 51 | |
| 52 | [h3 Synopsis] |
| 53 | |
| 54 | template <class UnaryFunction, |
| 55 | class Iterator, |
| 56 | class Reference = use_default, |
| 57 | class Value = use_default> |
| 58 | class transform_iterator |
| 59 | { |
| 60 | public: |
| 61 | typedef /* see below */ value_type; |
| 62 | typedef /* see below */ reference; |
| 63 | typedef /* see below */ pointer; |
| 64 | typedef iterator_traits<Iterator>::difference_type difference_type; |
| 65 | typedef /* see below */ iterator_category; |
| 66 | |
| 67 | transform_iterator(); |
| 68 | transform_iterator(Iterator const& x, UnaryFunction f); |
| 69 | |
| 70 | template<class F2, class I2, class R2, class V2> |
| 71 | transform_iterator( |
| 72 | transform_iterator<F2, I2, R2, V2> const& t |
| 73 | , typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only |
| 74 | , typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only |
| 75 | ); |
| 76 | UnaryFunction functor() const; |
| 77 | Iterator const& base() const; |
| 78 | reference operator*() const; |
| 79 | transform_iterator& operator++(); |
| 80 | transform_iterator& operator--(); |
| 81 | private: |
| 82 | Iterator m_iterator; // exposition only |
| 83 | UnaryFunction m_f; // exposition only |
| 84 | }; |
| 85 | |
| 86 | |
| 87 | If `Reference` is `use_default` then the `reference` member of |
| 88 | `transform_iterator` is[br] |
| 89 | `result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`. |
| 90 | Otherwise, `reference` is `Reference`. |
| 91 | |
| 92 | |
| 93 | If `Value` is `use_default` then the `value_type` member is |
| 94 | `remove_cv<remove_reference<reference> >::type`. Otherwise, |
| 95 | `value_type` is `Value`. |
| 96 | |
| 97 | |
| 98 | If `Iterator` models Readable Lvalue Iterator and if `Iterator` |
| 99 | models Random Access Traversal Iterator, then `iterator_category` is |
| 100 | convertible to `random_access_iterator_tag`. Otherwise, if |
| 101 | `Iterator` models Bidirectional Traversal Iterator, then |
| 102 | `iterator_category` is convertible to |
| 103 | `bidirectional_iterator_tag`. Otherwise `iterator_category` is |
| 104 | convertible to `forward_iterator_tag`. If `Iterator` does not |
| 105 | model Readable Lvalue Iterator then `iterator_category` is |
| 106 | convertible to `input_iterator_tag`. |
| 107 | |
| 108 | |
| 109 | [h3 Requirements] |
| 110 | |
| 111 | |
| 112 | The type `UnaryFunction` must be Assignable, Copy Constructible, and |
| 113 | the expression `f(*i)` must be valid where `f` is a const object of |
| 114 | type `UnaryFunction`, `i` is an object of type `Iterator`, and |
| 115 | where the type of `f(*i)` must be |
| 116 | `result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`. |
| 117 | |
| 118 | |
| 119 | The argument `Iterator` shall model Readable Iterator. |
| 120 | |
| 121 | |
| 122 | [h3 Concepts] |
| 123 | |
| 124 | |
| 125 | The resulting `transform_iterator` models the most refined of the |
| 126 | following that is also modeled by `Iterator`. |
| 127 | |
| 128 | |
| 129 | * Writable Lvalue Iterator if `transform_iterator::reference` is a non-const reference. |
| 130 | |
| 131 | * Readable Lvalue Iterator if `transform_iterator::reference` is a const reference. |
| 132 | |
| 133 | * Readable Iterator otherwise. |
| 134 | |
| 135 | |
| 136 | The `transform_iterator` models the most refined standard traversal |
| 137 | concept that is modeled by the `Iterator` argument. |
| 138 | |
| 139 | |
| 140 | If `transform_iterator` is a model of Readable Lvalue Iterator then |
| 141 | it models the following original iterator concepts depending on what |
| 142 | the `Iterator` argument models. |
| 143 | |
| 144 | |
| 145 | [table Category |
| 146 | [[If `Iterator` models][then `transform_iterator` models]] |
| 147 | [[Single Pass Iterator][Input Iterator]] |
| 148 | [[Forward Traversal Iterator][Forward Iterator]] |
| 149 | [[Bidirectional Traversal Iterator][Bidirectional Iterator]] |
| 150 | [[Random Access Traversal Iterator][Random Access Iterator]] |
| 151 | ] |
| 152 | |
| 153 | If `transform_iterator` models Writable Lvalue Iterator then it is a |
| 154 | mutable iterator (as defined in the old iterator requirements). |
| 155 | |
| 156 | |
| 157 | `transform_iterator<F1, X, R1, V1>` is interoperable with |
| 158 | `transform_iterator<F2, Y, R2, V2>` if and only if `X` is |
| 159 | interoperable with `Y`. |
| 160 | |
| 161 | [h3 Operations] |
| 162 | |
| 163 | In addition to the operations required by the [link iterator.specialized.transform.concepts concepts] modeled by |
| 164 | `transform_iterator`, `transform_iterator` provides the following |
| 165 | operations: |
| 166 | |
| 167 | transform_iterator(); |
| 168 | |
| 169 | [*Returns: ] An instance of `transform_iterator` with `m_f` |
| 170 | and `m_iterator` default constructed. |
| 171 | |
| 172 | transform_iterator(Iterator const& x, UnaryFunction f); |
| 173 | |
| 174 | [*Returns: ] An instance of `transform_iterator` with `m_f` |
| 175 | initialized to `f` and `m_iterator` initialized to `x`. |
| 176 | |
| 177 | template<class F2, class I2, class R2, class V2> |
| 178 | transform_iterator( |
| 179 | transform_iterator<F2, I2, R2, V2> const& t |
| 180 | , typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only |
| 181 | , typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only |
| 182 | ); |
| 183 | |
| 184 | [*Returns: ] An instance of `transform_iterator` with `m_f` |
| 185 | initialized to `t.functor()` and `m_iterator` initialized to |
| 186 | `t.base()`.[br] |
| 187 | [*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`. |
| 188 | |
| 189 | |
| 190 | UnaryFunction functor() const; |
| 191 | |
| 192 | [*Returns: ] `m_f` |
| 193 | |
| 194 | |
| 195 | Iterator const& base() const; |
| 196 | |
| 197 | [*Returns: ] `m_iterator` |
| 198 | |
| 199 | |
| 200 | reference operator*() const; |
| 201 | |
| 202 | [*Returns: ] `m_f(*m_iterator)` |
| 203 | |
| 204 | |
| 205 | transform_iterator& operator++(); |
| 206 | |
| 207 | [*Effects: ] `++m_iterator`[br] |
| 208 | [*Returns: ] `*this` |
| 209 | |
| 210 | |
| 211 | transform_iterator& operator--(); |
| 212 | |
| 213 | [*Effects: ] `--m_iterator`[br] |
| 214 | [*Returns: ] `*this` |
| 215 | |
| 216 | [endsect] |