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 cereal 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 RANDOLPH VOORHIES OR SHANE GRANT 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 
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 
261  #define CEREAL_CLASS_VERSION(TYPE, VERSION_NUMBER) \
262  namespace cereal { namespace detail { \
263  template <> struct Version<TYPE> \
264  { \
265  static const std::uint32_t version; \
266  static std::uint32_t registerVersion() \
267  { \
268  ::cereal::detail::StaticObject<Versions>::getInstance().mapping.emplace( \
269  std::type_index(typeid(TYPE)).hash_code(), VERSION_NUMBER ); \
270  return VERSION_NUMBER; \
271  } \
272  CEREAL_UNUSED_FUNCTION \
273  }; /* end Version */ \
274  const std::uint32_t Version<TYPE>::version = \
275  Version<TYPE>::registerVersion(); \
276  } } // end namespaces
277 
278  // ######################################################################
280 
295  template<class ArchiveType, std::uint32_t Flags = 0>
297  {
298  public:
300 
301  OutputArchive(ArchiveType * const derived) : self(derived), itsCurrentPointerId(1), itsCurrentPolymorphicTypeId(1)
302  { }
303 
304  OutputArchive & operator=( OutputArchive const & ) = delete;
305 
307 
308  template <class ... Types> inline
309  ArchiveType & operator()( Types && ... args )
310  {
311  self->process( std::forward<Types>( args )... );
312  return *self;
313  }
314 
316 
318  {
319  for( auto & deferment : itsDeferments )
320  deferment();
321  }
322 
326 
329 
333  using is_loading = std::false_type;
334 
336 
340  using is_saving = std::true_type;
341 
343 
346  template <class T> inline
347  ArchiveType & operator&( T && arg )
348  {
349  self->process( std::forward<T>( arg ) );
350  return *self;
351  }
352 
354 
357  template <class T> inline
358  ArchiveType & operator<<( T && arg )
359  {
360  self->process( std::forward<T>( arg ) );
361  return *self;
362  }
363 
365 
367 
374  inline std::uint32_t registerSharedPointer( void const * addr )
375  {
376  // Handle null pointers by just returning 0
377  if(addr == 0) return 0;
378 
379  auto id = itsSharedPointerMap.find( addr );
380  if( id == itsSharedPointerMap.end() )
381  {
382  auto ptrId = itsCurrentPointerId++;
383  itsSharedPointerMap.insert( {addr, ptrId} );
384  return ptrId | detail::msb_32bit; // mask MSB to be 1
385  }
386  else
387  return id->second;
388  }
389 
391 
398  inline std::uint32_t registerPolymorphicType( char const * name )
399  {
400  auto id = itsPolymorphicTypeMap.find( name );
401  if( id == itsPolymorphicTypeMap.end() )
402  {
403  auto polyId = itsCurrentPolymorphicTypeId++;
404  itsPolymorphicTypeMap.insert( {name, polyId} );
405  return polyId | detail::msb_32bit; // mask MSB to be 1
406  }
407  else
408  return id->second;
409  }
410 
411  private:
413  template <class T> inline
414  void process( T && head )
415  {
416  prologue( *self, head );
417  self->processImpl( head );
418  epilogue( *self, head );
419  }
420 
422  template <class T, class ... Other> inline
423  void process( T && head, Other && ... tail )
424  {
425  self->process( std::forward<T>( head ) );
426  self->process( std::forward<Other>( tail )... );
427  }
428 
430 
431  template <class T> inline
432  ArchiveType & processImpl(virtual_base_class<T> const & b)
433  {
434  traits::detail::base_class_id id(b.base_ptr);
435  if(itsBaseClassSet.count(id) == 0)
436  {
437  itsBaseClassSet.insert(id);
438  self->processImpl( *b.base_ptr );
439  }
440  return *self;
441  }
442 
444 
445  template <class T> inline
446  ArchiveType & processImpl(base_class<T> const & b)
447  {
448  self->processImpl( *b.base_ptr );
449  return *self;
450  }
451 
452  std::vector<std::function<void(void)>> itsDeferments;
453 
454  template <class T> inline
455  ArchiveType & processImpl(DeferredData<T> const & d)
456  {
457  std::function<void(void)> deferment( [=](){ self->process( d.value ); } );
458  itsDeferments.emplace_back( std::move(deferment) );
459 
460  return *self;
461  }
462 
464 
470  #define PROCESS_IF(name) \
471  traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
472  !traits::has_invalid_output_versioning<T, ArchiveType>::value, \
473  (traits::is_output_serializable<T, ArchiveType>::value && \
474  (traits::is_specialized_##name<T, ArchiveType>::value || \
475  !traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae
476 
478  template <class T, PROCESS_IF(member_serialize)> inline
479  ArchiveType & processImpl(T const & t)
480  {
481  access::member_serialize(*self, const_cast<T &>(t));
482  return *self;
483  }
484 
486  template <class T, PROCESS_IF(non_member_serialize)> inline
487  ArchiveType & processImpl(T const & t)
488  {
489  CEREAL_SERIALIZE_FUNCTION_NAME(*self, const_cast<T &>(t));
490  return *self;
491  }
492 
494  template <class T, PROCESS_IF(member_save)> inline
495  ArchiveType & processImpl(T const & t)
496  {
497  access::member_save(*self, t);
498  return *self;
499  }
500 
502  template <class T, PROCESS_IF(non_member_save)> inline
503  ArchiveType & processImpl(T const & t)
504  {
505  CEREAL_SAVE_FUNCTION_NAME(*self, t);
506  return *self;
507  }
508 
510  template <class T, PROCESS_IF(member_save_minimal)> inline
511  ArchiveType & processImpl(T const & t)
512  {
513  self->process( access::member_save_minimal(*self, t) );
514  return *self;
515  }
516 
518  template <class T, PROCESS_IF(non_member_save_minimal)> inline
519  ArchiveType & processImpl(T const & t)
520  {
521  self->process( CEREAL_SAVE_MINIMAL_FUNCTION_NAME(*self, t) );
522  return *self;
523  }
524 
526  template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
527  !traits::is_output_serializable<T, ArchiveType>::value,
528  std::is_empty<T>::value> = traits::sfinae> inline
529  ArchiveType & processImpl(T const &)
530  {
531  return *self;
532  }
533 
535 
538  template <class T, traits::EnableIf<traits::has_invalid_output_versioning<T, ArchiveType>::value ||
539  (!traits::is_output_serializable<T, ArchiveType>::value &&
540  (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
541  ArchiveType & processImpl(T const &)
542  {
543  static_assert(traits::detail::count_output_serializers<T, ArchiveType>::value != 0,
544  "cereal could not find any output serialization functions for the provided type and archive combination. \n\n "
545  "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
546  "Serialize functions generally have the following signature: \n\n "
547  "template<class Archive> \n "
548  " void serialize(Archive & ar) \n "
549  " { \n "
550  " ar( member1, member2, member3 ); \n "
551  " } \n\n " );
552 
553  static_assert(traits::detail::count_output_serializers<T, ArchiveType>::value < 2,
554  "cereal found more than one compatible output serialization function for the provided type and archive combination. \n\n "
555  "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
556  "Use specialization (see access.hpp) if you need to disambiguate between serialize vs load/save functions. \n "
557  "Note that serialization functions can be inherited which may lead to the aforementioned ambiguities. \n "
558  "In addition, you may not mix versioned with non-versioned serialization functions. \n\n ");
559 
560  return *self;
561  }
562 
564 
568  template <class T> inline
569  std::uint32_t registerClassVersion()
570  {
571  static const auto hash = std::type_index(typeid(T)).hash_code();
572  const auto insertResult = itsVersionedTypes.insert( hash );
574  const auto version =
575  detail::StaticObject<detail::Versions>::getInstance().find( hash, detail::Version<T>::version );
576 
577  if( insertResult.second ) // insertion took place, serialize the version number
578  process( make_nvp<ArchiveType>("cereal_class_version", version) );
579 
580  return version;
581  }
582 
584 
585  template <class T, PROCESS_IF(member_versioned_serialize)> inline
586  ArchiveType & processImpl(T const & t)
587  {
588  access::member_serialize(*self, const_cast<T &>(t), registerClassVersion<T>());
589  return *self;
590  }
591 
593 
594  template <class T, PROCESS_IF(non_member_versioned_serialize)> inline
595  ArchiveType & processImpl(T const & t)
596  {
597  CEREAL_SERIALIZE_FUNCTION_NAME(*self, const_cast<T &>(t), registerClassVersion<T>());
598  return *self;
599  }
600 
602 
603  template <class T, PROCESS_IF(member_versioned_save)> inline
604  ArchiveType & processImpl(T const & t)
605  {
606  access::member_save(*self, t, registerClassVersion<T>());
607  return *self;
608  }
609 
611 
612  template <class T, PROCESS_IF(non_member_versioned_save)> inline
613  ArchiveType & processImpl(T const & t)
614  {
615  CEREAL_SAVE_FUNCTION_NAME(*self, t, registerClassVersion<T>());
616  return *self;
617  }
618 
620 
621  template <class T, PROCESS_IF(member_versioned_save_minimal)> inline
622  ArchiveType & processImpl(T const & t)
623  {
624  self->process( access::member_save_minimal(*self, t, registerClassVersion<T>()) );
625  return *self;
626  }
627 
629 
630  template <class T, PROCESS_IF(non_member_versioned_save_minimal)> inline
631  ArchiveType & processImpl(T const & t)
632  {
633  self->process( CEREAL_SAVE_MINIMAL_FUNCTION_NAME(*self, t, registerClassVersion<T>()) );
634  return *self;
635  }
636 
637  #undef PROCESS_IF
638 
639  private:
640  ArchiveType * const self;
641 
643  std::unordered_set<traits::detail::base_class_id, traits::detail::base_class_id_hash> itsBaseClassSet;
644 
646  std::unordered_map<void const *, std::uint32_t> itsSharedPointerMap;
647 
649  std::uint32_t itsCurrentPointerId;
650 
652  std::unordered_map<char const *, std::uint32_t> itsPolymorphicTypeMap;
653 
655  std::uint32_t itsCurrentPolymorphicTypeId;
656 
658  std::unordered_set<size_type> itsVersionedTypes;
659  }; // class OutputArchive
660 
661  // ######################################################################
663 
678  template<class ArchiveType, std::uint32_t Flags = 0>
680  {
681  public:
683 
684  InputArchive(ArchiveType * const derived) :
685  self(derived),
686  itsBaseClassSet(),
687  itsSharedPointerMap(),
688  itsPolymorphicTypeMap(),
689  itsVersionedTypes()
690  { }
691 
692  InputArchive & operator=( InputArchive const & ) = delete;
693 
695 
696  template <class ... Types> inline
697  ArchiveType & operator()( Types && ... args )
698  {
699  process( std::forward<Types>( args )... );
700  return *self;
701  }
702 
704 
706  {
707  for( auto & deferment : itsDeferments )
708  deferment();
709  }
710 
714 
717 
721  using is_loading = std::true_type;
722 
724 
728  using is_saving = std::false_type;
729 
731 
734  template <class T> inline
735  ArchiveType & operator&( T && arg )
736  {
737  self->process( std::forward<T>( arg ) );
738  return *self;
739  }
740 
742 
745  template <class T> inline
746  ArchiveType & operator>>( T && arg )
747  {
748  self->process( std::forward<T>( arg ) );
749  return *self;
750  }
751 
753 
755 
762  inline std::shared_ptr<void> getSharedPointer(std::uint32_t const id)
763  {
764  if(id == 0) return std::shared_ptr<void>(nullptr);
765 
766  auto iter = itsSharedPointerMap.find( id );
767  if(iter == itsSharedPointerMap.end())
768  throw Exception("Error while trying to deserialize a smart pointer. Could not find id " + std::to_string(id));
769 
770  return iter->second;
771  }
772 
774 
780  inline void registerSharedPointer(std::uint32_t const id, std::shared_ptr<void> ptr)
781  {
782  std::uint32_t const stripped_id = id & ~detail::msb_32bit;
783  itsSharedPointerMap[stripped_id] = ptr;
784  }
785 
787 
793  inline std::string getPolymorphicName(std::uint32_t const id)
794  {
795  auto name = itsPolymorphicTypeMap.find( id );
796  if(name == itsPolymorphicTypeMap.end())
797  {
798  throw Exception("Error while trying to deserialize a polymorphic pointer. Could not find type id " + std::to_string(id));
799  }
800  return name->second;
801  }
802 
804 
810  inline void registerPolymorphicName(std::uint32_t const id, std::string const & name)
811  {
812  std::uint32_t const stripped_id = id & ~detail::msb_32bit;
813  itsPolymorphicTypeMap.insert( {stripped_id, name} );
814  }
815 
816  private:
818  template <class T> inline
819  void process( T && head )
820  {
821  prologue( *self, head );
822  self->processImpl( head );
823  epilogue( *self, head );
824  }
825 
827  template <class T, class ... Other> inline
828  void process( T && head, Other && ... tail )
829  {
830  process( std::forward<T>( head ) );
831  process( std::forward<Other>( tail )... );
832  }
833 
835 
836  template <class T> inline
837  ArchiveType & processImpl(virtual_base_class<T> & b)
838  {
839  traits::detail::base_class_id id(b.base_ptr);
840  if(itsBaseClassSet.count(id) == 0)
841  {
842  itsBaseClassSet.insert(id);
843  self->processImpl( *b.base_ptr );
844  }
845  return *self;
846  }
847 
849 
850  template <class T> inline
851  ArchiveType & processImpl(base_class<T> & b)
852  {
853  self->processImpl( *b.base_ptr );
854  return *self;
855  }
856 
857  std::vector<std::function<void(void)>> itsDeferments;
858 
859  template <class T> inline
860  ArchiveType & processImpl(DeferredData<T> const & d)
861  {
862  std::function<void(void)> deferment( [=](){ self->process( d.value ); } );
863  itsDeferments.emplace_back( std::move(deferment) );
864 
865  return *self;
866  }
867 
869 
875  #define PROCESS_IF(name) \
876  traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
877  !traits::has_invalid_input_versioning<T, ArchiveType>::value, \
878  (traits::is_input_serializable<T, ArchiveType>::value && \
879  (traits::is_specialized_##name<T, ArchiveType>::value || \
880  !traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae
881 
883  template <class T, PROCESS_IF(member_serialize)> inline
884  ArchiveType & processImpl(T & t)
885  {
886  access::member_serialize(*self, t);
887  return *self;
888  }
889 
891  template <class T, PROCESS_IF(non_member_serialize)> inline
892  ArchiveType & processImpl(T & t)
893  {
895  return *self;
896  }
897 
899  template <class T, PROCESS_IF(member_load)> inline
900  ArchiveType & processImpl(T & t)
901  {
902  access::member_load(*self, t);
903  return *self;
904  }
905 
907  template <class T, PROCESS_IF(non_member_load)> inline
908  ArchiveType & processImpl(T & t)
909  {
910  CEREAL_LOAD_FUNCTION_NAME(*self, t);
911  return *self;
912  }
913 
915  template <class T, PROCESS_IF(member_load_minimal)> inline
916  ArchiveType & processImpl(T & t)
917  {
918  using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
919  typename traits::has_member_save_minimal<T, OutArchiveType>::type value;
920  self->process( value );
921  access::member_load_minimal(*self, t, value);
922  return *self;
923  }
924 
926  template <class T, PROCESS_IF(non_member_load_minimal)> inline
927  ArchiveType & processImpl(T & t)
928  {
929  using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
930  typename traits::has_non_member_save_minimal<T, OutArchiveType>::type value;
931  self->process( value );
932  CEREAL_LOAD_MINIMAL_FUNCTION_NAME(*self, t, value);
933  return *self;
934  }
935 
937  template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
938  !traits::is_input_serializable<T, ArchiveType>::value,
939  std::is_empty<T>::value> = traits::sfinae> inline
940  ArchiveType & processImpl(T const &)
941  {
942  return *self;
943  }
944 
946 
949  template <class T, traits::EnableIf<traits::has_invalid_input_versioning<T, ArchiveType>::value ||
950  (!traits::is_input_serializable<T, ArchiveType>::value &&
951  (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
952  ArchiveType & processImpl(T const &)
953  {
954  static_assert(traits::detail::count_input_serializers<T, ArchiveType>::value != 0,
955  "cereal could not find any input serialization functions for the provided type and archive combination. \n\n "
956  "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
957  "Serialize functions generally have the following signature: \n\n "
958  "template<class Archive> \n "
959  " void serialize(Archive & ar) \n "
960  " { \n "
961  " ar( member1, member2, member3 ); \n "
962  " } \n\n " );
963 
964  static_assert(traits::detail::count_input_serializers<T, ArchiveType>::value < 2,
965  "cereal found more than one compatible input serialization function for the provided type and archive combination. \n\n "
966  "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
967  "Use specialization (see access.hpp) if you need to disambiguate between serialize vs load/save functions. \n "
968  "Note that serialization functions can be inherited which may lead to the aforementioned ambiguities. \n "
969  "In addition, you may not mix versioned with non-versioned serialization functions. \n\n ");
970 
971  return *self;
972  }
973 
975  template <class A, class B, bool C, bool D, bool E, bool F> friend struct detail::Construct;
976 
978 
982  template <class T> inline
983  std::uint32_t loadClassVersion()
984  {
985  static const auto hash = std::type_index(typeid(T)).hash_code();
986  auto lookupResult = itsVersionedTypes.find( hash );
987 
988  if( lookupResult != itsVersionedTypes.end() ) // already exists
989  return lookupResult->second;
990  else // need to load
991  {
992  std::uint32_t version;
993 
994  process( make_nvp<ArchiveType>("cereal_class_version", version) );
995  itsVersionedTypes.emplace_hint( lookupResult, hash, version );
996 
997  return version;
998  }
999  }
1000 
1002 
1003  template <class T, PROCESS_IF(member_versioned_serialize)> inline
1004  ArchiveType & processImpl(T & t)
1005  {
1006  const auto version = loadClassVersion<T>();
1007  access::member_serialize(*self, t, version);
1008  return *self;
1009  }
1010 
1012 
1013  template <class T, PROCESS_IF(non_member_versioned_serialize)> inline
1014  ArchiveType & processImpl(T & t)
1015  {
1016  const auto version = loadClassVersion<T>();
1017  CEREAL_SERIALIZE_FUNCTION_NAME(*self, t, version);
1018  return *self;
1019  }
1020 
1022 
1023  template <class T, PROCESS_IF(member_versioned_load)> inline
1024  ArchiveType & processImpl(T & t)
1025  {
1026  const auto version = loadClassVersion<T>();
1027  access::member_load(*self, t, version);
1028  return *self;
1029  }
1030 
1032 
1033  template <class T, PROCESS_IF(non_member_versioned_load)> inline
1034  ArchiveType & processImpl(T & t)
1035  {
1036  const auto version = loadClassVersion<T>();
1037  CEREAL_LOAD_FUNCTION_NAME(*self, t, version);
1038  return *self;
1039  }
1040 
1042 
1043  template <class T, PROCESS_IF(member_versioned_load_minimal)> inline
1044  ArchiveType & processImpl(T & t)
1045  {
1046  using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
1047  const auto version = loadClassVersion<T>();
1048  typename traits::has_member_versioned_save_minimal<T, OutArchiveType>::type value;
1049  self->process(value);
1050  access::member_load_minimal(*self, t, value, version);
1051  return *self;
1052  }
1053 
1055 
1056  template <class T, PROCESS_IF(non_member_versioned_load_minimal)> inline
1057  ArchiveType & processImpl(T & t)
1058  {
1059  using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
1060  const auto version = loadClassVersion<T>();
1061  typename traits::has_non_member_versioned_save_minimal<T, OutArchiveType>::type value;
1062  self->process(value);
1063  CEREAL_LOAD_MINIMAL_FUNCTION_NAME(*self, t, value, version);
1064  return *self;
1065  }
1066 
1067  #undef PROCESS_IF
1068 
1069  private:
1070  ArchiveType * const self;
1071 
1073  std::unordered_set<traits::detail::base_class_id, traits::detail::base_class_id_hash> itsBaseClassSet;
1074 
1076  std::unordered_map<std::uint32_t, std::shared_ptr<void>> itsSharedPointerMap;
1077 
1079  std::unordered_map<std::uint32_t, std::string> itsPolymorphicTypeMap;
1080 
1082  std::unordered_map<std::size_t, std::uint32_t> itsVersionedTypes;
1083  }; // class InputArchive
1084 } // namespace cereal
1085 
1086 // This include needs to come after things such as binary_data, make_nvp, etc
1087 #include "cereal/types/common.hpp"
1088 
1089 #endif // CEREAL_CEREAL_HPP_
cereal::InputArchive
The base input archive class.
Definition: cereal.hpp:679
cereal::epilogue
void epilogue(Archive &, T const &)
Definition: cereal.hpp:169
cereal::InputArchive::getSharedPointer
std::shared_ptr< void > getSharedPointer(std::uint32_t const id)
Retrieves a shared pointer given a unique key for it.
Definition: cereal.hpp:762
cereal::OutputArchive< JSONOutputArchive >::is_saving
std::true_type is_saving
Indicates this archive is intended for saving.
Definition: cereal.hpp:340
cereal::detail::OutputArchiveBase
Definition: helpers.hpp:269
cereal::InputArchive::operator()
ArchiveType & operator()(Types &&... args)
Serializes all passed in data.
Definition: cereal.hpp:697
cereal::InputArchive::InputArchive
InputArchive(ArchiveType *const derived)
Construct the output archive.
Definition: cereal.hpp:684
cereal::InputArchive::serializeDeferments
void serializeDeferments()
Serializes any data marked for deferment using defer.
Definition: cereal.hpp:705
common.hpp
Support common types - always included automatically.
cereal::OutputArchive< JSONOutputArchive >::is_loading
std::false_type is_loading
Indicates this archive is not intended for loading.
Definition: cereal.hpp:333
helpers.hpp
Internal helper functionality.
cereal::InputArchive::getPolymorphicName
std::string getPolymorphicName(std::uint32_t const id)
Retrieves the string for a polymorphic type given a unique key for it.
Definition: cereal.hpp:793
cereal::OutputArchive::serializeDeferments
void serializeDeferments()
Serializes any data marked for deferment using defer.
Definition: cereal.hpp:317
CEREAL_SERIALIZE_FUNCTION_NAME
#define CEREAL_SERIALIZE_FUNCTION_NAME
The serialization/deserialization function name to search for.
Definition: macros.hpp:78
cereal::prologue
void prologue(Archive &, T const &)
Definition: cereal.hpp:162
cereal::OutputArchive::operator&
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:347
CEREAL_SAVE_MINIMAL_FUNCTION_NAME
#define CEREAL_SAVE_MINIMAL_FUNCTION_NAME
The serialization (save_minimal) function name to search for.
Definition: macros.hpp:106
cereal::NameValuePair::make_nvp
NameValuePair< T > make_nvp(const char *name, T &&value)
Creates a name value pair.
Definition: cereal.hpp:64
cereal::OutputArchive::registerPolymorphicType
std::uint32_t registerPolymorphicType(char const *name)
Registers a polymorphic type name with the archive.
Definition: cereal.hpp:398
macros.hpp
Preprocessor macros that can customise the cereal library.
CEREAL_LOAD_FUNCTION_NAME
#define CEREAL_LOAD_FUNCTION_NAME
The deserialization (load) function name to search for.
Definition: macros.hpp:85
cereal::detail::Construct
Definition: traits.hpp:1338
cereal::Flags
Flags
Special flags for archives.
Definition: cereal.hpp:185
cereal::detail::StaticObject::lock
static LockGuard lock()
Attempts to lock this static object for the current scope.
Definition: static_object.hpp:109
cereal::NameValuePair
For holding name value pairs.
Definition: helpers.hpp:139
cereal::DeferredData::defer
DeferredData< T > defer(T &&value)
Marks data for deferred serialization.
Definition: cereal.hpp:149
cereal::InputArchive< PortableBinaryInputArchive, AllowEmptyClassElision >::is_loading
std::true_type is_loading
Indicates this archive is intended for loading.
Definition: cereal.hpp:721
base_class.hpp
Support for base classes (virtual and non-virtual)
cereal::OutputArchive
The base output archive class.
Definition: cereal.hpp:296
cereal::InputArchive::registerSharedPointer
void registerSharedPointer(std::uint32_t const id, std::shared_ptr< void > ptr)
Registers a shared pointer to its unique identifier.
Definition: cereal.hpp:780
CEREAL_SAVE_FUNCTION_NAME
#define CEREAL_SAVE_FUNCTION_NAME
The serialization (save) function name to search for.
Definition: macros.hpp:92
cereal::SizeTag::make_size_tag
SizeTag< T > make_size_tag(T &&sz)
Creates a size tag from some variable.
Definition: cereal.hpp:96
cereal::BinaryData
A wrapper around data that can be serialized in a binary fashion.
Definition: helpers.hpp:211
cereal::OutputArchive::registerSharedPointer
std::uint32_t registerSharedPointer(void const *addr)
Registers a shared pointer with the archive.
Definition: cereal.hpp:374
cereal::OutputArchive::operator<<
ArchiveType & operator<<(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:358
EnableIf
typename detail::EnableIfHelper< Conditions... >::type EnableIf
Provides a way to enable a function if conditions are met.
Definition: traits.hpp:116
cereal::OutputArchive::OutputArchive
OutputArchive(ArchiveType *const derived)
Construct the output archive.
Definition: cereal.hpp:301
cereal::SizeTag
A wrapper around size metadata.
Definition: helpers.hpp:312
cereal::Exception
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:48
CEREAL_LOAD_MINIMAL_FUNCTION_NAME
#define CEREAL_LOAD_MINIMAL_FUNCTION_NAME
The deserialization (load_minimal) function name to search for.
Definition: macros.hpp:99
cereal::DeferredData
A wrapper around data that should be serialized after all non-deferred data.
Definition: helpers.hpp:232
cereal::InputArchive::operator&
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:735
cereal::detail::InputArchiveBase
Definition: helpers.hpp:281
cereal::NameValuePair::make_nvp
NameValuePair< T > make_nvp(std::string const &name, T &&value)
Creates a name value pair.
Definition: cereal.hpp:55
traits.hpp
Internal type trait support.
cereal::OutputArchive::operator()
ArchiveType & operator()(Types &&... args)
Serializes all passed in data.
Definition: cereal.hpp:309
cereal::BinaryData::binary_data
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
cereal::InputArchive::registerPolymorphicName
void registerPolymorphicName(std::uint32_t const id, std::string const &name)
Registers a polymorphic name string to its unique identifier.
Definition: cereal.hpp:810
cereal::InputArchive::operator>>
ArchiveType & operator>>(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:746
cereal::InputArchive< PortableBinaryInputArchive, AllowEmptyClassElision >::is_saving
std::false_type is_saving
Indicates this archive is not intended for saving.
Definition: cereal.hpp:728