From 17c373ded3185255115df132d7c5bf93d33d6419 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 27 Jan 2004 04:12:54 +0000 Subject: [PATCH] Added zip_iterator docs [SVN r21988] --- doc/make_zip_iterator.rst | 8 + doc/zip_iterator.html | 352 ++++++++++++++++++++++++++++++++++ doc/zip_iterator.rst | 25 +++ doc/zip_iterator_abstract.rst | 6 + doc/zip_iterator_eg.rst | 117 +++++++++++ doc/zip_iterator_ref.rst | 152 +++++++++++++++ 6 files changed, 660 insertions(+) create mode 100755 doc/make_zip_iterator.rst create mode 100755 doc/zip_iterator.html create mode 100755 doc/zip_iterator.rst create mode 100755 doc/zip_iterator_abstract.rst create mode 100755 doc/zip_iterator_eg.rst create mode 100755 doc/zip_iterator_ref.rst diff --git a/doc/make_zip_iterator.rst b/doc/make_zip_iterator.rst new file mode 100755 index 0000000..0369760 --- /dev/null +++ b/doc/make_zip_iterator.rst @@ -0,0 +1,8 @@ +:: + + template + zip_iterator + make_zip_iterator(IteratorTuple t); + +:Returns: An instance of ``zip_iterator`` with ``m_iterator_tuple`` + initialized to ``t``. diff --git a/doc/zip_iterator.html b/doc/zip_iterator.html new file mode 100755 index 0000000..c76823a --- /dev/null +++ b/doc/zip_iterator.html @@ -0,0 +1,352 @@ + + + + + + +Zip Iterator + + + + + + + +
+

Zip Iterator

+ +++ + + + + + + + + + + + +
Author:David Abrahams, Thomas Becker
Contact:dave@boost-consulting.com, thomas@styleadvisor.com
Organization:Boost Consulting, Zephyr Associates, Inc.
Date:2004-01-19
Copyright:Copyright David Abrahams and Thomas Becker 2003. All rights reserved
+ +++ + + + +
abstract:The zip iterator provides the ability to parallel-iterate +over several controlled sequences simultaneously. A zip +iterator is constructed from a tuple of iterators. Moving +the zip iterator moves all the iterators in parallel. +Dereferencing the zip iterator returns a tuple that contains +the results of dereferencing the individual iterators.
+ +
+

zip_iterator synopsis

+
+template<typename IteratorTuple>
+class zip_iterator
+{  
+
+public:
+  typedef /* see below */ reference;
+  typedef reference value_type;
+  typedef value_type* pointer;
+  typedef /* see below */ difference_type;
+  typedef /* see below */ iterator_category;
+
+  zip_iterator();
+  zip_iterator(IteratorTuple iterator_tuple);
+
+  template<typename OtherIteratorTuple>
+  zip_iterator(
+        const zip_iterator<OtherIteratorTuple>& other
+      , typename enable_if_convertible<
+              OtherIteratorTuple
+            , IteratorTuple>::type* = 0     // exposition only
+  );
+
+  const IteratorTuple& get_iterator_tuple() const;
+
+private:
+  IteratorTuple m_iterator_tuple;     // exposition only
+};
+
+template<typename IteratorTuple> 
+zip_iterator<IteratorTuple> 
+make_zip_iterator(IteratorTuple t);
+
+

The reference member of zip_iterator is the type of the tuple +made of the reference types of the iterator types in the IteratorTuple +argument.

+

The difference_type member of zip_iterator is the difference_type +of the first of the iterator types in the IteratorTuple argument.

+

The iterator_category member of zip_iterator is convertible to the +minimum of the traversal categories of the iterator types in the IteratorTuple +argument. For example, if the zip_iterator holds only vector +iterators, then iterator_category is convertible to +boost::random_access_traversal_tag. If you add a list iterator, then +iterator_category will be convertible to boost::bidirectional_traversal_tag, +but no longer to boost::random_access_traversal_tag.

+
+
+

zip_iterator requirements

+

All iterator types in the argument IteratorTuple shall model Readable Iterator.

+
+
+

zip_iterator models

+

The resulting zip_iterator models Readable Iterator.

+

The fact that the zip_iterator models only Readable Iterator does not +prevent you from modifying the values that the individual iterators point +to. The tuple returned by the zip_iterator's operator* is a tuple +constructed from the reference types of the individual iterators, not +their value types. For example, if zip_it is a zip_iterator whose +first member iterator is an std::vector<double>::iterator, then the +following line will modify the value which the first member iterator of +zip_it currently points to:

+
+zip_it->get<0>() = 42.0;
+
+

Consider the set of standard traversal concepts obtained by taking +the most refined standard traversal concept modeled by each individual +iterator type in the IteratorTuple argument.The zip_iterator +models the least refined standard traversal concept in this set.

