Search code examples
c++boost-hana

Coordinate generation at compile time


Given a hana::tuple specifying the shape of a N-dimensional box, (e.g. (2,3,2) in 3D) at compile time, I would like to generate a tuple of tuples with all coordinate combinations at compile time. (0,0,0) (0,0,1) (0,1,0) (0,1,1) (0,2,0) (0,2,1) (1,0,0) (1,0,1) (1,1,0) (1,1,1) (1,2,0) (1,2,1)

The question is related to another one I posted a few days ago (link) but reformulated for hana. I seem to have trouble coming up with an algorithm which respects the immutability of the hana::tuple object. I fail to recognize what combination of hana algorithms will allow me to generate a recursive call and also collect the returned tuples at the same time.


Solution

  • Per your comment, you were only trying to perform loop unrolling. You may want to measure both ways, but usually the compiler will do an immensely better job than you at optimizing these things when the array bounds are known. You may actually significantly slow down or bloat your program by forcing loop unrolling.

    That being said, if that's what you want to do, here's how you can do it:

    #include <boost/hana.hpp>
    namespace hana = boost::hana;
    
    template <int ...> struct your_template { };
    
    int main() {
        auto xs = hana::to_tuple(hana::range_c<int, 0, 10>); // [0, ..., 9]
        auto ys = hana::to_tuple(hana::range_c<int, 0, 10>); // [0, ..., 9]
        auto zs = hana::to_tuple(hana::range_c<int, 0, 10>); // [0, ..., 9]
    
        auto coords = hana::cartesian_product(hana::make_tuple(xs, ys, zs));
        hana::for_each(coords, hana::fuse([](auto x, auto y, auto z) {
            your_template<decltype(x)::value, decltype(y)::value, decltype(z)::value> foo;
            (void)foo;
        }));
    }
    

    Be aware, however, that generating the cartesian product is pretty nasty at compile-time, as you're generating a huge tuple. The above, for example, takes about 10s to compile on my box.