Consider the following simplified example and desired output:
class A
{
class combined_iterator
{
????
}
typedef ??? t_combined_it;
zip_iterator works if you want to iterate two iterators in parallel. If you need to iterate over containers in sequence you can probably implement one using iterator_adaptor.
I already implemented something similar for a different question. The implementation is here. The basic idea is the one you approached: storing the two iterator ranges, when you are asked to perform an operation check whether you have completed the iteration in the first range, and use either range.
This is not thread safe by any means, and I have never used that implementation in real code, so there might be issues and bugs and...
boost::join is what you're looking for. You can also study the implementation, especially how to derive the lowest common denominator for container traversal, reference and return value types. To quote:
The intention of the join function is to join two ranges into one longer range.
The resultant range will have the lowest common traversal of the two ranges supplied as parameters.
Note that the joined range incurs a performance cost due to the need to check if the end of a range > has been reached internally during traversal.
Aasmund is right. Your approach, though simple should work. But there is much room for optimizing.
Collection Objects are often large, and as so take some time to be iterated through. Especially list's and arrays.
You should consider multithreading so that each collection can be iterated in parallel.
Additionally. You should take the advice of the post you linked to use and use
Boost.MultiIndex
I think your "naive" approach should work, with the following change: instead of comparing the iterator to the end()
of every container, keep a pointer to the current container and compare the iterator only the the current container's end()
. When the end has been reached, move on to the next container. That way, you'll never compare the iterator to another container than the one it points to. This will also easily generalize to an arbitrarily-sized collection of collections.
The answers other people gave only work for joining two ranges, but not an arbitrary number of range.
PStade Oven has a concatenated adaptor for joining any number of ranges; it also has a jointed
adaptor for joining 2 ranges, specifically.
You can of course turn the ranges into iterators with begin()
and end()
if necessary; just make sure the ranges outlast the iterators.