Based on this question I though I would pull together an iterator that iterated over a container of containers.
template<typename C>
class IteratorForContainerOfContainer
{
public:
using Container = C;
using ContainerContainer = typename Container::value_type;
using Contained = typename ContainerContainer::value_type;
using Level1Iter = typename Container::iterator;
using Level2Iter = typename ContainerContainer::iterator;
using iterator_category = std::forward_iterator_tag;
using value_type = Contained;
using difference_type = std::size_t;
using pointer = value_type*;
using reference = value_type&;
IteratorForContainerOfContainer(C& c)
: outerLoop(std::begin(c))
, outerEnd(std::end(c))
, innerLoop(std::begin(*outerLoop))
, innerEnd(std::end(*outerLoop))
{
nextValidPos();
}
IteratorForContainerOfContainer()
: outerLoop()
, outerEnd()
, innerLoop()
, innerEnd()
{}
IteratorForContainerOfContainer& operator++()
{
++innerLoop;
nextValidPos();
return *this;
}
value_type& operator*()
{
return *innerLoop;
}
bool operator!=(IteratorForContainerOfContainer const& rhs) const
{
return outerLoop != rhs.outerLoop || innerLoop != rhs.innerLoop;
}
private:
void nextValidPos()
{
while ((innerLoop == innerEnd) && (outerLoop != outerEnd)) {
++outerLoop;
if (outerLoop != outerEnd) {
innerLoop = std::begin(*outerLoop);
innerEnd = std::end(*outerLoop);
}
}
if (outerLoop == outerEnd) {
outerLoop = Level1Iter();
outerEnd = Level1Iter();
innerLoop = Level2Iter();
innerEnd = Level2Iter();
}
}
Level1Iter outerLoop;
Level1Iter outerEnd;
Level2Iter innerLoop;
Level2Iter innerEnd;
};
So an example of simple usage would be:
int main()
{
using CC = std::vector<std::vector<int>>;
using It = IteratorForContainerOfContainer<CC>;
CC data = {{1,2,3},{4,5,6},{7,8,9}};
for(It loop(data);loop != It(); ++loop) {
std::cout << *loop << " ";
}
std::cout << "\n";
}
nested_range
would be a great name for the iterator pair. Is there a reason you didn’t write range first? People could use range for loop then. I guess you had different usage in mind. \$\endgroup\$