]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/iterator/doc/quickbook/zip_iterator.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / iterator / doc / quickbook / zip_iterator.qbk
1
2 [section:zip Zip Iterator]
3
4 The zip iterator provides the ability to parallel-iterate
5 over several controlled sequences simultaneously. A zip
6 iterator is constructed from a tuple of iterators. Moving
7 the zip iterator moves all the iterators in parallel.
8 Dereferencing the zip iterator returns a tuple that contains
9 the results of dereferencing the individual iterators.
10
11 The tuple of iterators is now implemented in terms of a Boost fusion sequence.
12 Because of this the 'tuple' may be any Boost fusion sequence and, for backwards
13 compatibility through a Boost fusion sequence adapter, a Boost tuple. Because the
14 'tuple' may be any boost::fusion sequence the 'tuple' may also be any type for which a
15 Boost fusion adapter exists. This includes, among others, a std::tuple and a std::pair.
16 Just remember to include the appropriate Boost fusion adapter header files for these
17 other Boost fusion adapters. The zip_iterator header file already includes the
18 Boost fusion adapter header file for Boost tuple, so you need not include it yourself
19 to use a Boost tuple as your 'tuple'.
20
21 [section:zip_example Example]
22
23 There are two main types of applications of the `zip_iterator`. The first
24 one concerns runtime efficiency: If one has several controlled sequences
25 of the same length that must be somehow processed, e.g., with the
26 `for_each` algorithm, then it is more efficient to perform just
27 one parallel-iteration rather than several individual iterations. For an
28 example, assume that `vect_of_doubles` and `vect_of_ints`
29 are two vectors of equal length containing doubles and ints, respectively,
30 and consider the following two iterations:
31
32 std::vector<double>::const_iterator beg1 = vect_of_doubles.begin();
33 std::vector<double>::const_iterator end1 = vect_of_doubles.end();
34 std::vector<int>::const_iterator beg2 = vect_of_ints.begin();
35 std::vector<int>::const_iterator end2 = vect_of_ints.end();
36
37 std::for_each(beg1, end1, func_0());
38 std::for_each(beg2, end2, func_1());
39
40 These two iterations can now be replaced with a single one as follows:
41
42
43 std::for_each(
44 boost::make_zip_iterator(
45 boost::make_tuple(beg1, beg2)
46 ),
47 boost::make_zip_iterator(
48 boost::make_tuple(end1, end2)
49 ),
50 zip_func()
51 );
52
53 A non-generic implementation of `zip_func` could look as follows:
54
55
56 struct zip_func :
57 public std::unary_function<const boost::tuple<const double&, const int&>&, void>
58 {
59 void operator()(const boost::tuple<const double&, const int&>& t) const
60 {
61 m_f0(t.get<0>());
62 m_f1(t.get<1>());
63 }
64
65 private:
66 func_0 m_f0;
67 func_1 m_f1;
68 };
69
70 The second important application of the `zip_iterator` is as a building block
71 to make combining iterators. A combining iterator is an iterator
72 that parallel-iterates over several controlled sequences and, upon
73 dereferencing, returns the result of applying a functor to the values of the
74 sequences at the respective positions. This can now be achieved by using the
75 `zip_iterator` in conjunction with the `transform_iterator`.
76
77 Suppose, for example, that you have two vectors of doubles, say
78 `vect_1` and `vect_2`, and you need to expose to a client
79 a controlled sequence containing the products of the elements of
80 `vect_1` and `vect_2`. Rather than placing these products
81 in a third vector, you can use a combining iterator that calculates the
82 products on the fly. Let us assume that `tuple_multiplies` is a
83 functor that works like `std::multiplies`, except that it takes
84 its two arguments packaged in a tuple. Then the two iterators
85 `it_begin` and `it_end` defined below delimit a controlled
86 sequence containing the products of the elements of `vect_1` and
87 `vect_2`:
88
89 typedef boost::tuple<
90 std::vector<double>::const_iterator,
91 std::vector<double>::const_iterator
92 > the_iterator_tuple;
93
94 typedef boost::zip_iterator<
95 the_iterator_tuple
96 > the_zip_iterator;
97
98 typedef boost::transform_iterator<
99 tuple_multiplies<double>,
100 the_zip_iterator
101 > the_transform_iterator;
102
103 the_transform_iterator it_begin(
104 the_zip_iterator(
105 the_iterator_tuple(
106 vect_1.begin(),
107 vect_2.begin()
108 )
109 ),
110 tuple_multiplies<double>()
111 );
112
113 the_transform_iterator it_end(
114 the_zip_iterator(
115 the_iterator_tuple(
116 vect_1.end(),
117 vect_2.end()
118 )
119 ),
120 tuple_multiplies<double>()
121 );
122
123 [endsect]
124
125 [section:zip_reference Reference]
126
127 [h2 Synopsis]
128
129 template<typename IteratorTuple>
130 class zip_iterator
131 {
132
133 public:
134 typedef /* see below */ reference;
135 typedef reference value_type;
136 typedef value_type* pointer;
137 typedef /* see below */ difference_type;
138 typedef /* see below */ iterator_category;
139
140 zip_iterator();
141 zip_iterator(IteratorTuple iterator_tuple);
142
143 template<typename OtherIteratorTuple>
144 zip_iterator(
145 const zip_iterator<OtherIteratorTuple>& other
146 , typename enable_if_convertible<
147 OtherIteratorTuple
148 , IteratorTuple>::type* = 0 // exposition only
149 );
150
151 const IteratorTuple& get_iterator_tuple() const;
152
153 private:
154 IteratorTuple m_iterator_tuple; // exposition only
155 };
156
157 template<typename IteratorTuple>
158 zip_iterator<IteratorTuple>
159 make_zip_iterator(IteratorTuple t);
160
161 The `reference` member of `zip_iterator` is the type of the tuple
162 made of the reference types of the iterator types in the `IteratorTuple`
163 argument.
164
165 The `difference_type` member of `zip_iterator` is the `difference_type`
166 of the first of the iterator types in the `IteratorTuple` argument.
167
168 The `iterator_category` member of `zip_iterator` is convertible to the
169 minimum of the traversal categories of the iterator types in the `IteratorTuple`
170 argument. For example, if the `zip_iterator` holds only vector
171 iterators, then `iterator_category` is convertible to
172 `boost::random_access_traversal_tag`. If you add a list iterator, then
173 `iterator_category` will be convertible to `boost::bidirectional_traversal_tag`,
174 but no longer to `boost::random_access_traversal_tag`.
175
176 [h2 Requirements]
177
178 All iterator types in the argument `IteratorTuple` shall model Readable Iterator.
179
180 [h2 Concepts]
181
182 The resulting `zip_iterator` models Readable Iterator.
183
184 The fact that the `zip_iterator` models only Readable Iterator does not
185 prevent you from modifying the values that the individual iterators point
186 to. The tuple returned by the `zip_iterator`'s `operator*` is a tuple
187 constructed from the reference types of the individual iterators, not
188 their value types. For example, if `zip_it` is a `zip_iterator` whose
189 first member iterator is an `std::vector<double>::iterator`, then the
190 following line will modify the value which the first member iterator of
191 `zip_it` currently points to:
192
193 zip_it->get<0>() = 42.0;
194
195
196 Consider the set of standard traversal concepts obtained by taking
197 the most refined standard traversal concept modeled by each individual
198 iterator type in the `IteratorTuple` argument.The `zip_iterator`
199 models the least refined standard traversal concept in this set.
200
201 `zip_iterator<IteratorTuple1>` is interoperable with
202 `zip_iterator<IteratorTuple2>` if and only if `IteratorTuple1`
203 is interoperable with `IteratorTuple2`.
204
205 [h2 Operations]
206
207 In addition to the operations required by the concepts modeled by
208 `zip_iterator`, `zip_iterator` provides the following
209 operations.
210
211 zip_iterator();
212
213 [*Returns:] An instance of `zip_iterator` with `m_iterator_tuple`
214 default constructed.
215
216
217 zip_iterator(IteratorTuple iterator_tuple);
218
219 [*Returns:] An instance of `zip_iterator` with `m_iterator_tuple`
220 initialized to `iterator_tuple`.
221
222
223 template<typename OtherIteratorTuple>
224 zip_iterator(
225 const zip_iterator<OtherIteratorTuple>& other
226 , typename enable_if_convertible<
227 OtherIteratorTuple
228 , IteratorTuple>::type* = 0 // exposition only
229 );
230
231 [*Returns:] An instance of `zip_iterator` that is a copy of `other`.[br]
232 [*Requires:] `OtherIteratorTuple` is implicitly convertible to `IteratorTuple`.
233
234
235 const IteratorTuple& get_iterator_tuple() const;
236
237 [*Returns:] `m_iterator_tuple`
238
239
240 reference operator*() const;
241
242 [*Returns:] A tuple consisting of the results of dereferencing all iterators in
243 `m_iterator_tuple`.
244
245
246 zip_iterator& operator++();
247
248 [*Effects:] Increments each iterator in `m_iterator_tuple`.[br]
249 [*Returns:] `*this`
250
251
252 zip_iterator& operator--();
253
254 [*Effects:] Decrements each iterator in `m_iterator_tuple`.[br]
255 [*Returns:] `*this`
256
257 template<typename IteratorTuple>
258 zip_iterator<IteratorTuple>
259 make_zip_iterator(IteratorTuple t);
260
261 [*Returns:] An instance of `zip_iterator<IteratorTuple>` with `m_iterator_tuple`
262 initialized to `t`.
263
264 [endsect]
265
266 [endsect]