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