+

zip_iterator<IteratorTuple1> is interoperable with +zip_iterator<IteratorTuple2> if and only if IteratorTuple1 +is interoperable with IteratorTuple2.

+
+
+

zip_iterator operations

+

In addition to the operations required by the concepts modeled by +zip_iterator, zip_iterator provides the following +operations.

+

zip_iterator();

+ +++ + + + +
Returns:An instance of zip_iterator with m_iterator_tuple +default constructed.
+

zip_iterator(IteratorTuple iterator_tuple);

+ +++ + + + +
Returns:An instance of zip_iterator with m_iterator_tuple +initialized to iterator_tuple.
+
+template<typename OtherIteratorTuple>
+zip_iterator(
+      const zip_iterator<OtherIteratorTuple>& other
+    , typename enable_if_convertible<
+            OtherIteratorTuple
+          , IteratorTuple>::type* = 0     // exposition only
+);
+
+ +++ + + + + + +
Returns:An instance of zip_iterator that is a copy of other.
Requires:OtherIteratorTuple is implicitly convertible to IteratorTuple.
+

const IteratorTuple& get_iterator_tuple() const;

+ +++ + + + +
Returns:m_iterator_tuple
+

reference operator*() const;

+ +++ + + + +
Returns:A tuple consisting of the results of dereferencing all iterators in +m_iterator_tuple.
+

zip_iterator& operator++();

+ +++ + + + + + +
Effects:Increments each iterator in m_iterator_tuple.
Returns:*this
+

zip_iterator& operator--();

+ +++ + + + + + +
Effects:Decrements each iterator in m_iterator_tuple.
Returns:*this
+
+template<typename IteratorTuple> 
+zip_iterator<IteratorTuple> 
+make_zip_iterator(IteratorTuple t);
+
+ +++ + + + +
Returns:An instance of zip_iterator<IteratorTuple> with m_iterator_tuple +initialized to t.
+
+template<typename IteratorTuple> 
+zip_iterator<IteratorTuple> 
+make_zip_iterator(IteratorTuple t);
+
+ +++ + + + +
Returns:An instance of zip_iterator<IteratorTuple> with m_iterator_tuple +initialized to t.
+
+
+

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>()
+  );
+
+

The source code for these examples can be found here.

