cereal
A C++11 library for serialization
polymorphic_impl.hpp
Go to the documentation of this file.
1 
4 /*
5  Copyright (c) 2014, Randolph Voorhies, Shane Grant
6  All rights reserved.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10  * Redistributions of source code must retain the above copyright
11  notice, this list of conditions and the following disclaimer.
12  * Redistributions in binary form must reproduce the above copyright
13  notice, this list of conditions and the following disclaimer in the
14  documentation and/or other materials provided with the distribution.
15  * Neither the name of cereal nor the
16  names of its contributors may be used to endorse or promote products
17  derived from this software without specific prior written permission.
18 
19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
23  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 
31 /* This code is heavily inspired by the boost serialization implementation by the following authors
32 
33  (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
34  Use, modification and distribution is subject to the Boost Software
35  License, Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt)
36 
37  See http://www.boost.org for updates, documentation, and revision history.
38 
39  (C) Copyright 2006 David Abrahams - http://www.boost.org.
40 
41  See /boost/serialization/export.hpp, /boost/archive/detail/register_archive.hpp,
42  and /boost/serialization/void_cast.hpp for their implementation. Additional details
43  found in other files split across serialization and archive.
44 */
45 #ifndef CEREAL_DETAILS_POLYMORPHIC_IMPL_HPP_
46 #define CEREAL_DETAILS_POLYMORPHIC_IMPL_HPP_
47 
50 #include <cereal/types/memory.hpp>
51 #include <cereal/types/string.hpp>
52 #include <functional>
53 #include <typeindex>
54 #include <map>
55 
57 
61 #define CEREAL_BIND_TO_ARCHIVES(...) \
62  namespace cereal { \
63  namespace detail { \
64  template<> \
65  struct init_binding<__VA_ARGS__> { \
66  static bind_to_archives<__VA_ARGS__> const & b; \
67  static void unused() { (void)b; } \
68  }; \
69  bind_to_archives<__VA_ARGS__> const & init_binding<__VA_ARGS__>::b = \
70  ::cereal::detail::StaticObject< \
71  bind_to_archives<__VA_ARGS__> \
72  >::getInstance().bind(); \
73  }} /* end namespaces */
74 
75 namespace cereal
76 {
77  /* Polymorphic casting support */
78  namespace detail
79  {
81 
94  {
95  PolymorphicCaster() = default;
96  PolymorphicCaster( const PolymorphicCaster & ) = default;
97  PolymorphicCaster & operator=( const PolymorphicCaster & ) = default;
99  PolymorphicCaster & operator=( PolymorphicCaster && ) CEREAL_NOEXCEPT { return *this; }
100  virtual ~PolymorphicCaster() CEREAL_NOEXCEPT = default;
101 
103  virtual void const * downcast( void const * const ptr ) const = 0;
105  virtual void * upcast( void * const ptr ) const = 0;
107  virtual std::shared_ptr<void> upcast( std::shared_ptr<void> const & ptr ) const = 0;
108  };
109 
111 
114  {
116  std::map<std::type_index, std::map<std::type_index, std::vector<PolymorphicCaster const*>>> map;
117 
119  #define UNREGISTERED_POLYMORPHIC_CAST_EXCEPTION(LoadSave) \
120  throw cereal::Exception("Trying to " #LoadSave " a registered polymorphic type with an unregistered polymorphic cast.\n" \
121  "Could not find a path to a base class (" + util::demangle(baseInfo.name()) + ") for type: " + ::cereal::util::demangledName<Derived>() + "\n" \
122  "Make sure you either serialize the base class at some point via cereal::base_class or cereal::virtual_base_class.\n" \
123  "Alternatively, manually register the association with CEREAL_REGISTER_POLYMORPHIC_RELATION.");
124 
126 
128  static bool exists( std::type_index const & baseIndex, std::type_index const & derivedIndex )
129  {
130  // First phase of lookup - match base type index
131  auto const & baseMap = StaticObject<PolymorphicCasters>::getInstance().map;
132  auto baseIter = baseMap.find( baseIndex );
133  if (baseIter == baseMap.end())
134  return false;
135 
136  // Second phase - find a match from base to derived
137  auto & derivedMap = baseIter->second;
138  auto derivedIter = derivedMap.find( derivedIndex );
139  if (derivedIter == derivedMap.end())
140  return false;
141 
142  return true;
143  }
144 
146 
150  template <class F> inline
151  static std::vector<PolymorphicCaster const *> const & lookup( std::type_index const & baseIndex, std::type_index const & derivedIndex, F && exceptionFunc )
152  {
153  // First phase of lookup - match base type index
154  auto const & baseMap = StaticObject<PolymorphicCasters>::getInstance().map;
155  auto baseIter = baseMap.find( baseIndex );
156  if( baseIter == baseMap.end() )
157  exceptionFunc();
158 
159  // Second phase - find a match from base to derived
160  auto & derivedMap = baseIter->second;
161  auto derivedIter = derivedMap.find( derivedIndex );
162  if( derivedIter == derivedMap.end() )
163  exceptionFunc();
164 
165  return derivedIter->second;
166  }
167 
169  template <class Derived> inline
170  static const Derived * downcast( const void * dptr, std::type_info const & baseInfo )
171  {
172  auto const & mapping = lookup( baseInfo, typeid(Derived), [&](){ UNREGISTERED_POLYMORPHIC_CAST_EXCEPTION(save) } );
173 
174  for( auto const * map : mapping )
175  dptr = map->downcast( dptr );
176 
177  return static_cast<Derived const *>( dptr );
178  }
179 
181 
183  template <class Derived> inline
184  static void * upcast( Derived * const dptr, std::type_info const & baseInfo )
185  {
186  auto const & mapping = lookup( baseInfo, typeid(Derived), [&](){ UNREGISTERED_POLYMORPHIC_CAST_EXCEPTION(load) } );
187 
188  void * uptr = dptr;
189  for( auto const * map : mapping )
190  uptr = map->upcast( uptr );
191 
192  return uptr;
193  }
194 
196  template <class Derived> inline
197  static std::shared_ptr<void> upcast( std::shared_ptr<Derived> const & dptr, std::type_info const & baseInfo )
198  {
199  auto const & mapping = lookup( baseInfo, typeid(Derived), [&](){ UNREGISTERED_POLYMORPHIC_CAST_EXCEPTION(load) } );
200 
201  std::shared_ptr<void> uptr = dptr;
202  for( auto const * map : mapping )
203  uptr = map->upcast( uptr );
204 
205  return uptr;
206  }
207 
208  #undef UNREGISTERED_POLYMORPHIC_CAST_EXCEPTION
209  };
210 
212  template <class Base, class Derived>
214  {
216 
220  {
221  const auto lock = StaticObject<PolymorphicCasters>::lock();
222  auto & baseMap = StaticObject<PolymorphicCasters>::getInstance().map;
223  auto baseKey = std::type_index(typeid(Base));
224  auto lb = baseMap.lower_bound(baseKey);
225 
226  {
227  auto & derivedMap = baseMap.insert( lb, {baseKey, {}} )->second;
228  auto derivedKey = std::type_index(typeid(Derived));
229  auto lbd = derivedMap.lower_bound(derivedKey);
230  auto & derivedVec = derivedMap.insert( lbd, { std::move(derivedKey), {}} )->second;
231  derivedVec.push_back( this );
232  }
233 
234  // Find all chainable unregistered relations
235  std::map<std::type_index, std::pair<std::type_index, std::vector<PolymorphicCaster const *>>> unregisteredRelations;
236  {
237  auto checkRelation = [](std::type_index const & baseInfo, std::type_index const & derivedInfo)
238  {
239  const bool exists = PolymorphicCasters::exists( baseInfo, derivedInfo );
240  return std::make_pair( exists, exists ? PolymorphicCasters::lookup( baseInfo, derivedInfo, [](){} ) :
241  std::vector<PolymorphicCaster const *>{} );
242  };
243 
244  for( auto baseIt : baseMap )
245  for( auto derivedIt : baseIt.second )
246  {
247  for( auto otherBaseIt : baseMap )
248  {
249  if( baseIt.first == otherBaseIt.first ) // only interested in chained relations
250  continue;
251 
252  // Check if there exists a mapping otherBase -> base -> derived that is shorter than
253  // any existing otherBase -> derived direct mapping
254  auto otherBaseItToDerived = checkRelation( otherBaseIt.first, derivedIt.first );
255  auto baseToDerived = checkRelation( baseIt.first, derivedIt.first );
256  auto otherBaseToBase = checkRelation( otherBaseIt.first, baseIt.first );
257 
258  const size_t newLength = otherBaseToBase.second.size() + baseToDerived.second.size();
259  const bool isShorterOrFirstPath = !otherBaseItToDerived.first || (newLength < derivedIt.second.size());
260 
261  if( isShorterOrFirstPath &&
262  baseToDerived.first &&
263  otherBaseToBase.first )
264  {
265  std::vector<PolymorphicCaster const *> path = otherBaseToBase.second;
266  path.insert( path.end(), baseToDerived.second.begin(), baseToDerived.second.end() );
267 
268  #ifdef CEREAL_OLDER_GCC
269  unregisteredRelations.insert( std::make_pair(otherBaseIt.first,
270  std::pair<std::type_index, std::vector<PolymorphicCaster const *>>{derivedIt.first, std::move(path)}) );
271  #else // NOT CEREAL_OLDER_GCC
272  unregisteredRelations.emplace( otherBaseIt.first,
273  std::pair<std::type_index, std::vector<PolymorphicCaster const *>>{derivedIt.first, std::move(path)} );
274  #endif // NOT CEREAL_OLDER_GCC
275  }
276  } // end otherBaseIt
277  } // end derivedIt
278  } // end chain lookup
279 
280  // Insert chained relations
281  for( auto it : unregisteredRelations )
282  {
283  auto & derivedMap = baseMap.find( it.first )->second;
284  derivedMap[it.second.first] = it.second.second;
285  }
286  }
287 
289  void const * downcast( void const * const ptr ) const override
290  {
291  return dynamic_cast<Derived const*>( static_cast<Base const*>( ptr ) );
292  }
293 
295  void * upcast( void * const ptr ) const override
296  {
297  return dynamic_cast<Base*>( static_cast<Derived*>( ptr ) );
298  }
299 
301  std::shared_ptr<void> upcast( std::shared_ptr<void> const & ptr ) const override
302  {
303  return std::dynamic_pointer_cast<Base>( std::static_pointer_cast<Derived>( ptr ) );
304  }
305  };
306 
308 
314  template <class Base, class Derived>
316  {
317  static PolymorphicCaster const * bind( std::true_type /* is_polymorphic<Base> */)
318  {
320  }
321 
322  static PolymorphicCaster const * bind( std::false_type /* is_polymorphic<Base> */ )
323  { return nullptr; }
324 
326 
327  static PolymorphicCaster const * bind()
328  { return bind( typename std::is_polymorphic<Base>::type() ); }
329  };
330  }
331 
332  /* General polymorphism support */
333  namespace detail
334  {
336  template <class T>
337  struct binding_name {};
338 
340 
344  template <class Archive>
346  {
348 
353  typedef std::function<void(void*, void const *, std::type_info const &)> Serializer;
354 
356  struct Serializers
357  {
358  Serializer shared_ptr,
359  unique_ptr;
360  };
361 
363  std::map<std::type_index, Serializers> map;
364  };
365 
367  template<class T> struct EmptyDeleter { void operator()(T *) const {} };
368 
370 
374  template <class Archive>
376  {
378 
383  typedef std::function<void(void*, std::shared_ptr<void> &, std::type_info const &)> SharedSerializer;
385  typedef std::function<void(void*, std::unique_ptr<void, EmptyDeleter<void>> &, std::type_info const &)> UniqueSerializer;
386 
388  struct Serializers
389  {
392  };
393 
395  std::map<std::string, Serializers> map;
396  };
397 
398  // forward decls for archives from cereal.hpp
399  class InputArchiveBase;
400  class OutputArchiveBase;
401 
403 
407  template <class Archive, class T> struct InputBindingCreator
408  {
411  {
412  auto & map = StaticObject<InputBindingMap<Archive>>::getInstance().map;
413  auto lock = StaticObject<InputBindingMap<Archive>>::lock();
414  auto key = std::string(binding_name<T>::name());
415  auto lb = map.lower_bound(key);
416 
417  if (lb != map.end() && lb->first == key)
418  return;
419 
420  typename InputBindingMap<Archive>::Serializers serializers;
421 
422  serializers.shared_ptr =
423  [](void * arptr, std::shared_ptr<void> & dptr, std::type_info const & baseInfo)
424  {
425  Archive & ar = *static_cast<Archive*>(arptr);
426  std::shared_ptr<T> ptr;
427 
428  ar( CEREAL_NVP_("ptr_wrapper", ::cereal::memory_detail::make_ptr_wrapper(ptr)) );
429 
430  dptr = PolymorphicCasters::template upcast<T>( ptr, baseInfo );
431  };
432 
433  serializers.unique_ptr =
434  [](void * arptr, std::unique_ptr<void, EmptyDeleter<void>> & dptr, std::type_info const & baseInfo)
435  {
436  Archive & ar = *static_cast<Archive*>(arptr);
437  std::unique_ptr<T> ptr;
438 
439  ar( CEREAL_NVP_("ptr_wrapper", ::cereal::memory_detail::make_ptr_wrapper(ptr)) );
440 
441  dptr.reset( PolymorphicCasters::template upcast<T>( ptr.release(), baseInfo ));
442  };
443 
444  map.insert( lb, { std::move(key), std::move(serializers) } );
445  }
446  };
447 
449 
453  template <class Archive, class T> struct OutputBindingCreator
454  {
456  static void writeMetadata(Archive & ar)
457  {
458  // Register the polymorphic type name with the archive, and get the id
459  char const * name = binding_name<T>::name();
460  std::uint32_t id = ar.registerPolymorphicType(name);
461 
462  // Serialize the id
463  ar( CEREAL_NVP_("polymorphic_id", id) );
464 
465  // If the msb of the id is 1, then the type name is new, and we should serialize it
466  if( id & detail::msb_32bit )
467  {
468  std::string namestring(name);
469  ar( CEREAL_NVP_("polymorphic_name", namestring) );
470  }
471  }
472 
475  {
476  public:
489  PolymorphicSharedPointerWrapper( T const * dptr ) : refCount(), wrappedPtr( refCount, dptr )
490  { }
491 
493  inline std::shared_ptr<T const> const & operator()() const { return wrappedPtr; }
494 
495  private:
496  std::shared_ptr<void> refCount;
497  std::shared_ptr<T const> wrappedPtr;
498  };
499 
501 
508  static inline void savePolymorphicSharedPtr( Archive & ar, T const * dptr, std::true_type /* has_shared_from_this */ )
509  {
510  ::cereal::memory_detail::EnableSharedStateHelper<T> state( const_cast<T *>(dptr) );
511  PolymorphicSharedPointerWrapper psptr( dptr );
512  ar( CEREAL_NVP_("ptr_wrapper", memory_detail::make_ptr_wrapper( psptr() ) ) );
513  }
514 
516 
523  static inline void savePolymorphicSharedPtr( Archive & ar, T const * dptr, std::false_type /* has_shared_from_this */ )
524  {
525  PolymorphicSharedPointerWrapper psptr( dptr );
526  ar( CEREAL_NVP_("ptr_wrapper", memory_detail::make_ptr_wrapper( psptr() ) ) );
527  }
528 
531  {
532  auto & map = StaticObject<OutputBindingMap<Archive>>::getInstance().map;
533  auto key = std::type_index(typeid(T));
534  auto lb = map.lower_bound(key);
535 
536  if (lb != map.end() && lb->first == key)
537  return;
538 
539  typename OutputBindingMap<Archive>::Serializers serializers;
540 
541  serializers.shared_ptr =
542  [&](void * arptr, void const * dptr, std::type_info const & baseInfo)
543  {
544  Archive & ar = *static_cast<Archive*>(arptr);
545  writeMetadata(ar);
546 
547  auto ptr = PolymorphicCasters::template downcast<T>( dptr, baseInfo );
548 
549  #ifdef _MSC_VER
550  savePolymorphicSharedPtr( ar, ptr, ::cereal::traits::has_shared_from_this<T>::type() ); // MSVC doesn't like typename here
551  #else // not _MSC_VER
552  savePolymorphicSharedPtr( ar, ptr, typename ::cereal::traits::has_shared_from_this<T>::type() );
553  #endif // _MSC_VER
554  };
555 
556  serializers.unique_ptr =
557  [&](void * arptr, void const * dptr, std::type_info const & baseInfo)
558  {
559  Archive & ar = *static_cast<Archive*>(arptr);
560  writeMetadata(ar);
561 
562  std::unique_ptr<T const, EmptyDeleter<T const>> const ptr( PolymorphicCasters::template downcast<T>( dptr, baseInfo ) );
563 
564  ar( CEREAL_NVP_("ptr_wrapper", memory_detail::make_ptr_wrapper(ptr)) );
565  };
566 
567  map.insert( { std::move(key), std::move(serializers) } );
568  }
569  };
570 
573  struct adl_tag {};
574 
577  namespace { struct polymorphic_binding_tag {}; }
578 
580  template <class Archive, class T>
582  {
583  static const InputBindingCreator<Archive, T> &
584  load(std::true_type)
585  {
587  }
588 
589  static const OutputBindingCreator<Archive, T> &
590  save(std::true_type)
591  {
593  }
594 
595  inline static void load(std::false_type) {}
596  inline static void save(std::false_type) {}
597  };
598 
600  template <void(*)()>
602 
608  template <class Archive, class T>
610  {
611  #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
612  virtual CEREAL_DLL_EXPORT void instantiate() CEREAL_USED;
615  #else // NOT _MSC_VER
616  static CEREAL_DLL_EXPORT void instantiate() CEREAL_USED;
621  #endif // _MSC_VER
622  };
623 
624  // instantiate implementation
625  template <class Archive, class T>
627  {
628  create_bindings<Archive,T>::save( std::integral_constant<bool,
629  std::is_base_of<detail::OutputArchiveBase, Archive>::value &&
631 
632  create_bindings<Archive,T>::load( std::integral_constant<bool,
633  std::is_base_of<detail::InputArchiveBase, Archive>::value &&
635  }
636 
638 
642  template <class T, class Tag = polymorphic_binding_tag>
644  {
646  void bind(std::false_type) const
647  {
648  instantiate_polymorphic_binding((T*) 0, 0, Tag{}, adl_tag{});
649  }
650 
652  void bind(std::true_type) const
653  { }
654 
656 
658  bind_to_archives const & bind() const
659  {
660  static_assert( std::is_polymorphic<T>::value,
661  "Attempting to register non polymorphic type" );
662  bind( std::is_abstract<T>() );
663  return *this;
664  }
665  };
666 
668  template <class T, class Tag = polymorphic_binding_tag>
669  struct init_binding;
670 
672 
683  template <class T, typename BindingTag>
684  void instantiate_polymorphic_binding( T*, int, BindingTag, adl_tag ) {}
685  } // namespace detail
686 } // namespace cereal
687 
688 #endif // CEREAL_DETAILS_POLYMORPHIC_IMPL_HPP_
#define CEREAL_NVP_(name, value)
Convenience for creating a templated NVP.
Definition: helpers.hpp:197
void instantiate_polymorphic_binding(T *, int, BindingTag, adl_tag)
Base case overload for instantiation.
Definition: polymorphic_impl.hpp:684
Creates a binding (map entry) between an input archive type and a polymorphic type.
Definition: polymorphic_impl.hpp:407
static void * upcast(Derived *const dptr, std::type_info const &baseInfo)
Performs an upcast to the registered base type using the given a derived type.
Definition: polymorphic_impl.hpp:184
virtual void * upcast(void *const ptr) const =0
Upcast to proper base type.
Struct containing the serializer functions for all pointer types.
Definition: polymorphic_impl.hpp:356
When specialized, causes the compiler to instantiate its parameter.
Definition: polymorphic_impl.hpp:601
static PolymorphicCaster const * bind()
Performs registration (binding) between Base and Derived.
Definition: polymorphic_impl.hpp:327
std::function< void(void *, std::shared_ptr< void > &, std::type_info const &)> SharedSerializer
Shared ptr serializer function.
Definition: polymorphic_impl.hpp:383
Used to hide the static object used to bind T to registered archives.
Definition: polymorphic_impl.hpp:669
Base type for polymorphic void casting.
Definition: polymorphic_impl.hpp:93
Holds registered mappings between base and derived types for casting.
Definition: polymorphic_impl.hpp:113
Strongly typed derivation of PolymorphicCaster.
Definition: polymorphic_impl.hpp:213
PolymorphicVirtualCaster()
Inserts an entry in the polymorphic casting map for this pairing.
Definition: polymorphic_impl.hpp:219
Serializer unique_ptr
Serializer function for unique pointers.
Definition: polymorphic_impl.hpp:358
Holds a properly typed shared_ptr to the polymorphic type.
Definition: polymorphic_impl.hpp:474
std::shared_ptr< T const > const & operator()() const
Get the wrapped shared_ptr */.
Definition: polymorphic_impl.hpp:493
Registers a polymorphic casting relation between a Base and Derived type.
Definition: polymorphic_impl.hpp:315
static LockGuard lock()
Attempts to lock this static object for the current scope.
Definition: static_object.hpp:109
bind_to_archives const & bind() const
Binds the type T to all registered archives.
Definition: polymorphic_impl.hpp:658
Determine if T or any base class of T has inherited from std::enable_shared_from_this.
Definition: traits.hpp:1194
void bind(std::false_type) const
Binding for non abstract types.
Definition: polymorphic_impl.hpp:646
PolymorphicSharedPointerWrapper(T const *dptr)
Definition: polymorphic_impl.hpp:489
Definition: access.hpp:40
Serializer shared_ptr
Serializer function for shared/weak pointers.
Definition: polymorphic_impl.hpp:358
SharedSerializer shared_ptr
Serializer function for shared/weak pointers.
Definition: polymorphic_impl.hpp:390
Struct containing the serializer functions for all pointer types.
Definition: polymorphic_impl.hpp:388
#define UNREGISTERED_POLYMORPHIC_CAST_EXCEPTION(LoadSave)
Error message used for unregistered polymorphic casts.
Definition: polymorphic_impl.hpp:119
std::function< void(void *, void const *, std::type_info const &)> Serializer
A serializer function.
Definition: polymorphic_impl.hpp:353
static void savePolymorphicSharedPtr(Archive &ar, T const *dptr, std::true_type)
Does the actual work of saving a polymorphic shared_ptr.
Definition: polymorphic_impl.hpp:508
OutputBindingCreator()
Initialize the binding.
Definition: polymorphic_impl.hpp:530
std::map< std::string, Serializers > map
A map of serializers for pointers of all registered types.
Definition: polymorphic_impl.hpp:395
static CEREAL_DLL_EXPORT void instantiate() CEREAL_USED
Definition: polymorphic_impl.hpp:626
Definition: traits.hpp:1089
Definition: polymorphic_impl.hpp:573
Creates a binding (map entry) between an output archive type and a polymorphic type.
Definition: polymorphic_impl.hpp:453
static bool exists(std::type_index const &baseIndex, std::type_index const &derivedIndex)
Checks if the mapping object that can perform the upcast or downcast.
Definition: polymorphic_impl.hpp:128
Support for types found in <string>
Causes the static object bindings between an archive type and a serializable type T...
Definition: polymorphic_impl.hpp:581
static void writeMetadata(Archive &ar)
Writes appropriate metadata to the archive for this polymorphic type.
Definition: polymorphic_impl.hpp:456
#define CEREAL_NOEXCEPT
Defines the CEREAL_NOEXCEPT macro to use instead of noexcept.
Definition: macros.hpp:116
void * upcast(void *const ptr) const override
Performs the proper upcast with the templated types.
Definition: polymorphic_impl.hpp:295
An empty noop deleter.
Definition: polymorphic_impl.hpp:367
InputBindingCreator()
Initialize the binding.
Definition: polymorphic_impl.hpp:410
static void savePolymorphicSharedPtr(Archive &ar, T const *dptr, std::false_type)
Does the actual work of saving a polymorphic shared_ptr.
Definition: polymorphic_impl.hpp:523
Internal polymorphism support forward declarations.
std::map< std::type_index, std::map< std::type_index, std::vector< PolymorphicCaster const * > > > map
Maps from base type index to a map from derived type index to caster.
Definition: polymorphic_impl.hpp:116
std::map< std::type_index, Serializers > map
A map of serializers for pointers of all registered types.
Definition: polymorphic_impl.hpp:363
instantiate_function< instantiate > unused
This typedef causes the compiler to instantiate this static function.
Definition: polymorphic_impl.hpp:620
Binds a compile time type with a user defined string.
Definition: polymorphic_impl.hpp:337
Definition: helpers.hpp:228
#define CEREAL_DLL_EXPORT
Prevent link optimization from removing non-referenced static objects.
Definition: static_object.hpp:51
static std::shared_ptr< void > upcast(std::shared_ptr< Derived > const &dptr, std::type_info const &baseInfo)
Upcasts for shared pointers.
Definition: polymorphic_impl.hpp:197
std::function< void(void *, std::unique_ptr< void, EmptyDeleter< void >> &, std::type_info const &)> UniqueSerializer
Unique ptr serializer function.
Definition: polymorphic_impl.hpp:385
static const Derived * downcast(const void *dptr, std::type_info const &baseInfo)
Performs a downcast to the derived type using a registered mapping.
Definition: polymorphic_impl.hpp:170
static std::vector< PolymorphicCaster const * > const & lookup(std::type_index const &baseIndex, std::type_index const &derivedIndex, F &&exceptionFunc)
Gets the mapping object that can perform the upcast or downcast.
Definition: polymorphic_impl.hpp:151
A structure holding a map from type name strings to input serializer functions.
Definition: polymorphic_impl.hpp:375
Begins the binding process of a type to all registered archives.
Definition: polymorphic_impl.hpp:643
Definition: helpers.hpp:240
Definition: traits.hpp:1116
UniqueSerializer unique_ptr
Serializer function for unique pointers.
Definition: polymorphic_impl.hpp:391
A static, pre-execution object.
Definition: static_object.hpp:67
void const * downcast(void const *const ptr) const override
Performs the proper downcast with the templated types.
Definition: polymorphic_impl.hpp:289
A structure holding a map from type_indices to output serializer functions.
Definition: polymorphic_impl.hpp:345
Support for types found in <memory>
Internal polymorphism static object support.
virtual void const * downcast(void const *const ptr) const =0
Downcasts to the proper derived type.
void bind(std::true_type) const
Binding for abstract types.
Definition: polymorphic_impl.hpp:652
std::shared_ptr< void > upcast(std::shared_ptr< void > const &ptr) const override
Performs the proper upcast with the templated types (shared_ptr version)
Definition: polymorphic_impl.hpp:301