File: zip_iterator_eg.rst

package info (click to toggle)
boost1.35 1.35.0-5
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 203,856 kB
  • ctags: 337,867
  • sloc: cpp: 938,683; xml: 56,847; ansic: 41,589; python: 18,999; sh: 11,566; makefile: 664; perl: 494; yacc: 456; asm: 353; csh: 6
file content (116 lines) | stat: -rw-r--r-- 3,670 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
.. Copyright David Abrahams 2006. Distributed under the Boost
.. Software License, Version 1.0. (See accompanying
.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

Examples
........

There are two main types of applications of the ``zip_iterator``. The first
one concerns runtime efficiency: If one has several controlled sequences
of the same length that must be somehow processed, e.g., with the 
``for_each`` algorithm, then it is more efficient to perform just
one parallel-iteration rather than several individual iterations. For an 
example, assume that ``vect_of_doubles`` and ``vect_of_ints``
are two vectors of equal length containing doubles and ints, respectively,
and consider the following two iterations:

::


    std::vector<double>::const_iterator beg1 = vect_of_doubles.begin();
    std::vector<double>::const_iterator end1 = vect_of_doubles.end();
    std::vector<int>::const_iterator beg2 = vect_of_ints.begin();
    std::vector<int>::const_iterator end2 = vect_of_ints.end();

    std::for_each(beg1, end1, func_0());
    std::for_each(beg2, end2, func_1());

These two iterations can now be replaced with a single one as follows:

::


    std::for_each(
      boost::make_zip_iterator(
        boost::make_tuple(beg1, beg2)
        ),
      boost::make_zip_iterator(
        boost::make_tuple(end1, end2)
        ),
      zip_func()
      );

A non-generic implementation of ``zip_func`` could look as follows:

::


      struct zip_func : 
        public std::unary_function<const boost::tuple<const double&, const int&>&, void>
      {
        void operator()(const boost::tuple<const double&, const int&>& t) const
        {
          m_f0(t.get<0>());
          m_f1(t.get<1>());
        }

      private:
        func_0 m_f0;
        func_1 m_f1;
      };

The second important application of the ``zip_iterator`` is as a building block
to make combining iterators. A combining iterator is an iterator
that parallel-iterates over several controlled sequences and, upon
dereferencing, returns the result of applying a functor to the values of the
sequences at the respective positions. This can now be achieved by using the
``zip_iterator`` in conjunction with the ``transform_iterator``. 

Suppose, for example, that you have two vectors of doubles, say 
``vect_1`` and ``vect_2``, and you need to expose to a client
a controlled sequence containing the products of the elements of 
``vect_1`` and ``vect_2``. Rather than placing these products
in a third vector, you can use a combining iterator that calculates the
products on the fly. Let us assume that ``tuple_multiplies`` is a
functor that works like ``std::multiplies``, except that it takes
its two arguments packaged in a tuple. Then the two iterators 
``it_begin`` and ``it_end`` defined below delimit a controlled
sequence containing the products of the elements of ``vect_1`` and
``vect_2``:

::


    typedef boost::tuple<
      std::vector<double>::const_iterator,
      std::vector<double>::const_iterator
      > the_iterator_tuple;

    typedef boost::zip_iterator<
      the_iterator_tuple
      > the_zip_iterator;

    typedef boost::transform_iterator<
      tuple_multiplies<double>,
      the_zip_iterator
      > the_transform_iterator;

    the_transform_iterator it_begin(
      the_zip_iterator(
        the_iterator_tuple(
          vect_1.begin(),
          vect_2.begin()
          )
        ),
      tuple_multiplies<double>()
      );

    the_transform_iterator it_end(
      the_zip_iterator(
        the_iterator_tuple(
          vect_1.end(),
          vect_2.end()
          )
        ),
      tuple_multiplies<double>()
      );