1<?xml version="1.0" encoding="utf-8" ?> 2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 4<head> 5<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" /> 7<title>Zip Iterator</title> 8<meta name="author" content="David Abrahams, Thomas Becker" /> 9<meta name="organization" content="Boost Consulting, Zephyr Associates, Inc." /> 10<meta name="date" content="2006-09-11" /> 11<meta name="copyright" content="Copyright David Abrahams and Thomas Becker 2003." /> 12<link rel="stylesheet" href="../../../rst.css" type="text/css" /> 13</head> 14<body> 15<div class="document" id="zip-iterator"> 16<h1 class="title">Zip Iterator</h1> 17<table class="docinfo" frame="void" rules="none"> 18<col class="docinfo-name" /> 19<col class="docinfo-content" /> 20<tbody valign="top"> 21<tr><th class="docinfo-name">Author:</th> 22<td>David Abrahams, Thomas Becker</td></tr> 23<tr><th class="docinfo-name">Contact:</th> 24<td><a class="first reference external" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="last reference external" href="mailto:thomas@styleadvisor.com">thomas@styleadvisor.com</a></td></tr> 25<tr><th class="docinfo-name">Organization:</th> 26<td><a class="first reference external" href="http://www.boost-consulting.com">Boost Consulting</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr> 27<tr><th class="docinfo-name">Date:</th> 28<td>2006-09-11</td></tr> 29<tr><th class="docinfo-name">Copyright:</th> 30<td>Copyright David Abrahams and Thomas Becker 2003.</td></tr> 31</tbody> 32</table> 33<!-- Distributed under the Boost --> 34<!-- Software License, Version 1.0. (See accompanying --> 35<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> 36<table class="docutils field-list" frame="void" rules="none"> 37<col class="field-name" /> 38<col class="field-body" /> 39<tbody valign="top"> 40<tr class="field"><th class="field-name">abstract:</th><td class="field-body"><!-- Copyright David Abrahams 2006. Distributed under the Boost --> 41<!-- Software License, Version 1.0. (See accompanying --> 42<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> 43The zip iterator provides the ability to parallel-iterate 44over several controlled sequences simultaneously. A zip 45iterator is constructed from a tuple of iterators. Moving 46the zip iterator moves all the iterators in parallel. 47Dereferencing the zip iterator returns a tuple that contains 48the results of dereferencing the individual iterators.</td> 49</tr> 50</tbody> 51</table> 52<div class="contents topic" id="table-of-contents"> 53<p class="topic-title first">Table of Contents</p> 54<ul class="simple"> 55<li><a class="reference internal" href="#zip-iterator-synopsis" id="id1"><tt class="docutils literal"><span class="pre">zip_iterator</span></tt> synopsis</a></li> 56<li><a class="reference internal" href="#zip-iterator-requirements" id="id2"><tt class="docutils literal"><span class="pre">zip_iterator</span></tt> requirements</a></li> 57<li><a class="reference internal" href="#zip-iterator-models" id="id3"><tt class="docutils literal"><span class="pre">zip_iterator</span></tt> models</a></li> 58<li><a class="reference internal" href="#zip-iterator-operations" id="id4"><tt class="docutils literal"><span class="pre">zip_iterator</span></tt> operations</a></li> 59<li><a class="reference internal" href="#examples" id="id5">Examples</a></li> 60</ul> 61</div> 62<div class="section" id="zip-iterator-synopsis"> 63<h1><a class="toc-backref" href="#id1"><tt class="docutils literal"><span class="pre">zip_iterator</span></tt> synopsis</a></h1> 64<!-- Copyright David Abrahams 2006. Distributed under the Boost --> 65<!-- Software License, Version 1.0. (See accompanying --> 66<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> 67<pre class="literal-block"> 68template<typename IteratorTuple> 69class zip_iterator 70{ 71 72public: 73 typedef /* see below */ reference; 74 typedef reference value_type; 75 typedef value_type* pointer; 76 typedef /* see below */ difference_type; 77 typedef /* see below */ iterator_category; 78 79 zip_iterator(); 80 zip_iterator(IteratorTuple iterator_tuple); 81 82 template<typename OtherIteratorTuple> 83 zip_iterator( 84 const zip_iterator<OtherIteratorTuple>& other 85 , typename enable_if_convertible< 86 OtherIteratorTuple 87 , IteratorTuple>::type* = 0 // exposition only 88 ); 89 90 const IteratorTuple& get_iterator_tuple() const; 91 92private: 93 IteratorTuple m_iterator_tuple; // exposition only 94}; 95 96template<typename IteratorTuple> 97zip_iterator<IteratorTuple> 98make_zip_iterator(IteratorTuple t); 99</pre> 100<p>The <tt class="docutils literal"><span class="pre">reference</span></tt> member of <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> is the type of the tuple 101made of the reference types of the iterator types in the <tt class="docutils literal"><span class="pre">IteratorTuple</span></tt> 102argument.</p> 103<p>The <tt class="docutils literal"><span class="pre">difference_type</span></tt> member of <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> is the <tt class="docutils literal"><span class="pre">difference_type</span></tt> 104of the first of the iterator types in the <tt class="docutils literal"><span class="pre">IteratorTuple</span></tt> argument.</p> 105<p>The <tt class="docutils literal"><span class="pre">iterator_category</span></tt> member of <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> is convertible to the 106minimum of the traversal categories of the iterator types in the <tt class="docutils literal"><span class="pre">IteratorTuple</span></tt> 107argument. For example, if the <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> holds only vector 108iterators, then <tt class="docutils literal"><span class="pre">iterator_category</span></tt> is convertible to 109<tt class="docutils literal"><span class="pre">boost::random_access_traversal_tag</span></tt>. If you add a list iterator, then 110<tt class="docutils literal"><span class="pre">iterator_category</span></tt> will be convertible to <tt class="docutils literal"><span class="pre">boost::bidirectional_traversal_tag</span></tt>, 111but no longer to <tt class="docutils literal"><span class="pre">boost::random_access_traversal_tag</span></tt>.</p> 112</div> 113<div class="section" id="zip-iterator-requirements"> 114<h1><a class="toc-backref" href="#id2"><tt class="docutils literal"><span class="pre">zip_iterator</span></tt> requirements</a></h1> 115<p>All iterator types in the argument <tt class="docutils literal"><span class="pre">IteratorTuple</span></tt> shall model Readable Iterator.</p> 116</div> 117<div class="section" id="zip-iterator-models"> 118<h1><a class="toc-backref" href="#id3"><tt class="docutils literal"><span class="pre">zip_iterator</span></tt> models</a></h1> 119<p>The resulting <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> models Readable Iterator.</p> 120<p>The fact that the <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> models only Readable Iterator does not 121prevent you from modifying the values that the individual iterators point 122to. The tuple returned by the <tt class="docutils literal"><span class="pre">zip_iterator</span></tt>'s <tt class="docutils literal"><span class="pre">operator*</span></tt> is a tuple 123constructed from the reference types of the individual iterators, not 124their value types. For example, if <tt class="docutils literal"><span class="pre">zip_it</span></tt> is a <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> whose 125first member iterator is an <tt class="docutils literal"><span class="pre">std::vector<double>::iterator</span></tt>, then the 126following line will modify the value which the first member iterator of 127<tt class="docutils literal"><span class="pre">zip_it</span></tt> currently points to:</p> 128<pre class="literal-block"> 129zip_it->get<0>() = 42.0; 130</pre> 131<p>Consider the set of standard traversal concepts obtained by taking 132the most refined standard traversal concept modeled by each individual 133iterator type in the <tt class="docutils literal"><span class="pre">IteratorTuple</span></tt> argument.The <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> 134models the least refined standard traversal concept in this set.</p> 135<p><tt class="docutils literal"><span class="pre">zip_iterator<IteratorTuple1></span></tt> is interoperable with 136<tt class="docutils literal"><span class="pre">zip_iterator<IteratorTuple2></span></tt> if and only if <tt class="docutils literal"><span class="pre">IteratorTuple1</span></tt> 137is interoperable with <tt class="docutils literal"><span class="pre">IteratorTuple2</span></tt>.</p> 138</div> 139<div class="section" id="zip-iterator-operations"> 140<h1><a class="toc-backref" href="#id4"><tt class="docutils literal"><span class="pre">zip_iterator</span></tt> operations</a></h1> 141<p>In addition to the operations required by the concepts modeled by 142<tt class="docutils literal"><span class="pre">zip_iterator</span></tt>, <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> provides the following 143operations.</p> 144<p><tt class="docutils literal"><span class="pre">zip_iterator();</span></tt></p> 145<table class="docutils field-list" frame="void" rules="none"> 146<col class="field-name" /> 147<col class="field-body" /> 148<tbody valign="top"> 149<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> with <tt class="docutils literal"><span class="pre">m_iterator_tuple</span></tt> 150default constructed.</td> 151</tr> 152</tbody> 153</table> 154<p><tt class="docutils literal"><span class="pre">zip_iterator(IteratorTuple</span> <span class="pre">iterator_tuple);</span></tt></p> 155<table class="docutils field-list" frame="void" rules="none"> 156<col class="field-name" /> 157<col class="field-body" /> 158<tbody valign="top"> 159<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> with <tt class="docutils literal"><span class="pre">m_iterator_tuple</span></tt> 160initialized to <tt class="docutils literal"><span class="pre">iterator_tuple</span></tt>.</td> 161</tr> 162</tbody> 163</table> 164<pre class="literal-block"> 165template<typename OtherIteratorTuple> 166zip_iterator( 167 const zip_iterator<OtherIteratorTuple>& other 168 , typename enable_if_convertible< 169 OtherIteratorTuple 170 , IteratorTuple>::type* = 0 // exposition only 171); 172</pre> 173<table class="docutils field-list" frame="void" rules="none"> 174<col class="field-name" /> 175<col class="field-body" /> 176<tbody valign="top"> 177<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> that is a copy of <tt class="docutils literal"><span class="pre">other</span></tt>.</td> 178</tr> 179<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="docutils literal"><span class="pre">OtherIteratorTuple</span></tt> is implicitly convertible to <tt class="docutils literal"><span class="pre">IteratorTuple</span></tt>.</td> 180</tr> 181</tbody> 182</table> 183<p><tt class="docutils literal"><span class="pre">const</span> <span class="pre">IteratorTuple&</span> <span class="pre">get_iterator_tuple()</span> <span class="pre">const;</span></tt></p> 184<table class="docutils field-list" frame="void" rules="none"> 185<col class="field-name" /> 186<col class="field-body" /> 187<tbody valign="top"> 188<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="docutils literal"><span class="pre">m_iterator_tuple</span></tt></td> 189</tr> 190</tbody> 191</table> 192<p><tt class="docutils literal"><span class="pre">reference</span> <span class="pre">operator*()</span> <span class="pre">const;</span></tt></p> 193<table class="docutils field-list" frame="void" rules="none"> 194<col class="field-name" /> 195<col class="field-body" /> 196<tbody valign="top"> 197<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A tuple consisting of the results of dereferencing all iterators in 198<tt class="docutils literal"><span class="pre">m_iterator_tuple</span></tt>.</td> 199</tr> 200</tbody> 201</table> 202<p><tt class="docutils literal"><span class="pre">zip_iterator&</span> <span class="pre">operator++();</span></tt></p> 203<table class="docutils field-list" frame="void" rules="none"> 204<col class="field-name" /> 205<col class="field-body" /> 206<tbody valign="top"> 207<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Increments each iterator in <tt class="docutils literal"><span class="pre">m_iterator_tuple</span></tt>.</td> 208</tr> 209<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="docutils literal"><span class="pre">*this</span></tt></td> 210</tr> 211</tbody> 212</table> 213<p><tt class="docutils literal"><span class="pre">zip_iterator&</span> <span class="pre">operator--();</span></tt></p> 214<table class="docutils field-list" frame="void" rules="none"> 215<col class="field-name" /> 216<col class="field-body" /> 217<tbody valign="top"> 218<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Decrements each iterator in <tt class="docutils literal"><span class="pre">m_iterator_tuple</span></tt>.</td> 219</tr> 220<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="docutils literal"><span class="pre">*this</span></tt></td> 221</tr> 222</tbody> 223</table> 224<pre class="literal-block"> 225template<typename IteratorTuple> 226zip_iterator<IteratorTuple> 227make_zip_iterator(IteratorTuple t); 228</pre> 229<table class="docutils field-list" frame="void" rules="none"> 230<col class="field-name" /> 231<col class="field-body" /> 232<tbody valign="top"> 233<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="docutils literal"><span class="pre">zip_iterator<IteratorTuple></span></tt> with <tt class="docutils literal"><span class="pre">m_iterator_tuple</span></tt> 234initialized to <tt class="docutils literal"><span class="pre">t</span></tt>.</td> 235</tr> 236</tbody> 237</table> 238<!-- Copyright David Abrahams 2006. Distributed under the Boost --> 239<!-- Software License, Version 1.0. (See accompanying --> 240<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> 241<pre class="literal-block"> 242template<typename IteratorTuple> 243zip_iterator<IteratorTuple> 244make_zip_iterator(IteratorTuple t); 245</pre> 246<table class="docutils field-list" frame="void" rules="none"> 247<col class="field-name" /> 248<col class="field-body" /> 249<tbody valign="top"> 250<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="docutils literal"><span class="pre">zip_iterator<IteratorTuple></span></tt> with <tt class="docutils literal"><span class="pre">m_iterator_tuple</span></tt> 251initialized to <tt class="docutils literal"><span class="pre">t</span></tt>.</td> 252</tr> 253</tbody> 254</table> 255<!-- Copyright David Abrahams 2006. Distributed under the Boost --> 256<!-- Software License, Version 1.0. (See accompanying --> 257<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> 258</div> 259<div class="section" id="examples"> 260<h1><a class="toc-backref" href="#id5">Examples</a></h1> 261<p>There are two main types of applications of the <tt class="docutils literal"><span class="pre">zip_iterator</span></tt>. The first 262one concerns runtime efficiency: If one has several controlled sequences 263of the same length that must be somehow processed, e.g., with the 264<tt class="docutils literal"><span class="pre">for_each</span></tt> algorithm, then it is more efficient to perform just 265one parallel-iteration rather than several individual iterations. For an 266example, assume that <tt class="docutils literal"><span class="pre">vect_of_doubles</span></tt> and <tt class="docutils literal"><span class="pre">vect_of_ints</span></tt> 267are two vectors of equal length containing doubles and ints, respectively, 268and consider the following two iterations:</p> 269<pre class="literal-block"> 270std::vector<double>::const_iterator beg1 = vect_of_doubles.begin(); 271std::vector<double>::const_iterator end1 = vect_of_doubles.end(); 272std::vector<int>::const_iterator beg2 = vect_of_ints.begin(); 273std::vector<int>::const_iterator end2 = vect_of_ints.end(); 274 275std::for_each(beg1, end1, func_0()); 276std::for_each(beg2, end2, func_1()); 277</pre> 278<p>These two iterations can now be replaced with a single one as follows:</p> 279<pre class="literal-block"> 280std::for_each( 281 boost::make_zip_iterator( 282 boost::make_tuple(beg1, beg2) 283 ), 284 boost::make_zip_iterator( 285 boost::make_tuple(end1, end2) 286 ), 287 zip_func() 288 ); 289</pre> 290<p>A non-generic implementation of <tt class="docutils literal"><span class="pre">zip_func</span></tt> could look as follows:</p> 291<pre class="literal-block"> 292struct zip_func : 293 public std::unary_function<const boost::tuple<const double&, const int&>&, void> 294{ 295 void operator()(const boost::tuple<const double&, const int&>& t) const 296 { 297 m_f0(t.get<0>()); 298 m_f1(t.get<1>()); 299 } 300 301private: 302 func_0 m_f0; 303 func_1 m_f1; 304}; 305</pre> 306<p>The second important application of the <tt class="docutils literal"><span class="pre">zip_iterator</span></tt> is as a building block 307to make combining iterators. A combining iterator is an iterator 308that parallel-iterates over several controlled sequences and, upon 309dereferencing, returns the result of applying a functor to the values of the 310sequences at the respective positions. This can now be achieved by using the 311<tt class="docutils literal"><span class="pre">zip_iterator</span></tt> in conjunction with the <tt class="docutils literal"><span class="pre">transform_iterator</span></tt>.</p> 312<p>Suppose, for example, that you have two vectors of doubles, say 313<tt class="docutils literal"><span class="pre">vect_1</span></tt> and <tt class="docutils literal"><span class="pre">vect_2</span></tt>, and you need to expose to a client 314a controlled sequence containing the products of the elements of 315<tt class="docutils literal"><span class="pre">vect_1</span></tt> and <tt class="docutils literal"><span class="pre">vect_2</span></tt>. Rather than placing these products 316in a third vector, you can use a combining iterator that calculates the 317products on the fly. Let us assume that <tt class="docutils literal"><span class="pre">tuple_multiplies</span></tt> is a 318functor that works like <tt class="docutils literal"><span class="pre">std::multiplies</span></tt>, except that it takes 319its two arguments packaged in a tuple. Then the two iterators 320<tt class="docutils literal"><span class="pre">it_begin</span></tt> and <tt class="docutils literal"><span class="pre">it_end</span></tt> defined below delimit a controlled 321sequence containing the products of the elements of <tt class="docutils literal"><span class="pre">vect_1</span></tt> and 322<tt class="docutils literal"><span class="pre">vect_2</span></tt>:</p> 323<pre class="literal-block"> 324typedef boost::tuple< 325 std::vector<double>::const_iterator, 326 std::vector<double>::const_iterator 327 > the_iterator_tuple; 328 329typedef boost::zip_iterator< 330 the_iterator_tuple 331 > the_zip_iterator; 332 333typedef boost::transform_iterator< 334 tuple_multiplies<double>, 335 the_zip_iterator 336 > the_transform_iterator; 337 338the_transform_iterator it_begin( 339 the_zip_iterator( 340 the_iterator_tuple( 341 vect_1.begin(), 342 vect_2.begin() 343 ) 344 ), 345 tuple_multiplies<double>() 346 ); 347 348the_transform_iterator it_end( 349 the_zip_iterator( 350 the_iterator_tuple( 351 vect_1.end(), 352 vect_2.end() 353 ) 354 ), 355 tuple_multiplies<double>() 356 ); 357</pre> 358</div> 359</div> 360<div class="footer"> 361<hr class="footer" /> 362<a class="reference external" href="zip_iterator.rst">View document source</a>. 363Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. 364 365</div> 366</body> 367</html> 368