zip iterator over containers of unequal sizes

The zip iterator documentation says: "The zip iterator provides the ability to parallel-iterate over several controlled sequences simultaneously. ... Moving the zip iterator moves all the iterators in parallel." What is not specified is what happens when the several different sequences are of unequal size. At the moment, everything just blows up. python zip, if I remember correctly, just stops at the end of the shortest sequence in the tuple. (python map works differently). This seems a sensible thing to do. This requires just a modification to zip_iterator::equal. I guess distance_to might need to be changed as well. Leo Goodstadt The diff is attached at the end. Here is the example modified: #include <boost/iterator/zip_iterator.hpp> #include <boost/tuple/tuple.hpp> #include <iostream> #include <vector> int main() { typedef std::vector<int> IntSeq; // a = {1,2,3} IntSeq a; a.push_back(1); a.push_back(2); a.push_back(3); // b = {10,20,30,40} IntSeq b; b.push_back(10); b.push_back(20); b.push_back(30); b.push_back(40); // b = {100,200,300,400,500} IntSeq c; c.push_back(100); c.push_back(200); c.push_back(300); c.push_back(400); c.push_back(500); typedef boost::zip_iterator< boost::tuples::tuple< IntSeq::const_iterator, IntSeq::const_iterator, IntSeq::const_iterator> > ZIt; ZIt cur(boost::make_tuple(a.begin(), b.begin(), c.begin())); ZIt end(boost::make_tuple(a.end(), b.end(), c.end())); for ( ; cur != end; ++cur ) { std::cout << "{ " << boost::tuples::get<0>(*cur) << ", " << boost::tuples::get<1>(*cur) << ", " << boost::tuples::get<2>(*cur) << " }" << std::endl; } return 0; } diff old_boost/iterator/zip_iterator.hpp new_boost/iterator/zip_iterator.hpp 329a330,347
// Returns true if any tuples equal. NOTE: "==" for tuples currently (7/2003) // has problems under some compilers, so I just do my own. // No point in bringing in a bunch of #ifdefs here. This is // going to go away with the next tuple implementation anyway. // bool tuple_any_equal(tuples::null_type, tuples::null_type) { return false; }
template<typename Tuple1, typename Tuple2> bool tuple_any_equal( Tuple1 const& t1, Tuple2 const& t2 ) { return t1.get_head() == t2.get_head() || tuple_any_equal(t1.get_tail(), t2.get_tail()); }
537c555 < return detail::tuple_impl_specific::tuple_equal( ---
return detail::tuple_impl_specific::tuple_any_equal(

Leo Goodstadt <leo.goodstadt@human-anatomy.oxford.ac.uk> writes:
The zip iterator documentation says: "The zip iterator provides the ability to parallel-iterate over several controlled sequences simultaneously. ... Moving the zip iterator moves all the iterators in parallel."
What is not specified is what happens when the several different sequences are of unequal size. At the moment, everything just blows up.
python zip, if I remember correctly, just stops at the end of the shortest sequence in the tuple. (python map works differently). This seems a sensible thing to do.
Doesn't seem like such a great idea to me. It forces you to pay at each iteration of a loop when you could pay once to ensure that your ending zip iterator is formed from the correct position in each sequence. In my opinion the zip_iterator documentation should be improved (quite a lot) to make the requirements more explicit. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Doesn't seem like such a great idea to me. It forces you to pay at each iteration of a loop when you could pay once to ensure that your ending zip iterator is formed from the correct position in each sequence. In my opinion the zip_iterator documentation should be improved (quite a lot) to make the requirements more explicit. For iterators over a container, that is indeed true. In which case, surely it would be better to provide a constructor which calculates the minimum distance rather than relying on the user to remember to check beforehand.
Leo

"Llew Sion Goodstadt" <leo.goodstadt@human-anatomy.oxford.ac.uk> writes:
Doesn't seem like such a great idea to me. It forces you to pay at each iteration of a loop when you could pay once to ensure that your ending zip iterator is formed from the correct position in each sequence. In my opinion the zip_iterator documentation should be improved (quite a lot) to make the requirements more explicit.
For iterators over a container, that is indeed true. In which case, surely it would be better to provide a constructor which calculates the minimum distance rather than relying on the user to remember to check beforehand.
These are iterators, not sequences. It is not appropriate to build length calculations into the construction of a single iterator. The right place for this sort of functionality would be in a library of sequence views. -- Dave Abrahams Boost Consulting www.boost-consulting.com

The zip iterator documentation says: "The zip iterator provides the ability to parallel-iterate over several controlled sequences simultaneously. ... Moving the zip iterator moves all the iterators in parallel."
What is not specified is what happens when the several different sequences are of unequal size. At the moment, everything just blows up. This behavior is consistent with the STL's algorithms. std::equal, for example, only accepts a single iterator for the second container. The
Leo Goodstadt wrote: programmer must ensure that the second container has at least as many items in it from the position of the supplied iterator as exist between the iterator range supplied for the first container. The std::back_insert_iterator, std::front_insert_iterator, and std::insert_iterator adaptors exist so that the transformational STL algorithms can be utilized without having to initialize the receiving container with dummy items in advance.
python zip, if I remember correctly, just stops at the end of the shortest sequence in the tuple. (python map works differently). This seems a sensible thing to do.
Python iterators are different animals than STL iterators; Python's zip() probably just halts on a StopIteration exception raised by one or more of the iterators from the sequences passed into it. There is no exception raised when an STL iterator reaches the past-the-end point of the container it was generated by.
participants (4)
-
David Abrahams
-
Jason Kankiewicz
-
Leo Goodstadt
-
Llew Sion Goodstadt