I want to iterate over every point within a geometry::model::box<point>. I want to be able to do that with iterators so that I can also use all (or most of) the standard algorithms like for_each or all_of or etc.
Initially my code used several loops, one for each axis, like so for a 2d point:
for (int x = box.min_corner().template get<0>(); x <= box.max_corner().template get<0>(); ++x) {
for (int y = box.min_corner().template get<1>(); y <= box.max_corner().template get<1>(); ++y) {
callback(point(x,y))
}
}
There are several places where this occurs. Some loops have the x axis first, others the y axis first -- and this has performance issues when translating the point to a container. Some loops were erroneously considering right-open intervals with less-than instead of less-than-or-equal-to comparisons. So I've had to fix bounding bugs and performance issues in multiple places that are caused by these manual loops.
I've gone and unified a lot of that to use templated functions that basically duplicate some of the functionality in the standard. But that's not tractable and still doesn't use iterators so most of <algorithm> is still off-limits:
namespace mynamespace {
template <class box, enable_if vomit, blah blah>
void for_each(const box& b, const std::function<void(const typename box::point_type&)> callback) {
// the manual loops here, not repeated for brevity
}
}
Then I've replaced most of those manual loops with calls to:
mynamespace::for_each(box, [](const point& p){
// do some work here
});
So I want to instead do:
for (const auto& point : box) {
callback(point);
}
Satisfying that would make a lot of places simpler and easier to read. I think it should also help to enable use of a lot of the stuff in the standard <algorithm>
I understand that it might be difficult for, eg, a box containing a point with floating point types. But that's fine ... I'm only looping over integral points anyway.
I'd also prefer to have the ability to control the axis order ... eg do I want x or y on the inner/outer loop? Do I want to only iterate over the y axis?
I'm using C++14 and boost 1.70 at the moment. There's some friction against upgrading. But if this problem is solved in a future version -- like with C++20 ranges -- then that would be a strong point for me to convince my team to upgrade.
I could go and write up some iterators myself of course. But before I do that I wondered if someone else has already solved this problem and I just haven't found the solution. Thoughts?