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

View File

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

View File

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

View File

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