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/portable_binary.hpp>
31 #include <cereal/archives/xml.hpp>
32
33 #include <cereal/types/string.hpp>
34 #include <cereal/types/utility.hpp>
35 #include <cereal/types/memory.hpp>
36 #include <cereal/types/complex.hpp>
37 #include <cereal/types/base_class.hpp>
38 #include <cereal/types/array.hpp>
39 #include <cereal/types/vector.hpp>
40 #include <cereal/types/map.hpp>
41 #include <cereal/types/utility.hpp>
42 #include <cereal/types/bitset.hpp>
43 #include <cereal/types/polymorphic.hpp>
44
45 //#include <cxxabi.h>
46 #include <sstream>
47 #include <fstream>
48 #include <cassert>
49 #include <complex>
50 #include <iostream>
51 #include <random>
52
53 class Base
54 {
55 private:
56 friend class cereal::access;
57 template <class Archive>
serialize(Archive & ar)58 void serialize( Archive & ar )
59 {
60 std::cout << "Base serialize" << std::endl;
61 ar( x );
62 }
63
64 virtual void foo() = 0;
65
66 public:
67 int x;
68 };
69
70 class Derived : public Base
71 {
72 public:
73 using Base::x;
Derived()74 Derived() : Base(), y() {}
Derived(int d,int b)75 Derived( int d, int b )
76 {
77 y = d;
78 x = b;
79 }
80
81 template <class Archive>
save(Archive & ar) const82 void save( Archive & ar ) const
83 {
84 ar( cereal::virtual_base_class<Base>(this) );
85 std::cout << "Derived save" << std::endl;
86 ar( y );
87 }
88
89 template <class Archive>
load(Archive & ar)90 void load( Archive & ar )
91 {
92 ar( cereal::virtual_base_class<Base>(this) );
93 std::cout << "Derived load" << std::endl;
94 ar( y );
95 }
96
foo()97 void foo() {}
98
99 int y;
100 };
101
102 namespace cereal
103 {
104 template <class Archive> struct specialize<Archive, Derived, cereal::specialization::member_load_save> {};
105 }
106
107 CEREAL_REGISTER_TYPE(Derived)
108
109 // ###################################
110 struct Test1
111 {
112 int a;
113
114 private:
115 friend class cereal::access;
116 template<class Archive>
serializeTest1117 void serialize(Archive & ar)
118 {
119 ar(CEREAL_NVP(a));
120 }
121 };
122
123 // ###################################
124 class Test2
125 {
126 public:
Test2()127 Test2() {}
Test2(int x)128 Test2( int x ) : a( x ) {}
129 int a;
130
131 private:
132 friend class cereal::access;
133
134 template<class Archive>
save(Archive & ar) const135 void save(Archive & ar) const
136 {
137 ar(a);
138 }
139
140 template<class Archive>
load(Archive & ar)141 void load(Archive & ar)
142 {
143 ar(a);
144 }
145 };
146
147 // ###################################
148 struct Test3
149 {
150 int a;
151 };
152
153 template<class Archive>
serialize(Archive & ar,Test3 & t)154 void serialize(Archive & ar, Test3 & t)
155 {
156 ar(CEREAL_NVP(t.a));
157 }
158
159 namespace test4
160 {
161 // ###################################
162 struct Test4
163 {
164 int a;
165 };
166
167 template<class Archive>
save(Archive & ar,Test4 const & t)168 void save(Archive & ar, Test4 const & t)
169 {
170 ar(CEREAL_NVP(t.a));
171 }
172
173 template<class Archive>
load(Archive & ar,Test4 & t)174 void load(Archive & ar, Test4 & t)
175 {
176 ar(CEREAL_NVP(t.a));
177 }
178 }
179
180 class Private
181 {
182 public:
Private()183 Private() : a('z') {}
184
185 private:
186 char a;
187
188 friend class cereal::access;
189
190 template<class Archive>
serialize(Archive & ar)191 void serialize(Archive & ar)
192 {
193 ar(a);
194 }
195 };
196
197 struct Everything
198 {
199 int x;
200 int y;
201 Test1 t1;
202 Test2 t2;
203 Test3 t3;
204 test4::Test4 t4;
205 std::string s;
206
207 template<class Archive>
serializeEverything208 void serialize(Archive & ar)
209 {
210 ar(CEREAL_NVP(x));
211 ar(CEREAL_NVP(y));
212 ar(CEREAL_NVP(t1));
213 ar(CEREAL_NVP(t2));
214 ar(CEREAL_NVP(t3));
215 ar(CEREAL_NVP(t4));
216 ar(CEREAL_NVP(s));
217 }
218
operator ==Everything219 bool operator==(Everything const & o)
220 {
221 return
222 x == o.x &&
223 y == o.y &&
224 t1.a == o.t1.a &&
225 t2.a == o.t2.a &&
226 t3.a == o.t3.a &&
227 t4.a == o.t4.a &&
228 s == o.s;
229 }
230 };
231
232 struct EmptyStruct
233 {
234 template<class Archive>
serializeEmptyStruct235 void serialize(Archive &)
236 {
237 std::cout << "Side effects!" << std::endl;
238 }
239 };
240
241 struct NonEmptyStruct
242 {
243 int x, y, z;
244 };
245
246 struct NoDefaultCtor
247 {
248 private:
NoDefaultCtorNoDefaultCtor249 NoDefaultCtor() {};
250 int z;
NoDefaultCtorNoDefaultCtor251 NoDefaultCtor( int x, bool ) :y(x) {}
252 public:
NoDefaultCtorNoDefaultCtor253 NoDefaultCtor(int x) : y(x)
254 { }
255
256 friend class cereal::access;
257
258 int y;
259
260 template <class Archive>
serializeNoDefaultCtor261 void serialize( Archive & ar )
262 {
263 ar( y );
264 }
265
266 template <class Archive>
load_and_constructNoDefaultCtor267 static void load_and_construct( Archive & ar, cereal::construct<NoDefaultCtor> & construct )
268 {
269 int yy;
270 ar( yy );
271 construct( yy, true );
272 construct->z = 33;
273 construct.ptr()->z = 33;
274 }
275 };
276
277 //namespace cereal
278 //{
279 // template <>
280 // struct LoadAndConstruct<NoDefaultCtor>
281 // {
282 // template <class Archive>
283 // static void load_and_construct( Archive & ar, cereal::construct<NoDefaultCtor> & construct )
284 // {
285 // int y;
286 // ar( y );
287 // construct( y );
288 // }
289 // };
290 //}
291
292 struct unordered_naming
293 {
294 int x;
295 int y;
296 int z;
297
298 template <class Archive>
saveunordered_naming299 void save( Archive & ar ) const
300 {
301 ar( CEREAL_NVP(x),
302 CEREAL_NVP(z),
303 CEREAL_NVP(y) );
304 }
305
306 template <class Archive>
loadunordered_naming307 void load( Archive & ar )
308 {
309 ar( x,
310 CEREAL_NVP(y),
311 CEREAL_NVP(z) );
312 }
313
operator ==unordered_naming314 bool operator==( unordered_naming const & other ) const
315 {
316 return x == other.x && y == other.y && z == other.z;
317 }
318 };
319
operator <<(std::ostream & os,unordered_naming const & s)320 std::ostream& operator<<(std::ostream& os, unordered_naming const & s)
321 {
322 os << "[x: " << s.x << " y: " << s.y << " z: " << s.z << "]";
323 return os;
324 }
325
326 template <class IArchive, class OArchive>
test_unordered_loads()327 void test_unordered_loads()
328 {
329 std::random_device rd;
330 std::mt19937 gen(rd());
331
332 auto rngI = [](){ return 1; };
333 auto rngF = [](){ return 2.0f; };
334 auto rngD = [](){ return 3.2; };
335
336 for(int i=0; i<100; ++i)
337 {
338 auto const name1 = "1";
339 auto const name2 = "2";
340 auto const name3 = "3";
341 auto const name4 = "4";
342 auto const name5 = "5";
343 auto const name6 = "6";
344 auto const name7 = "7";
345
346 int o_int1 = rngI();
347 double o_double2 = rngD();
348 std::vector<bool> o_vecbool3 = { true, false, true, false, true };
349 int o_int4 = rngI();
350 int o_int5 = rngI();
351 int o_int6 = rngI();
352 std::pair<float, unordered_naming> o_un7;
353 o_un7.first = rngF();
354 o_un7.second.x = rngI();
355 o_un7.second.y = rngI();
356 o_un7.second.z = rngI();
357
358 {
359 std::ofstream os("test.xml");
360 OArchive oar(os);
361
362 oar( cereal::make_nvp( name1, o_int1 ),
363 cereal::make_nvp( name2, o_double2 ),
364 cereal::make_nvp( name3, o_vecbool3 ),
365 cereal::make_nvp( name4, o_int4 ),
366 cereal::make_nvp( name5, o_int5 ),
367 cereal::make_nvp( name6, o_int6 ),
368 cereal::make_nvp( name7, o_un7 ) );
369 }
370
371 decltype(o_int1) i_int1;
372 decltype(o_double2) i_double2;
373 decltype(o_vecbool3) i_vecbool3;
374 decltype(o_int4) i_int4;
375 decltype(o_int5) i_int5;
376 decltype(o_int6) i_int6;
377 decltype(o_un7) i_un7;
378
379 std::ifstream is("test.xml");
380 {
381 IArchive iar(is);
382
383 iar( cereal::make_nvp( name7, o_un7 ),
384 cereal::make_nvp( name2, i_double2 ),
385 cereal::make_nvp( name4, i_int4 ),
386 cereal::make_nvp( name3, i_vecbool3 ),
387 cereal::make_nvp( name1, i_int1 ),
388 cereal::make_nvp( name5, i_int5 ),
389 i_int6 );
390 }
391 }
392 }
393
394 class BoostTransitionMS
395 {
396 public:
BoostTransitionMS()397 BoostTransitionMS() {}
BoostTransitionMS(int xx)398 BoostTransitionMS( int xx ) : x(xx) {}
399
getX()400 int getX(){ return x; }
setX(int xx)401 void setX( int xx ){ x = xx; }
402
403 private:
404 friend class cereal::access;
405 int x;
406
407 template <class Archive>
serialize(Archive & ar,const std::uint32_t)408 void serialize( Archive & ar, const std::uint32_t /*version*/ )
409 { ar( x ); }
410 };
411
412 class BoostTransitionSplit
413 {
414 public:
BoostTransitionSplit()415 BoostTransitionSplit() {}
BoostTransitionSplit(int xx)416 BoostTransitionSplit( int xx ) : x(xx) {}
417
getX()418 int getX(){ return x; }
setX(int xx)419 void setX( int xx ){ x = xx; }
420
421 private:
422 friend class cereal::access;
423 int x;
424
425 template <class Archive>
save(Archive & ar,const std::uint32_t) const426 void save( Archive & ar, const std::uint32_t /*version*/ ) const
427 { ar( x ); }
428
429 template <class Archive>
load(Archive & ar,const std::uint32_t)430 void load( Archive & ar, const std::uint32_t /*version*/ )
431 { ar( x ); }
432 };
433
434 class BoostTransitionNMS
435 {
436 public:
BoostTransitionNMS()437 BoostTransitionNMS() {}
BoostTransitionNMS(int xx)438 BoostTransitionNMS( int xx ) : x(xx) {}
439
440 int x;
441 };
442
443 template <class Archive>
serialize(Archive & ar,BoostTransitionNMS & bnms,const std::uint32_t version)444 void serialize( Archive & ar, BoostTransitionNMS & bnms, const std::uint32_t version )
445 { ar( bnms.x ); std::cout << "NMS version: " << version << std::endl; }
446
447 struct BoostTransitionNMSplit
448 {
449 public:
BoostTransitionNMSplitBoostTransitionNMSplit450 BoostTransitionNMSplit() {}
BoostTransitionNMSplitBoostTransitionNMSplit451 BoostTransitionNMSplit( int xx ) : x(xx) {}
452
453 int x;
454 };
455
456 template <class Archive>
save(Archive & ar,BoostTransitionNMSplit const & bnsplit,const std::uint32_t version)457 void save( Archive & ar, BoostTransitionNMSplit const & bnsplit, const std::uint32_t version )
458 { ar( bnsplit.x ); std::cout << "NMsave version: " << version << std::endl; }
459
460 template <class Archive>
load(Archive & ar,BoostTransitionNMSplit & bnsplit,const std::uint32_t version)461 void load( Archive & ar, BoostTransitionNMSplit & bnsplit, const std::uint32_t version )
462 { ar( bnsplit.x ); std::cout << "NMload version: " << version << std::endl; }
463
464 // ######################################################################
main()465 int main()
466 {
467 std::cout << std::boolalpha << std::endl;
468
469 Everything e_out;
470 e_out.x = 99;
471 e_out.y = 100;
472 e_out.t1 = {1};
473 e_out.t2 = {2};
474 e_out.t3 = {3};
475 e_out.t4 = {4};
476 e_out.s = "Hello, World!";
477 std::unique_ptr<NoDefaultCtor> nodefault( new NoDefaultCtor( 3 ) );
478
479 Test2 t2 = {22};
480
481 {
482 std::ofstream os("out.txt", std::ios::binary);
483 cereal::BinaryOutputArchive archive(os);
484 archive(CEREAL_NVP(e_out));
485 archive(t2);
486 archive(nodefault);
487 }
488
489 Everything e_in;
490
491 std::unique_ptr<NoDefaultCtor> nodefaultin( new NoDefaultCtor( 1 ) );
492
493 {
494 std::ifstream is("out.txt", std::ios::binary);
495 cereal::BinaryInputArchive archive(is);
496 archive(CEREAL_NVP(e_in));
497 archive(t2);
498 archive(nodefaultin);
499 std::remove("out.txt");
500 }
501
502 assert(e_in == e_out);
503 assert(nodefault->y == nodefaultin->y);
504
505 {
506 cereal::BinaryOutputArchive archive(std::cout);
507 int xxx[] = {-1, 95, 3};
508 archive( xxx );
509
510 cereal::XMLOutputArchive archive2(std::cout, cereal::XMLOutputArchive::Options(std::numeric_limits<double>::max_digits10, true, true));
511 archive2( xxx );
512
513 std::vector<int> yyy = {1, 2, 3};
514 archive2( yyy );
515
516 archive2.saveBinaryValue( xxx, sizeof(int)*3 );
517 }
518
519 {
520 std::ofstream os("out.xml");
521 cereal::XMLOutputArchive oar( os );
522 //cereal::XMLOutputArchive oar( std::cout );
523
524 oar( cereal::make_nvp("hello", 5 ) );
525
526 std::string bla("bla");
527 oar( bla );
528
529 auto intptr = std::make_shared<int>(99);
530 oar( CEREAL_NVP(intptr) );
531
532 std::map<std::string, int> map1 =
533 {
534 {"one", 1},
535 {"two", 2},
536 {"three", 3}
537 };
538
539 oar( CEREAL_NVP(map1) );
540
541 int x = 3;
542 oar( CEREAL_NVP(x) );
543 oar( 5 );
544 oar( 3.3 );
545 oar( 3.2f );
546 oar( true );
547
548 std::array<int,5> arr = {{1, 2, 3, 4, 5}};
549 oar( arr );
550
551 std::vector<std::string> vec = {"hey",
552 "there",
553 "buddy"};
554
555 std::vector<std::vector<std::string>> vec2 = {vec, vec, vec};
556
557 oar( cereal::make_nvp("EVERYTHING", e_out) );
558 oar( vec );
559 oar( vec2 );
560
561 int xxx[] = {-1, 95, 3};
562 oar.saveBinaryValue( xxx, sizeof(int)*3, "xxxbinary" );
563 //oar.saveBinaryValue( xxx, sizeof(int)*3 );
564
565 std::unique_ptr<Derived> d1( new Derived(3, 4) );
566 std::unique_ptr<Base> d2( new Derived(4, 5) );
567 std::shared_ptr<Base> d3( new Derived(5, 6) );
568 oar( d1 );
569 oar( d2 );
570 oar( d3 );
571 }
572
573 {
574 std::ifstream is("out.xml");
575 cereal::XMLInputArchive iar( is );
576
577 int hello;
578 iar( cereal::make_nvp("hello", hello) );
579 assert( hello == 5 );
580
581 std::string bla;
582 iar( bla );
583 assert( bla == "bla" );
584
585 std::shared_ptr<int> intptr;
586 iar( CEREAL_NVP(intptr) );
587 assert( *intptr == 99 );
588
589 std::map<std::string, int> map1;
590
591 iar( CEREAL_NVP(map1) );
592 assert( map1["one"] == 1 );
593 assert( map1["two"] == 2 );
594 assert( map1["three"] == 3 );
595
596
597 int x;
598 iar( CEREAL_NVP(x) );
599 assert( x == 3 );
600
601 int x5;
602 iar( x5 );
603 assert( x5 == 5 );
604
605 double x33;
606 iar( x33 );
607 assert( x33 == 3.3 );
608
609 float x32;
610 iar( x32 );
611 assert( x32 == 3.2f );
612
613 bool xtrue;
614 iar( xtrue );
615 assert( xtrue == true );
616
617 std::array<int,5> arr;
618 iar( arr );
619 for( int i = 0; i < 5; ++i )
620 assert( arr[i] == (i+1) );
621
622 Everything e;
623 iar( cereal::make_nvp("EVERYTHING", e) );
624 assert( e == e_out );
625
626 std::vector<std::string> vec;
627 iar( vec );
628 assert( vec[0] == "hey" );
629 assert( vec[1] == "there" );
630 assert( vec[2] == "buddy" );
631
632 std::vector<std::vector<std::string>> vec2;
633 iar( vec2 );
634 for( auto & v : vec2 )
635 {
636 assert( v[0] == "hey" );
637 assert( v[1] == "there" );
638 assert( v[2] == "buddy" );
639 }
640
641 int xxx[3];
642 iar.loadBinaryValue( xxx, sizeof(int)*3 );
643 assert( xxx[0] == -1 );
644 assert( xxx[1] == 95 );
645 assert( xxx[2] == 3 );
646
647 std::unique_ptr<Derived> d1;
648 std::unique_ptr<Base> d2;
649 std::shared_ptr<Base> d3;
650
651 iar( d1 );
652 assert( d1->x == 4 && d1->y == 3 );
653 iar( d2 );
654 assert( dynamic_cast<Derived*>(d2.get())->x == 5 && dynamic_cast<Derived*>(d2.get())->y == 4 );
655 iar( d3 );
656 assert( dynamic_cast<Derived*>(d3.get())->x == 6 && dynamic_cast<Derived*>(d3.get())->y == 5 );
657 }
658
659 {
660 std::ofstream b("endian.out", std::ios::binary);
661 cereal::PortableBinaryOutputArchive oar(b);
662
663 bool bb = true;
664 char a = 'a';
665 int x = 1234;
666 float y = 1.324f;
667 double z = 3.1452;
668 long double d = 1.123451234512345;
669 long long j = 2394873298472343;
670
671 oar( bb, a, x, y, z, d, j );
672 std::cout << bb << " " << a << " " << x << " " << y << " " << z << " " << d << " " << j << std::endl;
673 // valgrind will complain about uninitialized bytes here - seems to be the padding caused by the long double and
674 // long long allocations (this padding just exists on the stack and is never used anywhere)
675 // see https://bugs.kde.org/show_bug.cgi?id=197915
676 }
677 {
678 std::ifstream b("endian.out", std::ios::binary);
679 cereal::PortableBinaryInputArchive iar(b);
680
681 bool bb;
682 char a;
683 int x;
684 float y;
685 double z;
686 long double d;
687 long long j;
688
689 iar( bb, a, x, y, z, d, j );
690
691 std::cout << bb << " " << a << " " << x << " " << y << " " << z << " " << d << " " << j << std::endl;
692
693 std::remove("endian.out");
694 }
695
696 {
697 std::ofstream ss("xml_ordering.out");
698 cereal::XMLOutputArchive ar(ss);
699
700 double one = 1;
701 double two = 2;
702 double three = 3;
703 std::vector<int> four = {1, 2, 3, 4};
704
705 // Output is ordered 3 2 1 4
706 ar( three, CEREAL_NVP(two), one, cereal::make_nvp("five", four) );
707 }
708
709 {
710 std::ifstream ss("xml_ordering.out");
711 cereal::XMLInputArchive ar(ss);
712
713 // Output prodered out of order, try to load in order 1 2 3 4
714 double one;
715 double two;
716 double three;
717 std::vector<int> four;
718
719 ar( one ); // cereal can only give warnings if you used an NVP!
720 ar( CEREAL_NVP( two ) );
721 ar( three );
722
723 try
724 {
725 ar( CEREAL_NVP( three ) );
726 }
727 catch( cereal::Exception const & e )
728 {
729 std::cout << e.what() << std::endl;
730 std::cout << "Looked for three but we didn't use an NVP when saving" << std::endl;
731 }
732 ar( cereal::make_nvp("five", four) );
733 ar( cereal::make_nvp("five", four) ); // do it a second time since it shouldn't matter as we provide the name
734
735 std::cout << one << std::endl;
736 std::cout << two << std::endl;
737 std::cout << three << std::endl;
738 for( auto i : four ) std::cout << i << " ";
739 std::cout << std::endl;
740 }
741
742 {
743 // Boost transition layer stuff
744 std::ofstream ss("cereal_version.out");
745 cereal::XMLOutputArchive ar(ss);
746
747 BoostTransitionMS b(3);
748 ar( b, b );
749
750 BoostTransitionSplit c(4);
751 ar( c, c );
752
753 BoostTransitionNMS d(5);
754 ar( d, d );
755
756 BoostTransitionNMSplit e(32);
757 ar( e, e );
758 }
759
760 {
761 // Boost transition layer stuff
762 std::ifstream ss("cereal_version.out");
763 cereal::XMLInputArchive ar(ss);
764
765 BoostTransitionMS b;
766 ar( b );
767 assert( b.getX() == 3 );
768 b.setX( 0 );
769 ar( b );
770 assert( b.getX() == 3 );
771
772 BoostTransitionSplit c;
773 ar( c );
774 assert( c.getX() == 4 );
775 c.setX( 0 );
776 ar( c );
777 assert( c.getX() == 4 );
778
779 BoostTransitionNMS d;
780 ar( d );
781 assert( d.x == 5 );
782 d.x = 0;
783 ar( d );
784 assert( d.x == 5 );
785
786 BoostTransitionNMSplit e;
787 ar( e );
788 assert( e.x == 32 );
789 e.x = 0;
790 ar( e );
791 assert( e.x == 32 );
792 }
793
794 #ifdef CEREAL_FUTURE_EXPERIMENTAL
795 {
796 // Any testing
797 int x = 32;
798 int * xx = &x;
799 std::string y("hello");
800 cereal::detail::Any a(xx);
801 auto b = a;
802
803 std::cout << *((int *)a) << std::endl;
804 *((int*)a) = 44;
805 std::cout << *((int *)b) << std::endl;
806 std::cout << *((int *)a) << std::endl;
807
808 a = cereal::detail::Any(y);
809 std::string a_out = a;
810 std::cout << a_out << std::endl;
811 }
812 #endif // CEREAL_FUTURE_EXPERIMENTAL
813
814 return 0;
815 }
816
817 CEREAL_CLASS_VERSION(BoostTransitionMS, 1)
818 CEREAL_CLASS_VERSION(BoostTransitionSplit, 2)
819 CEREAL_CLASS_VERSION(BoostTransitionNMS, 3)
820 // keep the other at default version (0)
821