• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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