mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 04:50:34 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			117 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. 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>()
 | |
|       );
 |