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