1 /*
2 Copyright (c) 2014, Randolph Voorhies, Shane Grant
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of cereal nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES AND SHANE GRANT BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <cereal/cereal.hpp>
29 #include <cereal/archives/binary.hpp>
30 #include <cereal/archives/json.hpp>
31
32 #include <cereal/types/string.hpp>
33 #include <cereal/types/utility.hpp>
34 #include <cereal/types/memory.hpp>
35 #include <cereal/types/complex.hpp>
36 #include <cereal/types/base_class.hpp>
37 #include <cereal/types/array.hpp>
38 #include <cereal/types/vector.hpp>
39 #include <cereal/types/map.hpp>
40
41 #include <sstream>
42 #include <fstream>
43 #include <cassert>
44 #include <complex>
45 #include <iostream>
46 #include <iomanip>
47 #include <string>
48
49 // ###################################
50 struct Test1
51 {
52 int a;
53
54 private:
55 friend class cereal::access;
56 template<class Archive>
serializeTest157 void serialize(Archive & ar)
58 {
59 ar(CEREAL_NVP(a));
60 }
61 };
62
63 // ###################################
64 class Test2
65 {
66 public:
Test2()67 Test2() {}
Test2(int x)68 Test2( int x ) : a( x ) {}
69 int a;
70
71 private:
72 friend class cereal::access;
73
74 template<class Archive>
save(Archive & ar) const75 void save(Archive & ar) const
76 {
77 ar(a);
78 }
79
80 template<class Archive>
load(Archive & ar)81 void load(Archive & ar)
82 {
83 ar(a);
84 }
85 };
86
87 // ###################################
88 struct Test3
89 {
90 int a;
91 };
92
93 template<class Archive>
serialize(Archive & ar,Test3 & t)94 void serialize(Archive & ar, Test3 & t)
95 {
96 ar(CEREAL_NVP(t.a));
97 }
98
99 namespace test4
100 {
101 // ###################################
102 struct Test4
103 {
104 int a;
105 };
106
107 template<class Archive>
save(Archive & ar,Test4 const & t)108 void save(Archive & ar, Test4 const & t)
109 {
110 ar(CEREAL_NVP(t.a));
111 }
112
113 template<class Archive>
load(Archive & ar,Test4 & t)114 void load(Archive & ar, Test4 & t)
115 {
116 ar(CEREAL_NVP(t.a));
117 }
118 }
119
120 class Private
121 {
122 public:
Private()123 Private() : a('z') {}
124
125 private:
126 char a;
127
128 friend class cereal::access;
129
130 template<class Archive>
serialize(Archive & ar)131 void serialize(Archive & ar)
132 {
133 ar(a);
134 }
135 };
136
137 struct Everything
138 {
139 int x;
140 int y;
141 Test1 t1;
142 Test2 t2;
143 Test3 t3;
144 test4::Test4 t4;
145 std::string s;
146
147 template<class Archive>
serializeEverything148 void serialize(Archive & ar)
149 {
150 ar(CEREAL_NVP(x));
151 ar(CEREAL_NVP(y));
152 ar(CEREAL_NVP(t1));
153 ar(CEREAL_NVP(t2));
154 ar(CEREAL_NVP(t3));
155 ar(CEREAL_NVP(t4));
156 ar(CEREAL_NVP(s));
157 }
158
operator ==Everything159 bool operator==(Everything const & o)
160 {
161 return
162 x == o.x &&
163 y == o.y &&
164 t1.a == o.t1.a &&
165 t2.a == o.t2.a &&
166 t3.a == o.t3.a &&
167 t4.a == o.t4.a &&
168 s == o.s;
169 }
170 };
171
172
173 struct SubFixture
174 {
SubFixtureSubFixture175 SubFixture() : a( 3 ),
176 b( 9999 ),
177 c( 100.1f ),
178 d( 2000.9 ),
179 s( "hello, world!" )
180 {}
181
182 int a;
183 uint64_t b;
184 float c;
185 double d;
186 std::string s;
187
188 template<class Archive>
serializeSubFixture189 void serialize(Archive & ar)
190 {
191 ar( CEREAL_NVP(a),
192 b,
193 c,
194 CEREAL_NVP(d),
195 CEREAL_NVP(s) );
196 }
changeSubFixture197 void change()
198 {
199 a = 4;
200 b = 4;
201 c = 4;
202 d = 4;
203 s = "4";
204 }
205 };
206
207 struct Fixture
208 {
209 SubFixture f1, f2, f3;
210 int array[4];
211
FixtureFixture212 Fixture()
213 {
214 array[0] = 1;
215 array[1] = 2;
216 array[2] = 3;
217 array[3] = 4;
218 }
219
220 template<class Archive>
saveFixture221 void save(Archive & ar) const
222 {
223 ar( f1,
224 CEREAL_NVP(f2),
225 f3 );
226 ar.saveBinaryValue( array, sizeof(int)*4, "cool array man" );
227 }
228
229 template<class Archive>
loadFixture230 void load(Archive & ar)
231 {
232 ar( f1,
233 CEREAL_NVP(f2),
234 f3 );
235 ar.loadBinaryValue( array, sizeof(int)*4 );
236 }
237
changeFixture238 void change()
239 {
240 f1.change();
241 f2.change();
242 f3.change();
243 }
244 };
245
246 struct AAA
247 {
AAAAAA248 AAA() : one( 1 ), two( 2 ), three( { {1, 2, 3}, { 4, 5, 6 }, {} } ) {}
249 int one, two;
250
251 std::vector<std::vector<int>> three;
252
253 template<class Archive>
serializeAAA254 void serialize(Archive & ar)
255 {
256 ar( CEREAL_NVP(one), CEREAL_NVP(two) );
257 //ar( CEREAL_NVP(three) );
258 }
259 };
260
261 class Stuff
262 {
263 public:
Stuff()264 Stuff() {}
265
fillData()266 void fillData()
267 {
268 std::vector<std::complex<float>> t1{ {0, -1.0f},
269 { 0, -2.9932f },
270 { 0, -3.5f } };
271 std::vector<std::complex<float>> t2{ {1.0f, 0},
272 { 2.2f, 0 },
273 { 3.3f, 0 } };
274 data["imaginary"] = t1;
275 data["real"] = t2;
276 }
277
278 private:
279 std::map<std::string, std::vector<std::complex<float>>> data;
280
281 friend class cereal::access;
282
283 template <class Archive>
serialize(Archive & ar)284 void serialize( Archive & ar )
285 {
286 ar( CEREAL_NVP(data) );
287 }
288 };
289
290 struct OOJson
291 {
292 OOJson() = default;
OOJsonOOJson293 OOJson( int aa, int bb, bool cc, double dd ) :
294 a( aa ), b( bb ), c{ cc, dd }
295 {
296 d[0] = 0; d[1] = 1; d[2] = 2;
297 }
298
299 int a;
300 int b;
301 std::pair<bool, double> c;
302 float d[3];
303
304 template <class Archive>
serializeOOJson305 void serialize( Archive & ar )
306 {
307 ar( CEREAL_NVP(c) );
308 ar( CEREAL_NVP(a) );
309 ar( b );
310 ar( CEREAL_NVP(d) );
311 }
312 };
313
314 // ######################################################################
main()315 int main()
316 {
317 std::cout << std::boolalpha << std::endl;
318
319 {
320 std::ofstream os("file.json");
321 cereal::JSONOutputArchive oar( os );
322
323 //auto f = std::make_shared<Fixture>();
324 //auto f2 = f;
325 //oar( f );
326 //oar( f2 );
327 Stuff s; s.fillData();
328 oar( cereal::make_nvp("best data ever", s) );
329 }
330
331 {
332 std::ifstream is("file.json");
333 std::string str((std::istreambuf_iterator<char>(is)), std::istreambuf_iterator<char>());
334 std::cout << "---------------------" << std::endl << str << std::endl << "---------------------" << std::endl;
335 }
336
337 // playground
338 {
339 cereal::JSONOutputArchive archive( std::cout );
340 bool arr[] = {true, false};
341 std::vector<int> vec = {1, 2, 3, 4, 5};
342 archive( CEREAL_NVP(vec),
343 arr );
344 auto f = std::make_shared<Fixture>();
345 auto f2 = f;
346 archive( f );
347 archive( f2 );
348 }
349
350 // test out of order
351 std::stringstream oos;
352 {
353 cereal::JSONOutputArchive ar(oos);
354 cereal::JSONOutputArchive ar2(std::cout,
355 cereal::JSONOutputArchive::Options(2, cereal::JSONOutputArchive::Options::IndentChar::space, 2) );
356
357 ar( cereal::make_nvp( "1", 1 ),
358 cereal::make_nvp( "2", 2 ),
359 3,
360 0, // unused
361 cereal::make_nvp( "4", 4 ),
362 cereal::make_nvp( "5", 5 ) );
363
364 int x = 33;
365 ar.saveBinaryValue( &x, sizeof(int), "bla" );
366
367 ar2( cereal::make_nvp( "1", 1 ),
368 cereal::make_nvp( "2", 2 ),
369 3,
370 0, // unused
371 cereal::make_nvp( "4", 4 ),
372 cereal::make_nvp( "5", 5 ) );
373 ar2.saveBinaryValue( &x, sizeof(int), "bla" );
374
375 OOJson oo( 1, 2, true, 4.2 );
376 ar( CEREAL_NVP(oo) );
377 ar2( CEREAL_NVP(oo) );
378
379 // boost stuff
380 ar & cereal::make_nvp("usingop&", oo ) & 6;
381 ar << 5 << 4 << 3;
382
383 ar2 & cereal::make_nvp("usingop&", oo ) & 6;
384 ar2 << 5 << 4 << 3;
385
386 long double ld = std::numeric_limits<long double>::max();
387 long long ll = std::numeric_limits<long long>::max();
388 unsigned long long ull = std::numeric_limits<unsigned long long>::max();
389
390 ar( CEREAL_NVP(ld),
391 CEREAL_NVP(ll),
392 CEREAL_NVP(ull) );
393
394 ar2( CEREAL_NVP(ld),
395 CEREAL_NVP(ll),
396 CEREAL_NVP(ull) );
397 }
398
399 {
400 cereal::JSONInputArchive ar(oos);
401 int i1, i2, i3, i4, i5, x;
402
403 ar( i1 );
404 ar( cereal::make_nvp( "2", i2 ), i3 );
405
406 ar( cereal::make_nvp( "4", i4 ),
407 i5 );
408
409 ar.loadBinaryValue( &x, sizeof(int) );
410
411 OOJson ii;
412 ar( cereal::make_nvp("oo", ii) );
413 ar( cereal::make_nvp( "2", i2 ) );
414
415 std::cout << i1 << " " << i2 << " " << i3 << " " << i4 << " " << i5 << std::endl;
416 std::cout << x << std::endl;
417 std::cout << ii.a << " " << ii.b << " " << ii.c.first << " " << ii.c.second << " ";
418 for( auto z : ii.d )
419 std::cout << z << " ";
420 std::cout << std::endl;
421
422 OOJson oo;
423 ar >> cereal::make_nvp("usingop&", oo );
424 std::cout << oo.a << " " << oo.b << " " << oo.c.first << " " << oo.c.second << " ";
425 for( auto z : oo.d )
426 std::cout << z << " ";
427
428 int aa, a, b, c;
429 ar & aa & a & b & c;
430 std::cout << aa << " " << a << " " << b << " " << c << std::endl;
431
432 long double ld;
433 long long ll;
434 unsigned long long ull;
435
436 ar( CEREAL_NVP(ld),
437 CEREAL_NVP(ll),
438 CEREAL_NVP(ull) );
439
440 std::cout << (ld == std::numeric_limits<long double>::max()) << std::endl;
441 std::cout << (ll == std::numeric_limits<long long>::max()) << std::endl;
442 std::cout << (ull == std::numeric_limits<unsigned long long>::max()) << std::endl;
443 }
444
445 return 0;
446 }
447