Poly types no longer fail to compile if an already included archive is not compatible with the type.

Updated run time error to be more informative when polymorphic serialization fails.

working on changing CEREAL_REGISTER_SHARED_LIBRARY to less specific name and description
This commit is contained in:
Shane Grant
2015-01-18 01:13:43 -08:00
parent b524b60ddf
commit 994aceeec0
2 changed files with 36 additions and 5 deletions
+6 -2
View File
@@ -374,9 +374,13 @@ namespace cereal
template <class Archive, class T>
CEREAL_DLL_EXPORT void polymorphic_serialization_support<Archive,T>::instantiate()
{
create_bindings<Archive,T>::save( std::is_base_of<detail::OutputArchiveBase, Archive>() );
create_bindings<Archive,T>::save( std::integral_constant<bool,
std::is_base_of<detail::OutputArchiveBase, Archive>::value &&
traits::is_output_serializable<T, Archive>::value>{} );
create_bindings<Archive,T>::load( std::is_base_of<detail::InputArchiveBase, Archive>() );
create_bindings<Archive,T>::load( std::integral_constant<bool,
std::is_base_of<detail::InputArchiveBase, Archive>::value &&
traits::is_input_serializable<T, Archive>::value>{} );
}
//! Begins the binding process of a type to all registered archives
+30 -3
View File
@@ -47,7 +47,7 @@
//! Registers a polymorphic type with cereal
/*! Polymorphic types must be registered before pointers
to them can be serialized. This also assumes that
all relevent archives have also previously been
all relevant archives have also previously been
registered. Registration for archives is usually done
in the header file in which they are defined. This means
that type registration needs to happen after specific
@@ -57,6 +57,9 @@
serialize it when a pointer to a base object is
used in conjunction with a derived class.
Type registration should be done in the header file
in which the type is declared.
Polymorphic support in cereal requires RTTI to be
enabled */
#define CEREAL_REGISTER_TYPE(T) \
@@ -85,6 +88,28 @@
} } /* end namespaces */ \
CEREAL_BIND_TO_ARCHIVES(T)
/*! In C++ dynamic initialization of non-local variables of a translation unit may be deferred until "the first odr-use
of any function or variable defined in the same translation unit as the variable to be initialized". Since polymorphic
types support in cereal relies on the fact that dynamic initialization of certain global objects happens before
the serialization is performed, it's important to make sure that something from files that call CEREAL_REGISTER_TYPE
macro is odr-used before serialization starts, otherwise the serialization will fail.
The _DYNAMIC_INIT_ENFORCER macros may be used to do this as follows:
1) Put CEREAL_DEFINE_DYNAMIC_INIT_ENFORCER(SomeName) into a source file that contains calls to CEREAL_REGISTER_TYPE;
2) Put CEREAL_DECLARE_DYNAMIC_INIT_ENFORCER(SomeName) to its associated header file.
Inclusion of the header file will now force the dynamic initialization of global stuff in the corresponding source file. */
/*! In C++, dynamic initialization of non-local variables of a translation
unit may be deferred until "the first odr-use of any function or variable
defined in the same translation unit as the variable to be initialized."
Since polymorphic type support in cereal relies on the dynamic
initialization of certain global objects happens before
serialization is performed, it is important to ensure that something
from files that call CEREAL_REGI */
#define CEREAL_REGISTER_DYNAMIC_INIT(Name)
#define CEREAL_FORCE_DYNAMIC_INIT(Name)
//! Adds a way to force loading of a shared library containing
//! only calls to CEREAL_REGISTER_TYPE
/*! Since CEREAL_REGISTER_TYPE must be in a source file,
@@ -261,7 +286,8 @@ namespace cereal
auto binding = bindingMap.find(std::type_index(ptrinfo));
if(binding == bindingMap.end())
throw cereal::Exception("Trying to save an unregistered polymorphic type (" + cereal::util::demangle(ptrinfo.name()) + ").\n"
"Make sure your type is registered with CEREAL_REGISTER_TYPE.\n"
"Make sure your type is registered with CEREAL_REGISTER_TYPE and that the archive "
"you are using was included (and registered with CEREAL_REGISTER_ARCHIVE) prior to calling CEREAL_REGISTER_TYPE.\n"
"If your type is already registered and you still see this error, you may need to use CEREAL_REGISTER_SHARED_LIBRARY.");
binding->second.shared_ptr(&ar, ptr.get());
@@ -298,7 +324,8 @@ namespace cereal
auto binding = bindingMap.find(std::type_index(ptrinfo));
if(binding == bindingMap.end())
throw cereal::Exception("Trying to save an unregistered polymorphic type (" + cereal::util::demangle(ptrinfo.name()) + ").\n"
"Make sure your type is registered with CEREAL_REGISTER_TYPE.\n"
"Make sure your type is registered with CEREAL_REGISTER_TYPE and that the archive "
"you are using was included (and registered with CEREAL_REGISTER_ARCHIVE) prior to calling CEREAL_REGISTER_TYPE.\n"
"If your type is already registered and you still see this error, you may need to use CEREAL_REGISTER_SHARED_LIBRARY.");
binding->second.shared_ptr(&ar, ptr.get());