I am trying to serialize a multi_array object but keep the dimensions variable (I only want to support 1, 2 and 3 dimensions). So I attempted to create a Variant of the three multi_array's and the corresponding serialize methods as shown below, but I am getting a run-time error when for the 1-Dimensional case. Here is the minimal code example I came up with that shows the problem. I am using the boost SVN trunk as of this posting (April 26, 2011).

Maybe I am implementing the load() method incorrectly for the multi_array. Should there be a special case for when Dim == 1?

Running the program, I get the following error:
> ./test
test: /home/goetz/local/src/boost-trunk/boost/multi_array/multi_array_ref.hpp:487: boost::multi_array_ref<T, NumDims>& boost::multi_array_ref<T, NumDims>::operator=(const ConstMultiArray&) [with ConstMultiArray = boost::multi_array<float, 1ul>, T = float, long unsigned int NumDims = 1ul, boost::multi_array_ref<T, NumDims> = boost::multi_array_ref<float, 1ul>]: Assertion `std::equal(other.shape(),other.shape()+this->num_dimensions(), this->shape())' failed.
Aborted (core dumped)

/// Begin File: multiarray-variant-serialize.cpp
/**
 * gcc compile command:
 *     g++ multiarray-variant-serialize.cpp -otest -lboost_serialization
 *
 * to run:
 *     ./test
 **/
#include <fstream>
#include <string>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/array.hpp>
#include <boost/serialization/variant.hpp>
#include <boost/multi_array.hpp>


typedef boost::variant<
    boost::multi_array<float,1>,
    boost::multi_array<float,2>,
    boost::multi_array<float,3>
    > multi_array_variant;


namespace boost {
namespace serialization {

    template<class Archive, typename T, size_t Dim>
    void save(
        Archive& ar,
        const boost::multi_array<T,Dim>& ma,
        const unsigned int version)
    {
        ar << boost::serialization::make_array(ma.shape(), Dim);
        ar << boost::serialization::make_array(ma.data(), ma.num_elements());
    }

    template<class Archive, typename T, size_t Dim>
    void load(
        Archive& ar,
        boost::multi_array<T,Dim>& ma,
        const unsigned int version)
    {
        typedef typename boost::multi_array<T,Dim>::index index_t;
        boost::array<index_t,Dim> shape;

        ar >> boost::serialization::make_array(shape.data(), Dim);
        ma.resize(shape);

        ar >> boost::serialization::make_array(ma.data(), ma.num_elements());
    }

    template<class Archive, typename T, size_t Dim>
    void serialize(
        Archive & ar,
        boost::multi_array<T,Dim>& ma,
        const unsigned int version)
    {
        split_free(ar, ma, version);
    }
} /// namespace boost::serialization
} /// namespace boost


int main()
{
    boost::multi_array<float,1> a1(boost::extents[5]);
    /// replacing the above line with either of the following two
    /// works as anticipated. Only the 1-Dimension breaks
    /// breaks at run-time.
    //boost::multi_array<float,2> a1(boost::extents[5][5]);
    //boost::multi_array<float,3> a1(boost::extents[5][5][5]);

    multi_array_variant a3 = a1;
    multi_array_variant a4;

    std::string filename = "archive.tmp";
    {
        std::ofstream ofs(filename.c_str());
        boost::archive::text_oarchive oa(ofs);
        oa << a3;
    }
    {
        std::ifstream ifs(filename.c_str());
        boost::archive::text_iarchive ia(ifs);
        ia >> a4;
    }

    return 0;
}
/// EOF

--
Johann T. Goetz