mirror of
https://github.com/USCiLab/cereal.git
synced 2025-10-18 01:45:52 +02:00
null ptr support to unique_ptr
This commit is contained in:
@@ -46,10 +46,32 @@
|
||||
#include <typeindex>
|
||||
#include <map>
|
||||
|
||||
//! Binds a polymorhic type to all registered archives
|
||||
/*! This binds a polymorphic type to all registered archives that
|
||||
have been registered with CEREAL_REGISTER_ARCHIVE. This must be called
|
||||
after all archives are registered (usually after the archives themselves
|
||||
have been included). */
|
||||
#define CEREAL_BIND_TO_ARCHIVES(T) \
|
||||
namespace cereal { \
|
||||
namespace detail { \
|
||||
template<> \
|
||||
struct init_binding<T> { \
|
||||
static bind_to_archives<T> const & b; \
|
||||
}; \
|
||||
bind_to_archives<T> const & init_binding<T>::b = \
|
||||
::cereal::detail::StaticObject< \
|
||||
bind_to_archives<T > \
|
||||
>::getInstance().bind(); \
|
||||
}} // end namespaces
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
//! Binds a compile time type with a user defined string
|
||||
template <class T>
|
||||
struct binding_name {};
|
||||
|
||||
template <class Archive>
|
||||
struct OutputBindingMap
|
||||
{
|
||||
@@ -73,8 +95,10 @@ namespace cereal
|
||||
struct InputArchiveBase;
|
||||
struct OutputArchiveBase;
|
||||
|
||||
//TODO
|
||||
template <class Archive, class T> struct InputBinding {};
|
||||
template <class Archive, class T> struct InputBinding
|
||||
{
|
||||
};
|
||||
|
||||
template <class Archive, class T> struct OutputBinding
|
||||
{
|
||||
OutputBinding( )
|
||||
|
||||
@@ -172,16 +172,30 @@ namespace cereal
|
||||
void save( Archive & ar, detail::PtrWrapper<std::unique_ptr<T, D> const &> const & wrapper )
|
||||
{
|
||||
auto & ptr = wrapper.ptr;
|
||||
|
||||
if( !ptr )
|
||||
ar( uint8_t(0) );
|
||||
else
|
||||
{
|
||||
ar( uint8_t(1) );
|
||||
ar( *ptr );
|
||||
}
|
||||
}
|
||||
|
||||
//! Loading std::unique_ptr, case when user provides load_and_allocate (wrapper implementation)
|
||||
template <class Archive, class T, class D> inline
|
||||
typename std::enable_if<traits::has_load_and_allocate<T, Archive>(), void>::type
|
||||
load( Archive & ar, detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper )
|
||||
{
|
||||
uint8_t isValid;
|
||||
ar( isValid );
|
||||
|
||||
auto & ptr = wrapper.ptr;
|
||||
|
||||
if( isValid )
|
||||
ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
|
||||
else
|
||||
ptr.reset( nullptr );
|
||||
}
|
||||
|
||||
//! Loading std::unique_ptr, case when no load_and_allocate (wrapper implementation)
|
||||
@@ -189,10 +203,19 @@ namespace cereal
|
||||
typename std::enable_if<!traits::has_load_and_allocate<T, Archive>(), void>::type
|
||||
load( Archive & ar, detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper )
|
||||
{
|
||||
uint8_t isValid;
|
||||
ar( isValid );
|
||||
|
||||
auto & ptr = wrapper.ptr;
|
||||
|
||||
if( isValid )
|
||||
{
|
||||
ptr.reset( detail::Load<T, Archive>::load_andor_allocate( ar ) );
|
||||
ar( *ptr );
|
||||
}
|
||||
else
|
||||
ptr.reset( nullptr );
|
||||
}
|
||||
|
||||
} // namespace cereal
|
||||
|
||||
|
||||
@@ -31,23 +31,23 @@
|
||||
#include <cereal/types/memory.hpp>
|
||||
#include <cereal/details/polymorphic_impl.hpp>
|
||||
|
||||
//! Binds a polymorhic type to all registered archives
|
||||
/*! This binds a polymorphic type to all registered archives that
|
||||
have been registered with CEREAL_REGISTER_ARCHIVE. This must be called
|
||||
after all archives are registered (usually after the archives themselves
|
||||
have been included). */
|
||||
#define CEREAL_BIND_TO_ARCHIVES(T) \
|
||||
#define CEREAL_REGISTER_TYPE(T) \
|
||||
namespace cereal { \
|
||||
namespace detail { \
|
||||
template<> \
|
||||
struct init_binding<T> { \
|
||||
static bind_to_archives<T> const & b; \
|
||||
}; \
|
||||
bind_to_archives<T> const & init_binding<T>::b = \
|
||||
::cereal::detail::StaticObject< \
|
||||
bind_to_archives<T > \
|
||||
>::getInstance().bind(); \
|
||||
}} // end namespaces
|
||||
template <> \
|
||||
struct binding_name<T> \
|
||||
{ static const char * name = #T; }; \
|
||||
} } /* end namespaces */ \
|
||||
CEREAL_BIND_TO_ARCHIVES(T);
|
||||
|
||||
#define CEREAL_REGISTER_TYPE_WITH_NAME(T, Name)\
|
||||
namespace cereal { \
|
||||
namespace detail { \
|
||||
template <> \
|
||||
struct binding_name<T> \
|
||||
{ static const char * name = #Name; }; \
|
||||
} } /* end namespaces */ \
|
||||
CEREAL_BIND_TO_ARCHIVES(T);
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
@@ -56,6 +56,12 @@ namespace cereal
|
||||
typename std::enable_if<std::is_polymorphic<T>::value, void>::type
|
||||
save( Archive & ar, std::shared_ptr<T> const & ptr )
|
||||
{
|
||||
if(!ptr)
|
||||
{
|
||||
//ar (detail::null_ptr());
|
||||
return;
|
||||
}
|
||||
|
||||
auto & bindingMap = detail::StaticObject<detail::OutputBindingMap<Archive>>::getInstance().map;
|
||||
|
||||
auto binding = bindingMap.find(std::type_index(typeid(*ptr.get())));
|
||||
|
||||
@@ -62,6 +62,8 @@ int main()
|
||||
cereal::BinaryOutputArchive archive(stream);
|
||||
|
||||
std::shared_ptr<Base> ptr = std::make_shared<MyType>();
|
||||
|
||||
archive(ptr);
|
||||
|
||||
std::unique_ptr<int> xxx(nullptr);
|
||||
archive(xxx);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user