Is there any existing iterator implementation (perhaps in boost) which implement some sort of flattening iterator?
For example:
unordered_set<vector<int> > s;
s.insert(vector<int>());
s.insert({1,2,3,4,5});
s.insert({6,7,8});
s.insert({9,10,11,12});
flattening_iterator<unordered_set<vector<int> >::iterator> it( ... ), end( ... );
for(; it != end; ++it)
{
cout << *it << endl;
}
//would print the numbers 1 through 12
I don’t know of any implementation in a major library, but it looked like an interesting problem so I wrote a basic implementation. I’ve only tested it with the test case I present here, so I don’t recommend using it without further testing.
The problem is a bit trickier than it looks because some of the “inner” containers may be empty and you have to skip over them. This means that advancing the
flattening_iteratorby one position may actually advance the iterator into the “outer” container by more than one position. Because of this, theflattening_iteratorneeds to know where the end of the outer range is so that it knows when it needs to stop.This implementation is a forward iterator. A bidirectional iterator would also need to keep track of the beginning of the outer range. The
flattenfunction templates are used to make constructingflattening_iterators a bit easier.The following is a minimal test stub:
Like I said at the beginning, I haven’t tested this thoroughly. Let me know if you find any bugs and I’ll be happy to correct them.