cereal
A C++11 library for serialization
cereal.hpp
Go to the documentation of this file.
1
3/*
4 Copyright (c) 2014, Randolph Voorhies, Shane Grant
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 * Neither the name of the copyright holder nor the
15 names of its contributors may be used to endorse or promote products
16 derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
22 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29#ifndef CEREAL_CEREAL_HPP_
30#define CEREAL_CEREAL_HPP_
31
32#include <type_traits>
33#include <string>
34#include <memory>
35#include <functional>
36#include <unordered_map>
37#include <unordered_set>
38#include <vector>
39#include <cstddef>
40#include <cstdint>
41#include <functional>
42
43#include "cereal/macros.hpp"
47
48namespace cereal
49{
50 // ######################################################################
52
54 template <class T> inline
55 NameValuePair<T> make_nvp( std::string const & name, T && value )
56 {
57 return {name.c_str(), std::forward<T>(value)};
58 }
59
61
63 template <class T> inline
64 NameValuePair<T> make_nvp( const char * name, T && value )
65 {
66 return {name, std::forward<T>(value)};
67 }
68
70
72 #define CEREAL_NVP(T) ::cereal::make_nvp(#T, T)
73
74 // ######################################################################
76
80 template <class T> inline
81 BinaryData<T> binary_data( T && data, size_t size )
82 {
83 return {std::forward<T>(data), size};
84 }
85
86 // ######################################################################
88
95 template <class T> inline
97 {
98 return {std::forward<T>(sz)};
99 }
100
101 // ######################################################################
103
148 template <class T> inline
149 DeferredData<T> defer( T && value )
150 {
151 return {std::forward<T>(value)};
152 }
153
154 // ######################################################################
157
161 template <class Archive, class T> inline
162 void prologue( Archive & /* archive */, T const & /* data */)
163 { }
164
167
168 template <class Archive, class T> inline
169 void epilogue( Archive & /* archive */, T const & /* data */)
170 { }
171
172 // ######################################################################
174
185 enum Flags { AllowEmptyClassElision = 1 };
186
187 // ######################################################################
189
195 #define CEREAL_REGISTER_ARCHIVE(Archive) \
196 namespace cereal { namespace detail { \
197 template <class T, class BindingTag> \
198 typename polymorphic_serialization_support<Archive, T>::type \
199 instantiate_polymorphic_binding( T*, Archive*, BindingTag, adl_tag ); \
200 } } /* end namespaces */
201
203 #if defined(__GNUC__)
204 // GCC / clang don't want the function
205 #define CEREAL_UNUSED_FUNCTION
206 #else
207 #define CEREAL_UNUSED_FUNCTION static void unused() { (void)version; }
208 #endif
209
210 // ######################################################################
212
265 #ifdef CEREAL_HAS_CPP17
266 #define CEREAL_CLASS_VERSION(TYPE, VERSION_NUMBER) \
267 namespace cereal { namespace detail { \
268 template <> struct Version<TYPE> \
269 { \
270 static std::uint32_t registerVersion() \
271 { \
272 ::cereal::detail::StaticObject<Versions>::getInstance().mapping.emplace( \
273 std::type_index(typeid(TYPE)).hash_code(), VERSION_NUMBER ); \
274 return VERSION_NUMBER; \
275 } \
276 static inline const std::uint32_t version = registerVersion(); \
277 CEREAL_UNUSED_FUNCTION \
278 }; /* end Version */ \
279 } } // end namespaces
280 #else
281 #define CEREAL_CLASS_VERSION(TYPE, VERSION_NUMBER) \
282 namespace cereal { namespace detail { \
283 template <> struct Version<TYPE> \
284 { \
285 static const std::uint32_t version; \
286 static std::uint32_t registerVersion() \
287 { \
288 ::cereal::detail::StaticObject<Versions>::getInstance().mapping.emplace( \
289 std::type_index(typeid(TYPE)).hash_code(), VERSION_NUMBER ); \
290 return VERSION_NUMBER; \
291 } \
292 CEREAL_UNUSED_FUNCTION \
293 }; /* end Version */ \
294 const std::uint32_t Version<TYPE>::version = \
295 Version<TYPE>::registerVersion(); \
296 } } // end namespaces
297
298 #endif
299
300 // ######################################################################
302
317 template<class ArchiveType, std::uint32_t Flags = 0>
319 {
320 public:
322
323 OutputArchive(ArchiveType * const derived) : self(derived), itsCurrentPointerId(1), itsCurrentPolymorphicTypeId(1)
324 { }
325
326 OutputArchive & operator=( OutputArchive const & ) = delete;
327
329
330 template <class ... Types> inline
331 ArchiveType & operator()( Types && ... args )
332 {
333 self->process( std::forward<Types>( args )... );
334 return *self;
335 }
336
338
340 {
341 for( auto & deferment : itsDeferments )
342 deferment();
343 }
344
349
351
355 using is_loading = std::false_type;
356
358
362 using is_saving = std::true_type;
363
365
368 template <class T> inline
369 ArchiveType & operator&( T && arg )
370 {
371 self->process( std::forward<T>( arg ) );
372 return *self;
373 }
374
376
379 template <class T> inline
380 ArchiveType & operator<<( T && arg )
381 {
382 self->process( std::forward<T>( arg ) );
383 return *self;
384 }
385
387
389
398 inline std::uint32_t registerSharedPointer(const std::shared_ptr<const void>& sharedPointer)
399 {
400 void const * addr = sharedPointer.get();
401
402 // Handle null pointers by just returning 0
403 if(addr == 0) return 0;
404 itsSharedPointerStorage.push_back(sharedPointer);
405
406 auto id = itsSharedPointerMap.find( addr );
407 if( id == itsSharedPointerMap.end() )
408 {
409 auto ptrId = itsCurrentPointerId++;
410 itsSharedPointerMap.insert( {addr, ptrId} );
411 return ptrId | detail::msb_32bit; // mask MSB to be 1
412 }
413 else
414 return id->second;
415 }
416
418
425 inline std::uint32_t registerPolymorphicType( char const * name )
426 {
427 auto id = itsPolymorphicTypeMap.find( name );
428 if( id == itsPolymorphicTypeMap.end() )
429 {
430 auto polyId = itsCurrentPolymorphicTypeId++;
431 itsPolymorphicTypeMap.insert( {name, polyId} );
432 return polyId | detail::msb_32bit; // mask MSB to be 1
433 }
434 else
435 return id->second;
436 }
437
438 private:
440 template <class T> inline
441 void process( T && head )
442 {
443 prologue( *self, head );
444 self->processImpl( head );
445 epilogue( *self, head );
446 }
447
449 template <class T, class ... Other> inline
450 void process( T && head, Other && ... tail )
451 {
452 self->process( std::forward<T>( head ) );
453 self->process( std::forward<Other>( tail )... );
454 }
455
457
458 template <class T> inline
459 ArchiveType & processImpl(virtual_base_class<T> const & b)
460 {
461 traits::detail::base_class_id id(b.base_ptr);
462 if(itsBaseClassSet.count(id) == 0)
463 {
464 itsBaseClassSet.insert(id);
465 self->processImpl( *b.base_ptr );
466 }
467 return *self;
468 }
469
471
472 template <class T> inline
473 ArchiveType & processImpl(base_class<T> const & b)
474 {
475 self->processImpl( *b.base_ptr );
476 return *self;
477 }
478
479 std::vector<std::function<void(void)>> itsDeferments;
480
481 template <class T> inline
482 ArchiveType & processImpl(DeferredData<T> const & d)
483 {
484 std::function<void(void)> deferment( [this, d](){ self->process( d.value ); } );
485 itsDeferments.emplace_back( std::move(deferment) );
486
487 return *self;
488 }
489
491
497 #define PROCESS_IF(name) \
498 traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
499 !traits::has_invalid_output_versioning<T, ArchiveType>::value, \
500 (traits::is_output_serializable<T, ArchiveType>::value && \
501 (traits::is_specialized_##name<T, ArchiveType>::value || \
502 !traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae
503
505 template <class T, PROCESS_IF(member_serialize)> inline
506 ArchiveType & processImpl(T const & t)
507 {
508 access::member_serialize(*self, const_cast<T &>(t));
509 return *self;
510 }
511
513 template <class T, PROCESS_IF(non_member_serialize)> inline
514 ArchiveType & processImpl(T const & t)
515 {
516 CEREAL_SERIALIZE_FUNCTION_NAME(*self, const_cast<T &>(t));
517 return *self;
518 }
519
521 template <class T, PROCESS_IF(member_save)> inline
522 ArchiveType & processImpl(T const & t)
523 {
524 access::member_save(*self, t);
525 return *self;
526 }
527
529 template <class T, PROCESS_IF(non_member_save)> inline
530 ArchiveType & processImpl(T const & t)
531 {
533 return *self;
534 }
535
537 template <class T, PROCESS_IF(member_save_minimal)> inline
538 ArchiveType & processImpl(T const & t)
539 {
540 self->process( access::member_save_minimal(*self, t) );
541 return *self;
542 }
543
545 template <class T, PROCESS_IF(non_member_save_minimal)> inline
546 ArchiveType & processImpl(T const & t)
547 {
548 self->process( CEREAL_SAVE_MINIMAL_FUNCTION_NAME(*self, t) );
549 return *self;
550 }
551
553 template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
554 !traits::is_output_serializable<T, ArchiveType>::value,
555 std::is_empty<T>::value> = traits::sfinae> inline
556 ArchiveType & processImpl(T const &)
557 {
558 return *self;
559 }
560
562
565 template <class T, traits::EnableIf<traits::has_invalid_output_versioning<T, ArchiveType>::value ||
566 (!traits::is_output_serializable<T, ArchiveType>::value &&
567 (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
568 ArchiveType & processImpl(T const &)
569 {
570 static_assert(traits::detail::count_output_serializers<T, ArchiveType>::value != 0,
571 "cereal could not find any output serialization functions for the provided type and archive combination. \n\n "
572 "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
573 "Serialize functions generally have the following signature: \n\n "
574 "template<class Archive> \n "
575 " void serialize(Archive & ar) \n "
576 " { \n "
577 " ar( member1, member2, member3 ); \n "
578 " } \n\n " );
579
580 static_assert(traits::detail::count_output_serializers<T, ArchiveType>::value < 2,
581 "cereal found more than one compatible output serialization function for the provided type and archive combination. \n\n "
582 "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
583 "Use specialization (see access.hpp) if you need to disambiguate between serialize vs load/save functions. \n "
584 "Note that serialization functions can be inherited which may lead to the aforementioned ambiguities. \n "
585 "In addition, you may not mix versioned with non-versioned serialization functions. \n\n ");
586
587 return *self;
588 }
589
591
595 template <class T> inline
596 std::uint32_t registerClassVersion()
597 {
598 static const auto hash = std::type_index(typeid(T)).hash_code();
599 const auto insertResult = itsVersionedTypes.insert( hash );
601 const auto version =
602 detail::StaticObject<detail::Versions>::getInstance().find( hash, detail::Version<T>::version );
603
604 if( insertResult.second ) // insertion took place, serialize the version number
605 process( make_nvp<ArchiveType>("cereal_class_version", version) );
606
607 return version;
608 }
609
611
612 template <class T, PROCESS_IF(member_versioned_serialize)> inline
613 ArchiveType & processImpl(T const & t)
614 {
615 access::member_serialize(*self, const_cast<T &>(t), registerClassVersion<T>());
616 return *self;
617 }
618
620
621 template <class T, PROCESS_IF(non_member_versioned_serialize)> inline
622 ArchiveType & processImpl(T const & t)
623 {
624 CEREAL_SERIALIZE_FUNCTION_NAME(*self, const_cast<T &>(t), registerClassVersion<T>());
625 return *self;
626 }
627
629
630 template <class T, PROCESS_IF(member_versioned_save)> inline
631 ArchiveType & processImpl(T const & t)
632 {
633 access::member_save(*self, t, registerClassVersion<T>());
634 return *self;
635 }
636
638
639 template <class T, PROCESS_IF(non_member_versioned_save)> inline
640 ArchiveType & processImpl(T const & t)
641 {
642 CEREAL_SAVE_FUNCTION_NAME(*self, t, registerClassVersion<T>());
643 return *self;
644 }
645
647
648 template <class T, PROCESS_IF(member_versioned_save_minimal)> inline
649 ArchiveType & processImpl(T const & t)
650 {
651 self->process( access::member_save_minimal(*self, t, registerClassVersion<T>()) );
652 return *self;
653 }
654
656
657 template <class T, PROCESS_IF(non_member_versioned_save_minimal)> inline
658 ArchiveType & processImpl(T const & t)
659 {
660 self->process( CEREAL_SAVE_MINIMAL_FUNCTION_NAME(*self, t, registerClassVersion<T>()) );
661 return *self;
662 }
663
664 #undef PROCESS_IF
665
666 private:
667 ArchiveType * const self;
668
670 std::unordered_set<traits::detail::base_class_id, traits::detail::base_class_id_hash> itsBaseClassSet;
671
673 std::unordered_map<void const *, std::uint32_t> itsSharedPointerMap;
674
676 // during lifetime of itsSharedPointerMap to prevent CVE-2020-11105.
677 std::vector<std::shared_ptr<const void>> itsSharedPointerStorage;
678
680 std::uint32_t itsCurrentPointerId;
681
683 std::unordered_map<char const *, std::uint32_t> itsPolymorphicTypeMap;
684
686 std::uint32_t itsCurrentPolymorphicTypeId;
687
689 std::unordered_set<size_type> itsVersionedTypes;
690 }; // class OutputArchive
691
692 // ######################################################################
694
709 template<class ArchiveType, std::uint32_t Flags = 0>
711 {
712 public:
714
715 InputArchive(ArchiveType * const derived) :
716 self(derived),
717 itsBaseClassSet(),
718 itsSharedPointerMap(),
719 itsPolymorphicTypeMap(),
720 itsVersionedTypes()
721 { }
722
723 InputArchive & operator=( InputArchive const & ) = delete;
724
726
727 template <class ... Types> inline
728 ArchiveType & operator()( Types && ... args )
729 {
730 process( std::forward<Types>( args )... );
731 return *self;
732 }
733
735
737 {
738 for( auto & deferment : itsDeferments )
739 deferment();
740 }
741
746
748
752 using is_loading = std::true_type;
753
755
759 using is_saving = std::false_type;
760
762
765 template <class T> inline
766 ArchiveType & operator&( T && arg )
767 {
768 self->process( std::forward<T>( arg ) );
769 return *self;
770 }
771
773
776 template <class T> inline
777 ArchiveType & operator>>( T && arg )
778 {
779 self->process( std::forward<T>( arg ) );
780 return *self;
781 }
782
784
786
793 inline std::shared_ptr<void> getSharedPointer(std::uint32_t const id)
794 {
795 if(id == 0) return std::shared_ptr<void>(nullptr);
796
797 auto iter = itsSharedPointerMap.find( id );
798 if(iter == itsSharedPointerMap.end())
799 throw Exception("Error while trying to deserialize a smart pointer. Could not find id " + std::to_string(id));
800
801 return iter->second;
802 }
803
805
811 inline void registerSharedPointer(std::uint32_t const id, std::shared_ptr<void> ptr)
812 {
813 std::uint32_t const stripped_id = id & ~detail::msb_32bit;
814 itsSharedPointerMap[stripped_id] = ptr;
815 }
816
818
824 inline std::string getPolymorphicName(std::uint32_t const id)
825 {
826 auto name = itsPolymorphicTypeMap.find( id );
827 if(name == itsPolymorphicTypeMap.end())
828 {
829 throw Exception("Error while trying to deserialize a polymorphic pointer. Could not find type id " + std::to_string(id));
830 }
831 return name->second;
832 }
833
835
841 inline void registerPolymorphicName(std::uint32_t const id, std::string const & name)
842 {
843 std::uint32_t const stripped_id = id & ~detail::msb_32bit;
844 itsPolymorphicTypeMap.insert( {stripped_id, name} );
845 }
846
847 private:
849 template <class T> inline
850 void process( T && head )
851 {
852 prologue( *self, head );
853 self->processImpl( head );
854 epilogue( *self, head );
855 }
856
858 template <class T, class ... Other> inline
859 void process( T && head, Other && ... tail )
860 {
861 process( std::forward<T>( head ) );
862 process( std::forward<Other>( tail )... );
863 }
864
866
867 template <class T> inline
868 ArchiveType & processImpl(virtual_base_class<T> & b)
869 {
870 traits::detail::base_class_id id(b.base_ptr);
871 if(itsBaseClassSet.count(id) == 0)
872 {
873 itsBaseClassSet.insert(id);
874 self->processImpl( *b.base_ptr );
875 }
876 return *self;
877 }
878
880
881 template <class T> inline
882 ArchiveType & processImpl(base_class<T> & b)
883 {
884 self->processImpl( *b.base_ptr );
885 return *self;
886 }
887
888 std::vector<std::function<void(void)>> itsDeferments;
889
890 template <class T> inline
891 ArchiveType & processImpl(DeferredData<T> const & d)
892 {
893 std::function<void(void)> deferment( [this, d](){ self->process( d.value ); } );
894 itsDeferments.emplace_back( std::move(deferment) );
895
896 return *self;
897 }
898
900
906 #define PROCESS_IF(name) \
907 traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
908 !traits::has_invalid_input_versioning<T, ArchiveType>::value, \
909 (traits::is_input_serializable<T, ArchiveType>::value && \
910 (traits::is_specialized_##name<T, ArchiveType>::value || \
911 !traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae
912
914 template <class T, PROCESS_IF(member_serialize)> inline
915 ArchiveType & processImpl(T & t)
916 {
917 access::member_serialize(*self, t);
918 return *self;
919 }
920
922 template <class T, PROCESS_IF(non_member_serialize)> inline
923 ArchiveType & processImpl(T & t)
924 {
926 return *self;
927 }
928
930 template <class T, PROCESS_IF(member_load)> inline
931 ArchiveType & processImpl(T & t)
932 {
933 access::member_load(*self, t);
934 return *self;
935 }
936
938 template <class T, PROCESS_IF(non_member_load)> inline
939 ArchiveType & processImpl(T & t)
940 {
942 return *self;
943 }
944
946 template <class T, PROCESS_IF(member_load_minimal)> inline
947 ArchiveType & processImpl(T & t)
948 {
949 using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
950 typename traits::has_member_save_minimal<T, OutArchiveType>::type value;
951 self->process( value );
952 access::member_load_minimal(*self, t, value);
953 return *self;
954 }
955
957 template <class T, PROCESS_IF(non_member_load_minimal)> inline
958 ArchiveType & processImpl(T & t)
959 {
960 using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
961 typename traits::has_non_member_save_minimal<T, OutArchiveType>::type value;
962 self->process( value );
963 CEREAL_LOAD_MINIMAL_FUNCTION_NAME(*self, t, value);
964 return *self;
965 }
966
968 template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
969 !traits::is_input_serializable<T, ArchiveType>::value,
970 std::is_empty<T>::value> = traits::sfinae> inline
971 ArchiveType & processImpl(T const &)
972 {
973 return *self;
974 }
975
977
980 template <class T, traits::EnableIf<traits::has_invalid_input_versioning<T, ArchiveType>::value ||
981 (!traits::is_input_serializable<T, ArchiveType>::value &&
982 (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
983 ArchiveType & processImpl(T const &)
984 {
985 static_assert(traits::detail::count_input_serializers<T, ArchiveType>::value != 0,
986 "cereal could not find any input serialization functions for the provided type and archive combination. \n\n "
987 "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
988 "Serialize functions generally have the following signature: \n\n "
989 "template<class Archive> \n "
990 " void serialize(Archive & ar) \n "
991 " { \n "
992 " ar( member1, member2, member3 ); \n "
993 " } \n\n " );
994
995 static_assert(traits::detail::count_input_serializers<T, ArchiveType>::value < 2,
996 "cereal found more than one compatible input serialization function for the provided type and archive combination. \n\n "
997 "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
998 "Use specialization (see access.hpp) if you need to disambiguate between serialize vs load/save functions. \n "
999 "Note that serialization functions can be inherited which may lead to the aforementioned ambiguities. \n "
1000 "In addition, you may not mix versioned with non-versioned serialization functions. \n\n ");
1001
1002 return *self;
1003 }
1004
1006 template <class A, class B, bool C, bool D, bool E, bool F> friend struct detail::Construct;
1007
1009
1013 template <class T> inline
1014 std::uint32_t loadClassVersion()
1015 {
1016 static const auto hash = std::type_index(typeid(T)).hash_code();
1017 auto lookupResult = itsVersionedTypes.find( hash );
1018
1019 if( lookupResult != itsVersionedTypes.end() ) // already exists
1020 return lookupResult->second;
1021 else // need to load
1022 {
1023 std::uint32_t version;
1024
1025 process( make_nvp<ArchiveType>("cereal_class_version", version) );
1026 itsVersionedTypes.emplace_hint( lookupResult, hash, version );
1027
1028 return version;
1029 }
1030 }
1031
1033
1034 template <class T, PROCESS_IF(member_versioned_serialize)> inline
1035 ArchiveType & processImpl(T & t)
1036 {
1037 const auto version = loadClassVersion<T>();
1038 access::member_serialize(*self, t, version);
1039 return *self;
1040 }
1041
1043
1044 template <class T, PROCESS_IF(non_member_versioned_serialize)> inline
1045 ArchiveType & processImpl(T & t)
1046 {
1047 const auto version = loadClassVersion<T>();
1048 CEREAL_SERIALIZE_FUNCTION_NAME(*self, t, version);
1049 return *self;
1050 }
1051
1053
1054 template <class T, PROCESS_IF(member_versioned_load)> inline
1055 ArchiveType & processImpl(T & t)
1056 {
1057 const auto version = loadClassVersion<T>();
1058 access::member_load(*self, t, version);
1059 return *self;
1060 }
1061
1063
1064 template <class T, PROCESS_IF(non_member_versioned_load)> inline
1065 ArchiveType & processImpl(T & t)
1066 {
1067 const auto version = loadClassVersion<T>();
1068 CEREAL_LOAD_FUNCTION_NAME(*self, t, version);
1069 return *self;
1070 }
1071
1073
1074 template <class T, PROCESS_IF(member_versioned_load_minimal)> inline
1075 ArchiveType & processImpl(T & t)
1076 {
1077 using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
1078 const auto version = loadClassVersion<T>();
1079 typename traits::has_member_versioned_save_minimal<T, OutArchiveType>::type value;
1080 self->process(value);
1081 access::member_load_minimal(*self, t, value, version);
1082 return *self;
1083 }
1084
1086
1087 template <class T, PROCESS_IF(non_member_versioned_load_minimal)> inline
1088 ArchiveType & processImpl(T & t)
1089 {
1090 using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
1091 const auto version = loadClassVersion<T>();
1092 typename traits::has_non_member_versioned_save_minimal<T, OutArchiveType>::type value;
1093 self->process(value);
1094 CEREAL_LOAD_MINIMAL_FUNCTION_NAME(*self, t, value, version);
1095 return *self;
1096 }
1097
1098 #undef PROCESS_IF
1099
1100 private:
1101 ArchiveType * const self;
1102
1104 std::unordered_set<traits::detail::base_class_id, traits::detail::base_class_id_hash> itsBaseClassSet;
1105
1107 std::unordered_map<std::uint32_t, std::shared_ptr<void>> itsSharedPointerMap;
1108
1110 std::unordered_map<std::uint32_t, std::string> itsPolymorphicTypeMap;
1111
1113 std::unordered_map<std::size_t, std::uint32_t> itsVersionedTypes;
1114 }; // class InputArchive
1115} // namespace cereal
1116
1117// This include needs to come after things such as binary_data, make_nvp, etc
1118#include "cereal/types/common.hpp"
1119
1120#endif // CEREAL_CEREAL_HPP_
Support for base classes (virtual and non-virtual)
A wrapper around data that should be serialized after all non-deferred data.
Definition: helpers.hpp:233
The base input archive class.
Definition: cereal.hpp:711
ArchiveType & operator>>(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:777
std::string getPolymorphicName(std::uint32_t const id)
Retrieves the string for a polymorphic type given a unique key for it.
Definition: cereal.hpp:824
void registerSharedPointer(std::uint32_t const id, std::shared_ptr< void > ptr)
Registers a shared pointer to its unique identifier.
Definition: cereal.hpp:811
ArchiveType & operator()(Types &&... args)
Serializes all passed in data.
Definition: cereal.hpp:728
InputArchive(ArchiveType *const derived)
Construct the output archive.
Definition: cereal.hpp:715
void serializeDeferments()
Serializes any data marked for deferment using defer.
Definition: cereal.hpp:736
std::shared_ptr< void > getSharedPointer(std::uint32_t const id)
Retrieves a shared pointer given a unique key for it.
Definition: cereal.hpp:793
std::true_type is_loading
Indicates this archive is intended for loading.
Definition: cereal.hpp:752
void registerPolymorphicName(std::uint32_t const id, std::string const &name)
Registers a polymorphic name string to its unique identifier.
Definition: cereal.hpp:841
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:766
std::false_type is_saving
Indicates this archive is not intended for saving.
Definition: cereal.hpp:759
For holding name value pairs.
Definition: helpers.hpp:140
The base output archive class.
Definition: cereal.hpp:319
std::uint32_t registerSharedPointer(const std::shared_ptr< const void > &sharedPointer)
Registers a shared pointer with the archive.
Definition: cereal.hpp:398
ArchiveType & operator<<(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:380
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:369
std::false_type is_loading
Indicates this archive is not intended for loading.
Definition: cereal.hpp:355
OutputArchive(ArchiveType *const derived)
Construct the output archive.
Definition: cereal.hpp:323
ArchiveType & operator()(Types &&... args)
Serializes all passed in data.
Definition: cereal.hpp:331
std::uint32_t registerPolymorphicType(char const *name)
Registers a polymorphic type name with the archive.
Definition: cereal.hpp:425
void serializeDeferments()
Serializes any data marked for deferment using defer.
Definition: cereal.hpp:339
std::true_type is_saving
Indicates this archive is intended for saving.
Definition: cereal.hpp:362
A wrapper around size metadata.
Definition: helpers.hpp:313
Definition: helpers.hpp:282
Definition: helpers.hpp:270
static LockGuard lock()
Attempts to lock this static object for the current scope.
Definition: static_object.hpp:110
Support common types - always included automatically.
void epilogue(Archive &, T const &)
Definition: cereal.hpp:169
void prologue(Archive &, T const &)
Definition: cereal.hpp:162
Flags
Special flags for archives.
Definition: cereal.hpp:185
NameValuePair< T > make_nvp(const char *name, T &&value)
Creates a name value pair.
Definition: cereal.hpp:64
SizeTag< T > make_size_tag(T &&sz)
Creates a size tag from some variable.
Definition: cereal.hpp:96
BinaryData< T > binary_data(T &&data, size_t size)
Convenience function to create binary data for both const and non const pointers.
Definition: cereal.hpp:81
NameValuePair< T > make_nvp(std::string const &name, T &&value)
Creates a name value pair.
Definition: cereal.hpp:55
DeferredData< T > defer(T &&value)
Marks data for deferred serialization.
Definition: cereal.hpp:149
Internal helper functionality.
Preprocessor macros that can customise the cereal library.
#define CEREAL_LOAD_MINIMAL_FUNCTION_NAME
The deserialization (load_minimal) function name to search for.
Definition: macros.hpp:99
#define CEREAL_LOAD_FUNCTION_NAME
The deserialization (load) function name to search for.
Definition: macros.hpp:85
#define CEREAL_SAVE_FUNCTION_NAME
The serialization (save) function name to search for.
Definition: macros.hpp:92
#define CEREAL_SAVE_MINIMAL_FUNCTION_NAME
The serialization (save_minimal) function name to search for.
Definition: macros.hpp:106
#define CEREAL_SERIALIZE_FUNCTION_NAME
The serialization/deserialization function name to search for.
Definition: macros.hpp:78
A wrapper around data that can be serialized in a binary fashion.
Definition: helpers.hpp:212
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:49
Definition: traits.hpp:1339
Internal type trait support.
typename detail::EnableIfHelper< Conditions... >::type EnableIf
Provides a way to enable a function if conditions are met.
Definition: traits.hpp:116