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 <unordered_map>
36 #include <unordered_set>
37 #include <vector>
38 #include <cstddef>
39 #include <cstdint>
40 #include <functional>
41 
42 #include "cereal/macros.hpp"
46 
47 namespace cereal
48 {
49  // ######################################################################
51 
53  template <class T> inline
54  NameValuePair<T> make_nvp( std::string const & name, T && value )
55  {
56  return {name.c_str(), std::forward<T>(value)};
57  }
58 
60 
62  template <class T> inline
63  NameValuePair<T> make_nvp( const char * name, T && value )
64  {
65  return {name, std::forward<T>(value)};
66  }
67 
69 
71  #define CEREAL_NVP(T) ::cereal::make_nvp(#T, T)
72 
73  // ######################################################################
75 
79  template <class T> inline
80  BinaryData<T> binary_data( T && data, size_t size )
81  {
82  return {std::forward<T>(data), size};
83  }
84 
85  // ######################################################################
87 
94  template <class T> inline
96  {
97  return {std::forward<T>(sz)};
98  }
99 
100  // ######################################################################
103 
107  template <class Archive, class T> inline
108  void prologue( Archive & /* archive */, T const & /* data */)
109  { }
110 
113 
114  template <class Archive, class T> inline
115  void epilogue( Archive & /* archive */, T const & /* data */)
116  { }
117 
118  // ######################################################################
120 
131  enum Flags { AllowEmptyClassElision = 1 };
132 
133  // ######################################################################
135 
141  #define CEREAL_REGISTER_ARCHIVE(Archive) \
142  namespace cereal { namespace detail { \
143  template <class T, class BindingTag> \
144  typename polymorphic_serialization_support<Archive, T>::type \
145  instantiate_polymorphic_binding( T*, Archive*, BindingTag, adl_tag ); \
146  } } /* end namespaces */
147 
148  // ######################################################################
150 
199  #define CEREAL_CLASS_VERSION(TYPE, VERSION_NUMBER) \
200  namespace cereal { namespace detail { \
201  template <> struct Version<TYPE> \
202  { \
203  static const std::uint32_t version; \
204  static std::uint32_t registerVersion() \
205  { \
206  ::cereal::detail::StaticObject<Versions>::getInstance().mapping.emplace( \
207  std::type_index(typeid(TYPE)).hash_code(), VERSION_NUMBER ); \
208  return VERSION_NUMBER; \
209  } \
210  static void unused() { (void)version; } \
211  }; /* end Version */ \
212  const std::uint32_t Version<TYPE>::version = \
213  Version<TYPE>::registerVersion(); \
214  } } // end namespaces
215 
216  // ######################################################################
218 
233  template<class ArchiveType, std::uint32_t Flags = 0>
235  {
236  public:
238 
239  OutputArchive(ArchiveType * const derived) : self(derived), itsCurrentPointerId(1), itsCurrentPolymorphicTypeId(1)
240  { }
241 
242  OutputArchive & operator=( OutputArchive const & ) = delete;
243 
245 
246  template <class ... Types> inline
247  ArchiveType & operator()( Types && ... args )
248  {
249  self->process( std::forward<Types>( args )... );
250  return *self;
251  }
252 
256 
259 
263  using is_loading = std::false_type;
264 
266 
270  using is_saving = std::true_type;
271 
273 
276  template <class T> inline
277  ArchiveType & operator&( T && arg )
278  {
279  self->process( std::forward<T>( arg ) );
280  return *self;
281  }
282 
284 
287  template <class T> inline
288  ArchiveType & operator<<( T && arg )
289  {
290  self->process( std::forward<T>( arg ) );
291  return *self;
292  }
293 
295 
297 
304  inline std::uint32_t registerSharedPointer( void const * addr )
305  {
306  // Handle null pointers by just returning 0
307  if(addr == 0) return 0;
308 
309  auto id = itsSharedPointerMap.find( addr );
310  if( id == itsSharedPointerMap.end() )
311  {
312  auto ptrId = itsCurrentPointerId++;
313  itsSharedPointerMap.insert( {addr, ptrId} );
314  return ptrId | detail::msb_32bit; // mask MSB to be 1
315  }
316  else
317  return id->second;
318  }
319 
321 
328  inline std::uint32_t registerPolymorphicType( char const * name )
329  {
330  auto id = itsPolymorphicTypeMap.find( name );
331  if( id == itsPolymorphicTypeMap.end() )
332  {
333  auto polyId = itsCurrentPolymorphicTypeId++;
334  itsPolymorphicTypeMap.insert( {name, polyId} );
335  return polyId | detail::msb_32bit; // mask MSB to be 1
336  }
337  else
338  return id->second;
339  }
340 
341  private:
343  template <class T> inline
344  void process( T && head )
345  {
346  prologue( *self, head );
347  self->processImpl( head );
348  epilogue( *self, head );
349  }
350 
352  template <class T, class ... Other> inline
353  void process( T && head, Other && ... tail )
354  {
355  self->process( std::forward<T>( head ) );
356  self->process( std::forward<Other>( tail )... );
357  }
358 
360 
361  template <class T> inline
362  ArchiveType & processImpl(virtual_base_class<T> const & b)
363  {
364  traits::detail::base_class_id id(b.base_ptr);
365  if(itsBaseClassSet.count(id) == 0)
366  {
367  itsBaseClassSet.insert(id);
368  self->processImpl( *b.base_ptr );
369  }
370  return *self;
371  }
372 
374 
375  template <class T> inline
376  ArchiveType & processImpl(base_class<T> const & b)
377  {
378  self->processImpl( *b.base_ptr );
379  return *self;
380  }
381 
383 
389  #define PROCESS_IF(name) \
390  traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
391  !traits::has_invalid_output_versioning<T, ArchiveType>::value, \
392  (traits::is_output_serializable<T, ArchiveType>::value && \
393  (traits::is_specialized_##name<T, ArchiveType>::value || \
394  !traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae
395 
397  template <class T, PROCESS_IF(member_serialize)> inline
398  ArchiveType & processImpl(T const & t)
399  {
400  access::member_serialize(*self, const_cast<T &>(t));
401  return *self;
402  }
403 
405  template <class T, PROCESS_IF(non_member_serialize)> inline
406  ArchiveType & processImpl(T const & t)
407  {
408  CEREAL_SERIALIZE_FUNCTION_NAME(*self, const_cast<T &>(t));
409  return *self;
410  }
411 
413  template <class T, PROCESS_IF(member_save)> inline
414  ArchiveType & processImpl(T const & t)
415  {
416  access::member_save(*self, t);
417  return *self;
418  }
419 
421  template <class T, PROCESS_IF(non_member_save)> inline
422  ArchiveType & processImpl(T const & t)
423  {
424  CEREAL_SAVE_FUNCTION_NAME(*self, t);
425  return *self;
426  }
427 
429  template <class T, PROCESS_IF(member_save_minimal)> inline
430  ArchiveType & processImpl(T const & t)
431  {
432  self->process( access::member_save_minimal(*self, t) );
433  return *self;
434  }
435 
437  template <class T, PROCESS_IF(non_member_save_minimal)> inline
438  ArchiveType & processImpl(T const & t)
439  {
440  self->process( CEREAL_SAVE_MINIMAL_FUNCTION_NAME(*self, t) );
441  return *self;
442  }
443 
445  template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
446  !traits::is_output_serializable<T, ArchiveType>::value,
447  std::is_empty<T>::value> = traits::sfinae> inline
448  ArchiveType & processImpl(T const &)
449  {
450  return *self;
451  }
452 
454 
457  template <class T, traits::EnableIf<traits::has_invalid_output_versioning<T, ArchiveType>::value ||
458  (!traits::is_output_serializable<T, ArchiveType>::value &&
459  (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
460  ArchiveType & processImpl(T const &)
461  {
462  static_assert(traits::detail::count_output_serializers<T, ArchiveType>::value != 0,
463  "cereal could not find any output serialization functions for the provided type and archive combination. \n\n "
464  "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
465  "Serialize functions generally have the following signature: \n\n "
466  "template<class Archive> \n "
467  " void serialize(Archive & ar) \n "
468  " { \n "
469  " ar( member1, member2, member3 ); \n "
470  " } \n\n " );
471 
472  static_assert(traits::detail::count_output_serializers<T, ArchiveType>::value < 2,
473  "cereal found more than one compatible output serialization function for the provided type and archive combination. \n\n "
474  "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
475  "Use specialization (see access.hpp) if you need to disambiguate between serialize vs load/save functions. \n "
476  "Note that serialization functions can be inherited which may lead to the aforementioned ambiguities. \n "
477  "In addition, you may not mix versioned with non-versioned serialization functions. \n\n ");
478 
479  return *self;
480  }
481 
483 
488  template <class T> inline
489  std::uint32_t registerClassVersion()
490  {
491  static const auto hash = std::type_index(typeid(T)).hash_code();
492  const auto insertResult = itsVersionedTypes.insert( hash );
494  const auto version =
495  detail::StaticObject<detail::Versions>::getInstance().find( hash, detail::Version<T>::version );
496 
497  if( insertResult.second ) // insertion took place, serialize the version number
498  process( make_nvp<ArchiveType>("cereal_class_version", version) );
499 
500  return version;
501  }
502 
504 
505  template <class T, PROCESS_IF(member_versioned_serialize)> inline
506  ArchiveType & processImpl(T const & t)
507  {
508  access::member_serialize(*self, const_cast<T &>(t), registerClassVersion<T>());
509  return *self;
510  }
511 
513 
514  template <class T, PROCESS_IF(non_member_versioned_serialize)> inline
515  ArchiveType & processImpl(T const & t)
516  {
517  CEREAL_SERIALIZE_FUNCTION_NAME(*self, const_cast<T &>(t), registerClassVersion<T>());
518  return *self;
519  }
520 
522 
523  template <class T, PROCESS_IF(member_versioned_save)> inline
524  ArchiveType & processImpl(T const & t)
525  {
526  access::member_save(*self, t, registerClassVersion<T>());
527  return *self;
528  }
529 
531 
532  template <class T, PROCESS_IF(non_member_versioned_save)> inline
533  ArchiveType & processImpl(T const & t)
534  {
535  CEREAL_SAVE_FUNCTION_NAME(*self, t, registerClassVersion<T>());
536  return *self;
537  }
538 
540 
541  template <class T, PROCESS_IF(member_versioned_save_minimal)> inline
542  ArchiveType & processImpl(T const & t)
543  {
544  self->process( access::member_save_minimal(*self, t, registerClassVersion<T>()) );
545  return *self;
546  }
547 
549 
550  template <class T, PROCESS_IF(non_member_versioned_save_minimal)> inline
551  ArchiveType & processImpl(T const & t)
552  {
553  self->process( CEREAL_SAVE_MINIMAL_FUNCTION_NAME(*self, t, registerClassVersion<T>()) );
554  return *self;
555  }
556 
557  #undef PROCESS_IF
558 
559  private:
560  ArchiveType * const self;
561 
563  std::unordered_set<traits::detail::base_class_id, traits::detail::base_class_id_hash> itsBaseClassSet;
564 
566  std::unordered_map<void const *, std::uint32_t> itsSharedPointerMap;
567 
569  std::uint32_t itsCurrentPointerId;
570 
572  std::unordered_map<char const *, std::uint32_t> itsPolymorphicTypeMap;
573 
575  std::uint32_t itsCurrentPolymorphicTypeId;
576 
578  std::unordered_set<size_type> itsVersionedTypes;
579  }; // class OutputArchive
580 
581  // ######################################################################
583 
598  template<class ArchiveType, std::uint32_t Flags = 0>
600  {
601  public:
603 
604  InputArchive(ArchiveType * const derived) :
605  self(derived),
606  itsBaseClassSet(),
607  itsSharedPointerMap(),
608  itsPolymorphicTypeMap(),
609  itsVersionedTypes()
610  { }
611 
612  InputArchive & operator=( InputArchive const & ) = delete;
613 
615 
616  template <class ... Types> inline
617  ArchiveType & operator()( Types && ... args )
618  {
619  process( std::forward<Types>( args )... );
620  return *self;
621  }
622 
626 
629 
633  using is_loading = std::true_type;
634 
636 
640  using is_saving = std::false_type;
641 
643 
646  template <class T> inline
647  ArchiveType & operator&( T && arg )
648  {
649  self->process( std::forward<T>( arg ) );
650  return *self;
651  }
652 
654 
657  template <class T> inline
658  ArchiveType & operator>>( T && arg )
659  {
660  self->process( std::forward<T>( arg ) );
661  return *self;
662  }
663 
665 
667 
673  inline std::shared_ptr<void> getSharedPointer(std::uint32_t const id)
674  {
675  if(id == 0) return std::shared_ptr<void>(nullptr);
676 
677  auto iter = itsSharedPointerMap.find( id );
678  if(iter == itsSharedPointerMap.end())
679  throw Exception("Error while trying to deserialize a smart pointer. Could not find id " + std::to_string(id));
680 
681  return iter->second;
682  }
683 
685 
690  inline void registerSharedPointer(std::uint32_t const id, std::shared_ptr<void> ptr)
691  {
692  std::uint32_t const stripped_id = id & ~detail::msb_32bit;
693  itsSharedPointerMap[stripped_id] = ptr;
694  }
695 
697 
702  inline std::string getPolymorphicName(std::uint32_t const id)
703  {
704  auto name = itsPolymorphicTypeMap.find( id );
705  if(name == itsPolymorphicTypeMap.end())
706  {
707  throw Exception("Error while trying to deserialize a polymorphic pointer. Could not find type id " + std::to_string(id));
708  }
709  return name->second;
710  }
711 
713 
718  inline void registerPolymorphicName(std::uint32_t const id, std::string const & name)
719  {
720  std::uint32_t const stripped_id = id & ~detail::msb_32bit;
721  itsPolymorphicTypeMap.insert( {stripped_id, name} );
722  }
723 
724  private:
726  template <class T> inline
727  void process( T && head )
728  {
729  prologue( *self, head );
730  self->processImpl( head );
731  epilogue( *self, head );
732  }
733 
735  template <class T, class ... Other> inline
736  void process( T && head, Other && ... tail )
737  {
738  process( std::forward<T>( head ) );
739  process( std::forward<Other>( tail )... );
740  }
741 
743 
744  template <class T> inline
745  ArchiveType & processImpl(virtual_base_class<T> & b)
746  {
747  traits::detail::base_class_id id(b.base_ptr);
748  if(itsBaseClassSet.count(id) == 0)
749  {
750  itsBaseClassSet.insert(id);
751  self->processImpl( *b.base_ptr );
752  }
753  return *self;
754  }
755 
757 
758  template <class T> inline
759  ArchiveType & processImpl(base_class<T> & b)
760  {
761  self->processImpl( *b.base_ptr );
762  return *self;
763  }
764 
766 
772  #define PROCESS_IF(name) \
773  traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
774  !traits::has_invalid_input_versioning<T, ArchiveType>::value, \
775  (traits::is_input_serializable<T, ArchiveType>::value && \
776  (traits::is_specialized_##name<T, ArchiveType>::value || \
777  !traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae
778 
780  template <class T, PROCESS_IF(member_serialize)> inline
781  ArchiveType & processImpl(T & t)
782  {
783  access::member_serialize(*self, t);
784  return *self;
785  }
786 
788  template <class T, PROCESS_IF(non_member_serialize)> inline
789  ArchiveType & processImpl(T & t)
790  {
792  return *self;
793  }
794 
796  template <class T, PROCESS_IF(member_load)> inline
797  ArchiveType & processImpl(T & t)
798  {
799  access::member_load(*self, t);
800  return *self;
801  }
802 
804  template <class T, PROCESS_IF(non_member_load)> inline
805  ArchiveType & processImpl(T & t)
806  {
807  CEREAL_LOAD_FUNCTION_NAME(*self, t);
808  return *self;
809  }
810 
812  template <class T, PROCESS_IF(member_load_minimal)> inline
813  ArchiveType & processImpl(T & t)
814  {
815  using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
816  typename traits::has_member_save_minimal<T, OutArchiveType>::type value;
817  self->process( value );
818  access::member_load_minimal(*self, t, value);
819  return *self;
820  }
821 
823  template <class T, PROCESS_IF(non_member_load_minimal)> inline
824  ArchiveType & processImpl(T & t)
825  {
826  using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
827  typename traits::has_non_member_save_minimal<T, OutArchiveType>::type value;
828  self->process( value );
829  CEREAL_LOAD_MINIMAL_FUNCTION_NAME(*self, t, value);
830  return *self;
831  }
832 
834  template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
835  !traits::is_input_serializable<T, ArchiveType>::value,
836  std::is_empty<T>::value> = traits::sfinae> inline
837  ArchiveType & processImpl(T const &)
838  {
839  return *self;
840  }
841 
843 
846  template <class T, traits::EnableIf<traits::has_invalid_input_versioning<T, ArchiveType>::value ||
847  (!traits::is_input_serializable<T, ArchiveType>::value &&
848  (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
849  ArchiveType & processImpl(T const &)
850  {
851  static_assert(traits::detail::count_input_serializers<T, ArchiveType>::value != 0,
852  "cereal could not find any input serialization functions for the provided type and archive combination. \n\n "
853  "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
854  "Serialize functions generally have the following signature: \n\n "
855  "template<class Archive> \n "
856  " void serialize(Archive & ar) \n "
857  " { \n "
858  " ar( member1, member2, member3 ); \n "
859  " } \n\n " );
860 
861  static_assert(traits::detail::count_input_serializers<T, ArchiveType>::value < 2,
862  "cereal found more than one compatible input serialization function for the provided type and archive combination. \n\n "
863  "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
864  "Use specialization (see access.hpp) if you need to disambiguate between serialize vs load/save functions. \n "
865  "Note that serialization functions can be inherited which may lead to the aforementioned ambiguities. \n "
866  "In addition, you may not mix versioned with non-versioned serialization functions. \n\n ");
867 
868  return *self;
869  }
870 
872  template <class A, class B, bool C, bool D, bool E, bool F> friend struct detail::Construct;
873 
875 
880  template <class T> inline
881  std::uint32_t loadClassVersion()
882  {
883  static const auto hash = std::type_index(typeid(T)).hash_code();
884  auto lookupResult = itsVersionedTypes.find( hash );
885 
886  if( lookupResult != itsVersionedTypes.end() ) // already exists
887  return lookupResult->second;
888  else // need to load
889  {
890  std::uint32_t version;
891 
892  process( make_nvp<ArchiveType>("cereal_class_version", version) );
893  itsVersionedTypes.emplace_hint( lookupResult, hash, version );
894 
895  return version;
896  }
897  }
898 
900 
901  template <class T, PROCESS_IF(member_versioned_serialize)> inline
902  ArchiveType & processImpl(T & t)
903  {
904  const auto version = loadClassVersion<T>();
905  access::member_serialize(*self, t, version);
906  return *self;
907  }
908 
910 
911  template <class T, PROCESS_IF(non_member_versioned_serialize)> inline
912  ArchiveType & processImpl(T & t)
913  {
914  const auto version = loadClassVersion<T>();
915  CEREAL_SERIALIZE_FUNCTION_NAME(*self, t, version);
916  return *self;
917  }
918 
920 
921  template <class T, PROCESS_IF(member_versioned_load)> inline
922  ArchiveType & processImpl(T & t)
923  {
924  const auto version = loadClassVersion<T>();
925  access::member_load(*self, t, version);
926  return *self;
927  }
928 
930 
931  template <class T, PROCESS_IF(non_member_versioned_load)> inline
932  ArchiveType & processImpl(T & t)
933  {
934  const auto version = loadClassVersion<T>();
935  CEREAL_LOAD_FUNCTION_NAME(*self, t, version);
936  return *self;
937  }
938 
940 
941  template <class T, PROCESS_IF(member_versioned_load_minimal)> inline
942  ArchiveType & processImpl(T & t)
943  {
944  using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
945  const auto version = loadClassVersion<T>();
946  typename traits::has_member_versioned_save_minimal<T, OutArchiveType>::type value;
947  self->process(value);
948  access::member_load_minimal(*self, t, value, version);
949  return *self;
950  }
951 
953 
954  template <class T, PROCESS_IF(non_member_versioned_load_minimal)> inline
955  ArchiveType & processImpl(T & t)
956  {
957  using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
958  const auto version = loadClassVersion<T>();
959  typename traits::has_non_member_versioned_save_minimal<T, OutArchiveType>::type value;
960  self->process(value);
961  CEREAL_LOAD_MINIMAL_FUNCTION_NAME(*self, t, value, version);
962  return *self;
963  }
964 
965  #undef PROCESS_IF
966 
967  private:
968  ArchiveType * const self;
969 
971  std::unordered_set<traits::detail::base_class_id, traits::detail::base_class_id_hash> itsBaseClassSet;
972 
974  std::unordered_map<std::uint32_t, std::shared_ptr<void>> itsSharedPointerMap;
975 
977  std::unordered_map<std::uint32_t, std::string> itsPolymorphicTypeMap;
978 
980  std::unordered_map<std::size_t, std::uint32_t> itsVersionedTypes;
981  }; // class InputArchive
982 } // namespace cereal
983 
984 // This include needs to come after things such as binary_data, make_nvp, etc
985 #include "cereal/types/common.hpp"
986 
987 #endif // CEREAL_CEREAL_HPP_
ArchiveType & operator()(Types &&...args)
Serializes all passed in data.
Definition: cereal.hpp:617
A wrapper around size metadata.
Definition: helpers.hpp:273
std::false_type is_loading
Indicates this archive is not intended for loading.
Definition: cereal.hpp:263
Support for base classes (virtual and non-virtual)
std::shared_ptr< void > getSharedPointer(std::uint32_t const id)
Retrieves a shared pointer given a unique key for it.
Definition: cereal.hpp:673
typename detail::EnableIfHelper< Conditions...>::type EnableIf
Provides a way to enable a function if conditions are met.
Definition: traits.hpp:116
NameValuePair< T > make_nvp(std::string const &name, T &&value)
Creates a name value pair.
Definition: cereal.hpp:54
std::true_type is_saving
Indicates this archive is intended for saving.
Definition: cereal.hpp:270
Internal type trait support.
std::string getPolymorphicName(std::uint32_t const id)
Retrieves the string for a polymorphic type given a unique key for it.
Definition: cereal.hpp:702
The base input archive class.
Definition: cereal.hpp:599
#define CEREAL_SERIALIZE_FUNCTION_NAME
The serialization/deserialization function name to search for.
Definition: macros.hpp:78
InputArchive(ArchiveType *const derived)
Construct the output archive.
Definition: cereal.hpp:604
#define CEREAL_SAVE_MINIMAL_FUNCTION_NAME
The serialization (save_minimal) function name to search for.
Definition: macros.hpp:106
void prologue(Archive &, T const &)
Definition: cereal.hpp:108
SizeTag< T > make_size_tag(T &&sz)
Creates a size tag from some variable.
Definition: cereal.hpp:95
std::uint32_t registerPolymorphicType(char const *name)
Registers a polymorphic type name with the archive.
Definition: cereal.hpp:328
Support common types - always included automatically.
Internal helper functionality.
Flags
Special flags for archives.
Definition: cereal.hpp:131
static LockGuard lock()
Attempts to lock this static object for the current scope.
Definition: static_object.hpp:109
Definition: access.hpp:40
NameValuePair< T > make_nvp(const char *name, T &&value)
Creates a name value pair.
Definition: cereal.hpp:63
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:277
For holding name value pairs.
Definition: helpers.hpp:137
Preprocessor macros that can customise the cereal library.
void registerSharedPointer(std::uint32_t const id, std::shared_ptr< void > ptr)
Registers a shared pointer to its unique identifier.
Definition: cereal.hpp:690
#define CEREAL_LOAD_FUNCTION_NAME
The deserialization (load) function name to search for.
Definition: macros.hpp:85
#define CEREAL_LOAD_MINIMAL_FUNCTION_NAME
The deserialization (load_minimal) function name to search for.
Definition: macros.hpp:99
std::uint32_t registerSharedPointer(void const *addr)
Registers a shared pointer with the archive.
Definition: cereal.hpp:304
void registerPolymorphicName(std::uint32_t const id, std::string const &name)
Registers a polymorphic name string to its unique identifier.
Definition: cereal.hpp:718
A wrapper around data that can be serialized in a binary fashion.
Definition: helpers.hpp:209
OutputArchive(ArchiveType *const derived)
Construct the output archive.
Definition: cereal.hpp:239
ArchiveType & operator>>(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:658
std::true_type is_loading
Indicates this archive is intended for loading.
Definition: cereal.hpp:633
std::false_type is_saving
Indicates this archive is not intended for saving.
Definition: cereal.hpp:640
Definition: helpers.hpp:230
ArchiveType & operator()(Types &&...args)
Serializes all passed in data.
Definition: cereal.hpp:247
The base output archive class.
Definition: cereal.hpp:234
#define CEREAL_SAVE_FUNCTION_NAME
The serialization (save) function name to search for.
Definition: macros.hpp:92
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:647
Definition: traits.hpp:1316
Definition: helpers.hpp:242
ArchiveType & operator<<(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:288
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:48
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:80
void epilogue(Archive &, T const &)
Definition: cereal.hpp:115