NDDEM
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 
48 namespace 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 
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  {
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  {
532  CEREAL_SAVE_FUNCTION_NAME(*self, t);
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),
556  ArchiveType & processImpl(T const &)
557  {
558  return *self;
559  }
560 
562 
568  ArchiveType & processImpl(T const &)
569  {
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 
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
597  {
598  static const auto hash = std::type_index(typeid(T)).hash_code();
599  const auto insertResult = itsVersionedTypes.insert( hash );
601  const auto 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 
681 
683  std::unordered_map<char const *, std::uint32_t> itsPolymorphicTypeMap;
684 
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(),
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
869  {
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  {
941  CEREAL_LOAD_FUNCTION_NAME(*self, t);
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;
951  self->process( 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;
962  self->process( value );
964  return *self;
965  }
966 
968  template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
971  ArchiveType & processImpl(T const &)
972  {
973  return *self;
974  }
975 
977 
983  ArchiveType & processImpl(T const &)
984  {
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 
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
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>();
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>();
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_
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:25318
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
DeferredData< T > defer(T &&value)
Marks data for deferred serialization.
Definition: cereal.hpp:149
The base input archive class.
Definition: cereal.hpp:711
ArchiveType *const self
Definition: cereal.hpp:1101
void process(T &&head, Other &&... tail)
Unwinds to process all data.
Definition: cereal.hpp:859
InputArchive & operator=(InputArchive const &)=delete
std::unordered_map< std::uint32_t, std::shared_ptr< void > > itsSharedPointerMap
Maps from pointer ids to metadata.
Definition: cereal.hpp:1107
ArchiveType & operator()(Types &&... args)
Serializes all passed in data.
Definition: cereal.hpp:728
std::shared_ptr< void > getSharedPointer(std::uint32_t const id)
Retrieves a shared pointer given a unique key for it.
Definition: cereal.hpp:793
ArchiveType & processImpl(virtual_base_class< T > &b)
Serialization of a virtual_base_class wrapper.
Definition: cereal.hpp:868
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
std::unordered_set< traits::detail::base_class_id, traits::detail::base_class_id_hash > itsBaseClassSet
A set of all base classes that have been serialized.
Definition: cereal.hpp:1104
std::uint32_t loadClassVersion()
Registers a class version with the archive and serializes it if necessary.
Definition: cereal.hpp:1014
std::unordered_map< std::uint32_t, std::string > itsPolymorphicTypeMap
Maps from name ids to names.
Definition: cereal.hpp:1110
ArchiveType & processImpl(T const &)
Empty class specialization.
Definition: cereal.hpp:971
void registerSharedPointer(std::uint32_t const id, std::shared_ptr< void > ptr)
Registers a shared pointer to its unique identifier.
Definition: cereal.hpp:811
InputArchive(ArchiveType *const derived)
Construct the output archive.
Definition: cereal.hpp:715
ArchiveType & processImpl(base_class< T > &b)
Serialization of a base_class wrapper.
Definition: cereal.hpp:882
void serializeDeferments()
Serializes any data marked for deferment using defer.
Definition: cereal.hpp:736
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:766
std::unordered_map< std::size_t, std::uint32_t > itsVersionedTypes
Maps from type hash codes to version numbers.
Definition: cereal.hpp:1113
std::vector< std::function< void(void)> > itsDeferments
Definition: cereal.hpp:888
ArchiveType & operator>>(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:777
ArchiveType & processImpl(DeferredData< T > const &d)
Definition: cereal.hpp:891
ArchiveType & processImpl(T &t)
Member serialization.
Definition: cereal.hpp:915
std::true_type is_loading
Indicates this archive is intended for loading.
Definition: cereal.hpp:752
void process(T &&head)
Serializes data after calling prologue, then calls epilogue.
Definition: cereal.hpp:850
void registerPolymorphicName(std::uint32_t const id, std::string const &name)
Registers a polymorphic name string to its unique identifier.
Definition: cereal.hpp:841
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
NameValuePair< T > make_nvp(const char *name, T &&value)
Creates a name value pair.
Definition: cereal.hpp:64
NameValuePair< T > make_nvp(std::string const &name, T &&value)
Creates a name value pair.
Definition: cereal.hpp:55
The base output archive class.
Definition: cereal.hpp:319
ArchiveType & operator<<(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:380
ArchiveType & processImpl(DeferredData< T > const &d)
Definition: cereal.hpp:482
std::unordered_map< char const *, std::uint32_t > itsPolymorphicTypeMap
Maps from polymorphic type name strings to ids.
Definition: cereal.hpp:683
std::uint32_t registerSharedPointer(const std::shared_ptr< const void > &sharedPointer)
Registers a shared pointer with the archive.
Definition: cereal.hpp:398
OutputArchive & operator=(OutputArchive const &)=delete
std::unordered_set< traits::detail::base_class_id, traits::detail::base_class_id_hash > itsBaseClassSet
A set of all base classes that have been serialized.
Definition: cereal.hpp:670
ArchiveType & processImpl(virtual_base_class< T > const &b)
Serialization of a virtual_base_class wrapper.
Definition: cereal.hpp:459
std::uint32_t itsCurrentPolymorphicTypeId
The id to be given to the next polymorphic type name.
Definition: cereal.hpp:686
ArchiveType *const self
Definition: cereal.hpp:667
std::unordered_set< size_type > itsVersionedTypes
Keeps track of classes that have versioning information associated with them.
Definition: cereal.hpp:689
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:369
void process(T &&head)
Serializes data after calling prologue, then calls epilogue.
Definition: cereal.hpp:441
ArchiveType & processImpl(T const &t)
Member serialization.
Definition: cereal.hpp:506
std::unordered_map< void const *, std::uint32_t > itsSharedPointerMap
Maps from addresses to pointer ids.
Definition: cereal.hpp:673
std::vector< std::function< void(void)> > itsDeferments
Definition: cereal.hpp:479
void process(T &&head, Other &&... tail)
Unwinds to process all data.
Definition: cereal.hpp:450
ArchiveType & processImpl(T const &)
Empty class specialization.
Definition: cereal.hpp:556
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
std::vector< std::shared_ptr< const void > > itsSharedPointerStorage
Copy of shared pointers used in itsSharedPointerMap to make sure they are kept alive.
Definition: cereal.hpp:677
ArchiveType & processImpl(base_class< T > const &b)
Serialization of a base_class wrapper.
Definition: cereal.hpp:473
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
std::uint32_t registerClassVersion()
Registers a class version with the archive and serializes it if necessary.
Definition: cereal.hpp:596
std::uint32_t itsCurrentPointerId
The id to be given to the next pointer.
Definition: cereal.hpp:680
A wrapper around size metadata.
Definition: helpers.hpp:313
SizeTag< T > make_size_tag(T &&sz)
Creates a size tag from some variable.
Definition: cereal.hpp:96
static auto member_load(Archive &ar, T &t) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar))
Definition: access.hpp:257
static auto member_load_minimal(Archive const &ar, T &t, U &&u) -> decltype(t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward< U >(u)))
Definition: access.hpp:269
static auto member_save(Archive &ar, T const &t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
Definition: access.hpp:249
static auto member_serialize(Archive &ar, T &t) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar))
Definition: access.hpp:245
static auto member_save_minimal(Archive const &ar, T const &t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
Definition: access.hpp:261
Definition: helpers.hpp:282
Definition: helpers.hpp:270
static T & getInstance()
Definition: static_object.hpp:82
static LockGuard lock()
Attempts to lock this static object for the current scope.
Definition: static_object.hpp:110
Support common types - always included automatically.
uint d
Internal helper functionality.
Preprocessor macros that can customise the cereal library.
type
The type the bitset is encoded with.
Definition: bitset.hpp:44
static const uint32_t msb_32bit
Definition: helpers.hpp:298
in certain simple scenarios. They should probably not be used if maximizing performance is the main o...
Definition: access.hpp:42
std::enable_if< common_detail::is_enum< T >::value, typename common_detail::is_enum< T >::base_type >::type CEREAL_SAVE_MINIMAL_FUNCTION_NAME(Archive const &, T const &t)
Saving for enum types.
Definition: common.hpp:95
void epilogue(JSONOutputArchive &, NameValuePair< T > const &)
Epilogue for NVPs for JSON archives.
Definition: json.hpp:780
std::enable_if< std::is_arithmetic< T >::value, void >::type CEREAL_LOAD_FUNCTION_NAME(BinaryInputArchive &ar, T &t)
Loading for POD types from binary.
Definition: binary.hpp:126
CEREAL_SERIALIZE_FUNCTION_NAME(Archive &ar, NameValuePair< T > &t)
Serializing NVP types to binary.
Definition: binary.hpp:134
std::enable_if< std::is_arithmetic< T >::value, void >::type CEREAL_SAVE_FUNCTION_NAME(BinaryOutputArchive &ar, T const &t)
Saving for POD types to binary.
Definition: binary.hpp:118
Flags
Special flags for archives.
Definition: cereal.hpp:185
@ AllowEmptyClassElision
Definition: cereal.hpp:185
std::enable_if< common_detail::is_enum< T >::value, void >::type CEREAL_LOAD_MINIMAL_FUNCTION_NAME(Archive const &, T &&t, typename common_detail::is_enum< T >::base_type const &value)
Loading for enum types.
Definition: common.hpp:103
void prologue(JSONOutputArchive &, NameValuePair< T > const &)
Prologue for NVPs for JSON archives.
Definition: json.hpp:768
detail namespace with internal helper functions
Definition: json.hpp:260
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:6370
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1282
unsigned int uint32_t
Definition: stdint.h:126
A wrapper around data that can be serialized in a binary fashion.
Definition: helpers.hpp:212
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
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:49
Casts a derived class to its non-virtual base class in a way that safely supports abstract classes.
Definition: base_class.hpp:101
Base * base_ptr
Definition: base_class.hpp:110
Definition: traits.hpp:1339
Version information class.
Definition: helpers.hpp:402
Definition: traits.hpp:1146
The number of input serialization functions available.
Definition: traits.hpp:1134
The number of output serialization functions available.
Definition: traits.hpp:1107
Definition: traits.hpp:1139
Definition: traits.hpp:1112
Casts a derived class to its virtual base class in a way that allows cereal to track inheritance.
Definition: base_class.hpp:189
Base * base_ptr
Definition: base_class.hpp:198
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
static const detail::sfinae sfinae
Used as the default value for EnableIf and DisableIf template parameters.
Definition: traits.hpp:88