#include #include #include #include #include #include #include #include #include template class Mtx_Wrap { size_t Ndims; ///< Total number of dimensions size_t *dimbuf; ///< Buffer of dimensions, from the fastest to the slowest one size_t Nel; ///< Total number of elements into the data buffer T *data; ///< Buffer of data bool data_owned; ///< TRUE only if the object owns its data template void set_dimensions(InIt dimB,InIt dimE) { using namespace boost::lambda; Ndims = static_cast(std::distance(dimB,dimE)); delete []dimbuf; dimbuf = NULL; if (Ndims>0) { dimbuf = new size_t[Ndims]; std::transform(dimB,dimE,dimbuf,ll_static_cast(_1)); Nel = std::accumulate(dimbuf,dimbuf+Ndims,1,std::multiplies()); } else { Nel = 0; } } template void copy_data(InIt dB,InIt dE) { using namespace boost::lambda; if (Nel != static_cast(std::distance(dB,dE))) { throw std::runtime_error("Wrong number of data"); } delete []data; data = NULL; if (Nel>0) { data_owned = true; data = new T[Nel]; std::transform(dB,dE,data,ll_static_cast(_1)); } } // Split serialization into save/load template void save(Archive & ar,const unsigned int version) const { #ifndef BOOST_SERIALIZATION_WORK_AROUND ar << Ndims; ar.save_binary(dimbuf,Ndims*sizeof(size_t)); ar << Nel; ar.save_binary(data,Nel*sizeof(size_t)); #else ar << Ndims; size_t k; for (k=0;k void load(Archive & ar, const unsigned int version) { if (data_owned) { delete []data; data = NULL; } delete []dimbuf; dimbuf = NULL; #ifndef BOOST_SERIALIZATION_WORK_AROUND ar >> Ndims; dimbuf = new size_t[Ndims]; ar.load_binary(dimbuf,Ndims*sizeof(size_t)); ar >> Nel; data_owned = true; data = new T[Nel]; ar.load_binary(data,Nel*sizeof(size_t)); #else ar >> Ndims; dimbuf = new size_t[Ndims]; size_t k; for (k=0;k> dimbuf[k++]); ar >> Nel; data_owned = true; data = new T[Nel]; for (k=0;k> data[k++]); #endif } BOOST_SERIALIZATION_SPLIT_MEMBER() template friend class Mtx_Wrap_RW; friend class boost::serialization::access; public: Mtx_Wrap() : Ndims(0),dimbuf(NULL),Nel(0),data(NULL),data_owned(false) {} Mtx_Wrap(const Mtx_Wrap &rhs) : Ndims(0),dimbuf(NULL),Nel(0), data(NULL),data_owned(false) { set_dimensions(rhs.dimbuf,rhs.dimbuf+rhs.Ndims); copy_data(rhs.data,rhs.data + rhs.Nel); } ~Mtx_Wrap() { if (data_owned) { delete []data; data = NULL; } delete []dimbuf; dimbuf = NULL; } Mtx_Wrap & operator =(const Mtx_Wrap &rhs) { if (&rhs == this) return *this; set_dimensions(rhs.dimbuf,rhs.dimbuf+rhs.Ndims); copy_data(rhs.data,rhs.data + Nel); return *this; } template void set_data(InItDim dimB,InItDim dimE,InItData dB,InItData dE) { set_dimensions(dimB,dimE); if (data_owned) { delete []data; data = NULL; } copy_data(dB,dE); } }; using namespace std; using namespace boost; using namespace archive; int main(int argc, char* argv[]) { Mtx_Wrap mtx,mtx2; float data[] = {1.1,2.2,3.3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}; size_t dims[] = {1,21}; /* float data[] = {1.1,2.2,3.3}; size_t dims[] = {1,3};*/ size_t Ndims = sizeof(dims)/sizeof(*dims); size_t Ndata = sizeof(data)/sizeof(*data); mtx.set_data(dims,dims+Ndims,data,data+Ndata); ofstream ofs("test.arch",ios::out | ios::binary); { binary_oarchive boa(ofs); boa << mtx; } ofs.close(); ifstream ifs("test.arch",ios::in | ios::binary); { binary_iarchive bia(ifs); bia >> mtx2; } ifs.close(); return 0; }