c++boost-multi-array

Nesting boost::multi_array?


I have a template class which does some computation and returns multi_array, a bit oversimplified like this:

template <typename T>
class C
{
public:
    typedef boost::multi_array<T, 2> result_type;

    void do_something(T const& data, unsigned i, unsigned j); // add result to R[i][j]

    result_type R;
};

Instantiating the class with a simple type T=double works fine. Now, I want to instantiate with "T=boost::multi_array<double, 1>", but such that the result type is boost::multi_array<double, 3>.

The definition multi_array<multi_array<T, N>, M>> does clearly not result in multi_array<T, N+M>, it is just a N-dimensional multi_array with elements being M-dimensional multi_arrays ...

The idea to generate such a type is motivated by the Boost manual saying

MultiArray is recursively defined; the containers at each level of the container hierarchy model MultiArray as well. Actually, it turns out that the "elements" of the intermediate multi_array levels are of type subarray.

Can one use subarray to generate a multi_array type with an effective dimensionality N+M? Maybe somehow along the following lines:

typedef typename boost::multi_array<double, 3>::subarray<1>::type value_type;
boost::multi_array<value_type, 2> a;

I'm looking for a relatively clean solution (not a lengthy hack), if this is not possible with the multi_array interface I will better rethink the design of what I'm going to implement.


Solution

  • I think it makes no sense to instantiate multi_array with elements of type multi_array (although it might compile). For example, it would not lead to a contiguous memory layout since the elements manage memory themselves.

    To solve the problem that motivated my question, I came up with the following solution:

    template <typename T>
    class C
    {
        enum { extra_rank = get_rank<T>() };
    public:
        typedef boost::multi_array<T, 2 + extra_rank> result_type;
    }
    

    The class defines a multi_array with extra dimensions depending on the type of T. The helper function get_rank checks whether T is multi_array and returns its dimensionality, otherwise it returns 0.