+
+
+ + + + diff --git a/doc/zip_iterator.rst b/doc/zip_iterator.rst new file mode 100755 index 0000000..cf9327c --- /dev/null +++ b/doc/zip_iterator.rst @@ -0,0 +1,25 @@ ++++++++++++++ + Zip Iterator ++++++++++++++ + +:Author: David Abrahams, Thomas Becker +:Contact: dave@boost-consulting.com, thomas@styleadvisor.com +:organization: `Boost Consulting`_, `Zephyr Associates, Inc.`_ +:date: $Date$ +:copyright: Copyright David Abrahams and Thomas Becker 2003. All rights reserved + +.. _`Boost Consulting`: http://www.boost-consulting.com +.. _`Zephyr Associates, Inc.`: http://www.styleadvisor.com + +:abstract: + + .. include:: zip_iterator_abstract.rst + +.. contents:: Table of Contents + +``zip_iterator`` synopsis +............................... + +.. include:: zip_iterator_ref.rst +.. include:: make_zip_iterator.rst +.. include:: zip_iterator_eg.rst diff --git a/doc/zip_iterator_abstract.rst b/doc/zip_iterator_abstract.rst new file mode 100755 index 0000000..0d1cf11 --- /dev/null +++ b/doc/zip_iterator_abstract.rst @@ -0,0 +1,6 @@ +The zip iterator provides the ability to parallel-iterate +over several controlled sequences simultaneously. A zip +iterator is constructed from a tuple of iterators. Moving +the zip iterator moves all the iterators in parallel. +Dereferencing the zip iterator returns a tuple that contains +the results of dereferencing the individual iterators. diff --git a/doc/zip_iterator_eg.rst b/doc/zip_iterator_eg.rst new file mode 100755 index 0000000..77e23ab --- /dev/null +++ b/doc/zip_iterator_eg.rst @@ -0,0 +1,117 @@ +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::const_iterator beg1 = vect_of_doubles.begin(); + std::vector::const_iterator end1 = vect_of_doubles.end(); + std::vector::const_iterator beg2 = vect_of_ints.begin(); + std::vector::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&, void> + { + void operator()(const boost::tuple& 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::const_iterator, + std::vector::const_iterator + > the_iterator_tuple; + + typedef boost::zip_iterator< + the_iterator_tuple + > the_zip_iterator; + + typedef boost::transform_iterator< + tuple_multiplies, + 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() + ); + + the_transform_iterator it_end( + the_zip_iterator( + the_iterator_tuple( + vect_1.end(), + vect_2.end() + ) + ), + tuple_multiplies() + ); + + +The source code for these examples can be found `here`__. + +__ ../example/zip_iterator_examples.cpp diff --git a/doc/zip_iterator_ref.rst b/doc/zip_iterator_ref.rst new file mode 100755 index 0000000..340fdc8 --- /dev/null +++ b/doc/zip_iterator_ref.rst @@ -0,0 +1,152 @@ + +:: + + template + class zip_iterator + { + + public: + typedef /* see below */ reference; + typedef reference value_type; + typedef value_type* pointer; + typedef /* see below */ difference_type; + typedef /* see below */ iterator_category; + + zip_iterator(); + zip_iterator(IteratorTuple iterator_tuple); + + template + zip_iterator( + const zip_iterator& other + , typename enable_if_convertible< + OtherIteratorTuple + , IteratorTuple>::type* = 0 // exposition only + ); + + const IteratorTuple& get_iterator_tuple() const; + + private: + IteratorTuple m_iterator_tuple; // exposition only + }; + + template + zip_iterator + make_zip_iterator(IteratorTuple t); + + +The ``reference`` member of ``zip_iterator`` is the type of the tuple +made of the reference types of the iterator types in the ``IteratorTuple`` +argument. + +The ``difference_type`` member of ``zip_iterator`` is the ``difference_type`` +of the first of the iterator types in the ``IteratorTuple`` argument. + +The ``iterator_category`` member of ``zip_iterator`` is convertible to the +minimum of the traversal categories of the iterator types in the ``IteratorTuple`` +argument. For example, if the ``zip_iterator`` holds only vector +iterators, then ``iterator_category`` is convertible to +``boost::random_access_traversal_tag``. If you add a list iterator, then +``iterator_category`` will be convertible to ``boost::bidirectional_traversal_tag``, +but no longer to ``boost::random_access_traversal_tag``. + + +``zip_iterator`` requirements +................................... + +All iterator types in the argument ``IteratorTuple`` shall model Readable Iterator. + + +``zip_iterator`` models +............................. + +The resulting ``zip_iterator`` models Readable Iterator. + +The fact that the ``zip_iterator`` models only Readable Iterator does not +prevent you from modifying the values that the individual iterators point +to. The tuple returned by the ``zip_iterator``'s ``operator*`` is a tuple +constructed from the reference types of the individual iterators, not +their value types. For example, if ``zip_it`` is a ``zip_iterator`` whose +first member iterator is an ``std::vector::iterator``, then the +following line will modify the value which the first member iterator of +``zip_it`` currently points to: + +:: + + zip_it->get<0>() = 42.0; + + +Consider the set of standard traversal concepts obtained by taking +the most refined standard traversal concept modeled by each individual +iterator type in the ``IteratorTuple`` argument.The ``zip_iterator`` +models the least refined standard traversal concept in this set. + +``zip_iterator`` is interoperable with +``zip_iterator`` if and only if ``IteratorTuple1`` +is interoperable with ``IteratorTuple2``. + + + +``zip_iterator`` operations +................................. + +In addition to the operations required by the concepts modeled by +``zip_iterator``, ``zip_iterator`` provides the following +operations. + + +``zip_iterator();`` + +:Returns: An instance of ``zip_iterator`` with ``m_iterator_tuple`` + default constructed. + + +``zip_iterator(IteratorTuple iterator_tuple);`` + +:Returns: An instance of ``zip_iterator`` with ``m_iterator_tuple`` + initialized to ``iterator_tuple``. + + +:: + + template + zip_iterator( + const zip_iterator& other + , typename enable_if_convertible< + OtherIteratorTuple + , IteratorTuple>::type* = 0 // exposition only + ); + +:Returns: An instance of ``zip_iterator`` that is a copy of ``other``. +:Requires: ``OtherIteratorTuple`` is implicitly convertible to ``IteratorTuple``. + + +``const IteratorTuple& get_iterator_tuple() const;`` + +:Returns: ``m_iterator_tuple`` + + +``reference operator*() const;`` + +:Returns: A tuple consisting of the results of dereferencing all iterators in + ``m_iterator_tuple``. + + +``zip_iterator& operator++();`` + +:Effects: Increments each iterator in ``m_iterator_tuple``. +:Returns: ``*this`` + + +``zip_iterator& operator--();`` + +:Effects: Decrements each iterator in ``m_iterator_tuple``. +:Returns: ``*this`` + +:: + + template + zip_iterator + make_zip_iterator(IteratorTuple t); + +:Returns: An instance of ``zip_iterator`` with ``m_iterator_tuple`` + initialized to ``t``.