Search code examples
c++iteratornested-loops

Transforming a C++ nested loop into a single one with an iterator


Let's say we have the following nested loop:

MyClass myobject;

for (const std::array<int,16>& arr : myobject)
{
    for (int i : arr)  {  /* do something with i */  }
}

where MyClass can iterate over arrays of 16 integers for instance.

Now, I would like to have a single loop that iterates over all integers of all arrays of myobject:

for (int i : MagicClass(myobject))  {  /* do something with i */  }

where MagicClass is the class I am trying to design. I understand that MagicClass should implement begin/end methods that return a specific iterator, ie. something like:

class MagicClass
{
public:
    MagicClass (MyClass obj) : obj_(obj) {}

    struct iterator 
    {
        // the hard part comes here...
    };

    iterator begin()  { return iterator (obj_.begin()); }
    iterator end  ()  { return iterator (obj_.end  ()); }

private:
    MyClass obj_;
};

Since I am struggling to get a decent implementation of MagicClass::iterator, I am wondering whether a generic solution already exists.

Is there any library that can transform a nested loop (a container iterating other containers) into a single loop through a single iterator ? Or at least, what should be the best practice to implement MagicClass::iterator ?


Solution

  • It's called std::views::join.

    #include <array>
    #include <iostream>
    #include <ranges>
    
    int main()
    {
        std::array<std::array<int, 3>,3> arr = {{
            {1,2,3},
            {4,5,6},
            {7,8,9},
        }};
    
        for (int x : arr | std::views::join)
            std::cout << x << '\n'; // 1 2 3 4 5 6 7 8 9
    }