Ticket #2002: main.cpp

File main.cpp, 4.0 KB (added by MIchele De Stefano <micdestefano@…>, 14 years ago)

Small test program for the bug

Line 
1#include <boost/lambda/lambda.hpp>
2#include <boost/lambda/casts.hpp>
3#include <boost/serialization/split_member.hpp>
4#include <boost/archive/binary_oarchive.hpp>
5#include <boost/archive/binary_iarchive.hpp>
6#include <algorithm>
7#include <stdexcept>
8#include <iterator>
9#include <fstream>
10
11template<typename T>
12class Mtx_Wrap {
13
14 size_t Ndims; ///< Total number of dimensions
15 size_t *dimbuf; ///< Buffer of dimensions, from the fastest to the slowest one
16
17 size_t Nel; ///< Total number of elements into the data buffer
18 T *data; ///< Buffer of data
19
20 bool data_owned; ///< TRUE only if the object owns its data
21
22 template<class InIt>
23 void set_dimensions(InIt dimB,InIt dimE) {
24
25 using namespace boost::lambda;
26
27 Ndims = static_cast<size_t>(std::distance(dimB,dimE));
28 delete []dimbuf; dimbuf = NULL;
29 if (Ndims>0) {
30 dimbuf = new size_t[Ndims];
31 std::transform(dimB,dimE,dimbuf,ll_static_cast<size_t>(_1));
32
33 Nel = std::accumulate(dimbuf,dimbuf+Ndims,1,std::multiplies<size_t>());
34 } else {
35 Nel = 0;
36 }
37 }
38
39
40 template<class InIt>
41 void copy_data(InIt dB,InIt dE) {
42
43 using namespace boost::lambda;
44
45 if (Nel != static_cast<size_t>(std::distance(dB,dE))) {
46 throw std::runtime_error("Wrong number of data");
47 }
48 delete []data; data = NULL;
49
50 if (Nel>0) {
51 data_owned = true;
52 data = new T[Nel];
53 std::transform(dB,dE,data,ll_static_cast<T>(_1));
54 }
55 }
56
57 // Split serialization into save/load
58 template<class Archive>
59 void save(Archive & ar,const unsigned int version) const {
60
61#ifndef BOOST_SERIALIZATION_WORK_AROUND
62 ar << Ndims;
63 ar.save_binary(dimbuf,Ndims*sizeof(size_t));
64 ar << Nel;
65 ar.save_binary(data,Nel*sizeof(size_t));
66#else
67 ar << Ndims;
68 size_t k;
69 for (k=0;k<Ndims;ar << dimbuf[k++]);
70 ar << Nel;
71 for (k=0;k<Nel;ar << data[k++]);
72#endif
73 }
74
75 template<class Archive>
76 void load(Archive & ar, const unsigned int version) {
77
78 if (data_owned) {
79 delete []data;
80 data = NULL;
81 }
82 delete []dimbuf;
83 dimbuf = NULL;
84
85#ifndef BOOST_SERIALIZATION_WORK_AROUND
86 ar >> Ndims;
87 dimbuf = new size_t[Ndims];
88 ar.load_binary(dimbuf,Ndims*sizeof(size_t));
89 ar >> Nel;
90 data_owned = true;
91 data = new T[Nel];
92 ar.load_binary(data,Nel*sizeof(size_t));
93#else
94 ar >> Ndims;
95 dimbuf = new size_t[Ndims];
96 size_t k;
97 for (k=0;k<Ndims;ar >> dimbuf[k++]);
98 ar >> Nel;
99 data_owned = true;
100 data = new T[Nel];
101 for (k=0;k<Nel;ar >> data[k++]);
102#endif
103 }
104
105 BOOST_SERIALIZATION_SPLIT_MEMBER()
106
107 template<typename Taux> friend class Mtx_Wrap_RW;
108 friend class boost::serialization::access;
109
110public:
111
112 Mtx_Wrap() : Ndims(0),dimbuf(NULL),Nel(0),data(NULL),data_owned(false) {}
113
114 Mtx_Wrap(const Mtx_Wrap &rhs) : Ndims(0),dimbuf(NULL),Nel(0),
115 data(NULL),data_owned(false) {
116
117 set_dimensions(rhs.dimbuf,rhs.dimbuf+rhs.Ndims);
118
119 copy_data(rhs.data,rhs.data + rhs.Nel);
120 }
121
122 ~Mtx_Wrap() {
123 if (data_owned) {
124 delete []data;
125 data = NULL;
126 }
127 delete []dimbuf;
128 dimbuf = NULL;
129 }
130
131
132 Mtx_Wrap & operator =(const Mtx_Wrap &rhs) {
133
134 if (&rhs == this) return *this;
135
136 set_dimensions(rhs.dimbuf,rhs.dimbuf+rhs.Ndims);
137
138 copy_data(rhs.data,rhs.data + Nel);
139
140 return *this;
141 }
142
143 template<class InItDim,class InItData>
144 void set_data(InItDim dimB,InItDim dimE,InItData dB,InItData dE) {
145
146 set_dimensions(dimB,dimE);
147
148 if (data_owned) {
149 delete []data; data = NULL;
150 }
151
152 copy_data(dB,dE);
153 }
154
155};
156
157using namespace std;
158using namespace boost;
159using namespace archive;
160
161int main(int argc, char* argv[]) {
162
163
164 Mtx_Wrap<float> mtx,mtx2;
165
166 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};
167 size_t dims[] = {1,21};
168
169/* float data[] = {1.1,2.2,3.3};
170 size_t dims[] = {1,3};*/
171
172 size_t Ndims = sizeof(dims)/sizeof(*dims);
173 size_t Ndata = sizeof(data)/sizeof(*data);
174
175 mtx.set_data(dims,dims+Ndims,data,data+Ndata);
176
177 ofstream ofs("test.arch",ios::out | ios::binary);
178 {
179 binary_oarchive boa(ofs);
180 boa << mtx;
181 }
182 ofs.close();
183
184 ifstream ifs("test.arch",ios::in | ios::binary);
185 {
186 binary_iarchive bia(ifs);
187 bia >> mtx2;
188 }
189 ifs.close();
190
191 return 0;
192}