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
?
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
}