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