1.. Copyright David Abrahams 2006. Distributed under the Boost 2.. Software License, Version 1.0. (See accompanying 3.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 5Examples 6........ 7 8There are two main types of applications of the ``zip_iterator``. The first 9one concerns runtime efficiency: If one has several controlled sequences 10of the same length that must be somehow processed, e.g., with the 11``for_each`` algorithm, then it is more efficient to perform just 12one parallel-iteration rather than several individual iterations. For an 13example, assume that ``vect_of_doubles`` and ``vect_of_ints`` 14are two vectors of equal length containing doubles and ints, respectively, 15and consider the following two iterations: 16 17:: 18 19 20 std::vector<double>::const_iterator beg1 = vect_of_doubles.begin(); 21 std::vector<double>::const_iterator end1 = vect_of_doubles.end(); 22 std::vector<int>::const_iterator beg2 = vect_of_ints.begin(); 23 std::vector<int>::const_iterator end2 = vect_of_ints.end(); 24 25 std::for_each(beg1, end1, func_0()); 26 std::for_each(beg2, end2, func_1()); 27 28These two iterations can now be replaced with a single one as follows: 29 30:: 31 32 33 std::for_each( 34 boost::make_zip_iterator( 35 boost::make_tuple(beg1, beg2) 36 ), 37 boost::make_zip_iterator( 38 boost::make_tuple(end1, end2) 39 ), 40 zip_func() 41 ); 42 43A non-generic implementation of ``zip_func`` could look as follows: 44 45:: 46 47 48 struct zip_func 49 { 50 void operator()(const boost::tuple<const double&, const int&>& t) const 51 { 52 m_f0(t.get<0>()); 53 m_f1(t.get<1>()); 54 } 55 56 private: 57 func_0 m_f0; 58 func_1 m_f1; 59 }; 60 61The second important application of the ``zip_iterator`` is as a building block 62to make combining iterators. A combining iterator is an iterator 63that parallel-iterates over several controlled sequences and, upon 64dereferencing, returns the result of applying a functor to the values of the 65sequences at the respective positions. This can now be achieved by using the 66``zip_iterator`` in conjunction with the ``transform_iterator``. 67 68Suppose, for example, that you have two vectors of doubles, say 69``vect_1`` and ``vect_2``, and you need to expose to a client 70a controlled sequence containing the products of the elements of 71``vect_1`` and ``vect_2``. Rather than placing these products 72in a third vector, you can use a combining iterator that calculates the 73products on the fly. Let us assume that ``tuple_multiplies`` is a 74functor that works like ``std::multiplies``, except that it takes 75its two arguments packaged in a tuple. Then the two iterators 76``it_begin`` and ``it_end`` defined below delimit a controlled 77sequence containing the products of the elements of ``vect_1`` and 78``vect_2``: 79 80:: 81 82 83 typedef boost::tuple< 84 std::vector<double>::const_iterator, 85 std::vector<double>::const_iterator 86 > the_iterator_tuple; 87 88 typedef boost::zip_iterator< 89 the_iterator_tuple 90 > the_zip_iterator; 91 92 typedef boost::transform_iterator< 93 tuple_multiplies<double>, 94 the_zip_iterator 95 > the_transform_iterator; 96 97 the_transform_iterator it_begin( 98 the_zip_iterator( 99 the_iterator_tuple( 100 vect_1.begin(), 101 vect_2.begin() 102 ) 103 ), 104 tuple_multiplies<double>() 105 ); 106 107 the_transform_iterator it_end( 108 the_zip_iterator( 109 the_iterator_tuple( 110 vect_1.end(), 111 vect_2.end() 112 ) 113 ), 114 tuple_multiplies<double>() 115 ); 116