null ptr support to unique_ptr

This commit is contained in:
Randolph Voorhies
2013-06-28 15:54:45 -07:00
parent f1b42507d7
commit 3c9554f8a2
4 changed files with 79 additions and 24 deletions

View File

@@ -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( )

View File

@@ -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

View File

@@ -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())));

View File

@@ -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);
} }