Renaming load_and_allocate to load_and_construct

Anything associated this that used the verb allocate has been replaced with construct

closes #59
This commit is contained in:
Shane Grant
2014-02-21 15:52:26 -08:00
parent 4a3c2859e6
commit 30a22fec28
7 changed files with 137 additions and 137 deletions

View File

@@ -39,11 +39,11 @@ namespace cereal
{ {
//! A class that allows cereal to load smart pointers to types that have no default constructor //! A class that allows cereal to load smart pointers to types that have no default constructor
/*! If your class does not have a default constructor, cereal will not be able /*! If your class does not have a default constructor, cereal will not be able
to load any smart pointers to it unless you overload LoadAndAllocate to load any smart pointers to it unless you overload LoadAndConstruct
for your class, and provide an appropriate load_and_allocate method. You can also for your class, and provide an appropriate load_and_construct method. You can also
choose to define a member static function instead of specializing this class. choose to define a member static function instead of specializing this class.
The specialization of LoadAndAllocate must be placed within the cereal namespace: The specialization of LoadAndConstruct must be placed within the cereal namespace:
@code{.cpp} @code{.cpp}
struct MyType struct MyType
@@ -59,20 +59,20 @@ namespace cereal
} }
}; };
// Provide a specialization for LoadAndAllocate for your type // Provide a specialization for LoadAndConstruct for your type
namespace cereal namespace cereal
{ {
template <> struct LoadAndAllocate<MyType> template <> struct LoadAndConstruct<MyType>
{ {
// load_and_allocate will be passed the archive that you will be loading // load_and_construct will be passed the archive that you will be loading
// from as well as an allocate object which you can use as if it were the // from as well as a construct object which you can use as if it were the
// constructor for your type. cereal will handle all memory management for you. // constructor for your type. cereal will handle all memory management for you.
template <class Archive> template <class Archive>
static void load_and_allocate( Archive & ar, cereal::allocate<MyType> & allocate ) static void load_and_construct( Archive & ar, cereal::construct<MyType> & construct )
{ {
int x; int x;
ar( x ); ar( x );
allocate( x ); construct( x );
} }
}; };
} // end namespace cereal } // end namespace cereal
@@ -81,30 +81,30 @@ namespace cereal
Please note that just as in using external serialization functions, you cannot get Please note that just as in using external serialization functions, you cannot get
access to non-public members of your class by befriending cereal::access. If you access to non-public members of your class by befriending cereal::access. If you
have the ability to modify the class you wish to serialize, it is recommended that you have the ability to modify the class you wish to serialize, it is recommended that you
use member serialize functions and a static member load_and_allocate function. use member serialize functions and a static member load_and_construct function.
@tparam T The type to specialize for @tparam T The type to specialize for
@ingroup Access */ @ingroup Access */
template <class T> template <class T>
struct LoadAndAllocate struct LoadAndConstruct
{ {
//! Called by cereal if no default constructor exists to load and allocate data simultaneously //! Called by cereal if no default constructor exists to load and construct data simultaneously
/*! Overloads of this should return a pointer to T and expect an archive as a parameter */ /*! Overloads of this should return a pointer to T and expect an archive as a parameter */
static std::false_type load_and_allocate(...) static std::false_type load_and_construct(...)
{ return std::false_type(); } { return std::false_type(); }
}; };
// forward decl for allocate // forward decl for construct
//! @cond PRIVATE_NEVERDEFINED //! @cond PRIVATE_NEVERDEFINED
namespace memory_detail{ template <class Ar, class T> struct LoadAndAllocateLoadWrapper; } namespace memory_detail{ template <class Ar, class T> struct LoadAndConstructLoadWrapper; }
//! @endcond //! @endcond
//! Used to allocate types with no default constructor //! Used to construct types with no default constructor
/*! When serializing a type that has no default constructor, cereal /*! When serializing a type that has no default constructor, cereal
will attempt to call either the class static function load_and_allocate will attempt to call either the class static function load_and_construct
or the appropriate template specialization of LoadAndAllocate. cereal or the appropriate template specialization of LoadAndConstruct. cereal
will pass that function a reference to the archive as well as a reference will pass that function a reference to the archive as well as a reference
to an allocate object which should be used to perform the allocation once to a construct object which should be used to perform the allocation once
data has been appropriately loaded. data has been appropriately loaded.
@code{.cpp} @code{.cpp}
@@ -124,21 +124,21 @@ namespace cereal
} }
template <class Archive> template <class Archive>
static void load_and_allocate( Archive & ar, cereal::allocate<MyType> & allocate ) static void load_and_construct( Archive & ar, cereal::construct<MyType> & construct )
{ {
int x, y; int x, y;
ar( x, y ); ar( x, y );
// use allocate object to initialize with loaded data // use construct object to initialize with loaded data
allocate( x, y ); construct( x, y );
// access to member variables and functions via -> operator // access to member variables and functions via -> operator
ar( allocate->notInConstructor ); ar( construct->notInConstructor );
// could also do the above section by: // could also do the above section by:
double z; double z;
ar( z ); ar( z );
allocate->notInConstructor = z; construct->notInConstructor = z;
} }
}; };
@endcode @endcode
@@ -146,10 +146,10 @@ namespace cereal
@tparam T The class type being serialized @tparam T The class type being serialized
*/ */
template <class T> template <class T>
class allocate class construct
{ {
public: public:
//! Allocate and initialize the type T with the given arguments //! Construct and initialize the type T with the given arguments
/*! This will forward all arguments to the underlying type T, /*! This will forward all arguments to the underlying type T,
calling an appropriate constructor. calling an appropriate constructor.
@@ -162,7 +162,7 @@ namespace cereal
void operator()( Args && ... args ) void operator()( Args && ... args )
{ {
if( itsValid ) if( itsValid )
throw Exception("Attempting to allocate an already initialized object"); throw Exception("Attempting to construct an already initialized object");
new (itsPtr) T( std::forward<Args>( args )... ); new (itsPtr) T( std::forward<Args>( args )... );
itsValid = true; itsValid = true;
@@ -183,7 +183,7 @@ namespace cereal
//! Returns a raw pointer to the initialized underlying object //! Returns a raw pointer to the initialized underlying object
/*! This is mainly intended for use with passing an instance of /*! This is mainly intended for use with passing an instance of
an allocated object to cereal::base_class. a constructed object to cereal::base_class.
It is strongly recommended to avoid using this function in It is strongly recommended to avoid using this function in
any other circumstance. any other circumstance.
@@ -195,11 +195,11 @@ namespace cereal
} }
private: private:
template <class A, class B> friend struct ::cereal::memory_detail::LoadAndAllocateLoadWrapper; template <class A, class B> friend struct ::cereal::memory_detail::LoadAndConstructLoadWrapper;
allocate( T * p ) : itsPtr( p ), itsValid( false ) {} construct( T * p ) : itsPtr( p ), itsValid( false ) {}
allocate( allocate const & ) = delete; construct( construct const & ) = delete;
allocate & operator=( allocate const & ) = delete; construct & operator=( construct const & ) = delete;
T * itsPtr; T * itsPtr;
bool itsValid; bool itsValid;
@@ -263,13 +263,13 @@ namespace cereal
{ t.load(ar, version); } { t.load(ar, version); }
template <class T> template <class T>
static std::false_type load_and_allocate(...) static std::false_type load_and_construct(...)
{ return std::false_type(); } { return std::false_type(); }
template<class T, class Archive> inline template<class T, class Archive> inline
static auto load_and_allocate(Archive & ar, ::cereal::allocate<T> & allocate) -> decltype(T::load_and_allocate(ar, allocate)) static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct) -> decltype(T::load_and_construct(ar, construct))
{ {
T::load_and_allocate( ar, allocate ); T::load_and_construct( ar, construct );
} }
}; };

View File

@@ -145,22 +145,22 @@ namespace cereal
struct has_non_member_versioned_##name : std::integral_constant<bool, detail::has_non_member_versioned_##name##_impl<T, A>::value> {} struct has_non_member_versioned_##name : std::integral_constant<bool, detail::has_non_member_versioned_##name##_impl<T, A>::value> {}
// ###################################################################### // ######################################################################
// Member load_and_allocate // Member load_and_construct
template<typename T, typename A> template<typename T, typename A>
struct has_member_load_and_allocate : struct has_member_load_and_construct :
std::integral_constant<bool, std::is_same<decltype( access::load_and_allocate<T>( std::declval<A&>(), std::declval< ::cereal::allocate<T>&>() ) ), void>::value> {}; std::integral_constant<bool, std::is_same<decltype( access::load_and_construct<T>( std::declval<A&>(), std::declval< ::cereal::construct<T>&>() ) ), void>::value> {};
// ###################################################################### // ######################################################################
// Non Member load_and_allocate // Non Member load_and_construct
template<typename T, typename A> template<typename T, typename A>
struct has_non_member_load_and_allocate : std::integral_constant<bool, struct has_non_member_load_and_construct : std::integral_constant<bool,
std::is_same<decltype( LoadAndAllocate<T>::load_and_allocate( std::declval<A&>(), std::declval< ::cereal::allocate<T>&>() ) ), void>::value> {}; std::is_same<decltype( LoadAndConstruct<T>::load_and_construct( std::declval<A&>(), std::declval< ::cereal::construct<T>&>() ) ), void>::value> {};
// ###################################################################### // ######################################################################
// Has either a member or non member allocate // Has either a member or non member allocate
template<typename T, typename A> template<typename T, typename A>
struct has_load_and_allocate : std::integral_constant<bool, struct has_load_and_construct : std::integral_constant<bool,
has_member_load_and_allocate<T, A>::value || has_non_member_load_and_allocate<T, A>::value> has_member_load_and_construct<T, A>::value || has_non_member_load_and_construct<T, A>::value>
{ }; { };
// ###################################################################### // ######################################################################
@@ -580,47 +580,47 @@ namespace cereal
// ###################################################################### // ######################################################################
namespace detail namespace detail
{ {
template <class T, class A, bool Member = traits::has_member_load_and_allocate<T, A>::value, bool NonMember = traits::has_non_member_load_and_allocate<T, A>::value> template <class T, class A, bool Member = traits::has_member_load_and_construct<T, A>::value, bool NonMember = traits::has_non_member_load_and_construct<T, A>::value>
struct Load struct Construct
{ {
static_assert( !sizeof(T), "Cereal detected both member and non member load_and_allocate functions!" ); static_assert( !sizeof(T), "Cereal detected both member and non member load_and_construct functions!" );
static T * load_andor_allocate( A & /*ar*/, allocate<T> & /*allocate*/ ) static T * load_andor_construct( A & /*ar*/, construct<T> & /*construct*/ )
{ return nullptr; } { return nullptr; }
}; };
template <class T, class A> template <class T, class A>
struct Load<T, A, false, false> struct Construct<T, A, false, false>
{ {
static_assert( std::is_default_constructible<T>::value, static_assert( std::is_default_constructible<T>::value,
"Trying to serialize a an object with no default constructor.\n\n" "Trying to serialize a an object with no default constructor.\n\n"
"Types must either be default constructible or define either a member or non member Construct function.\n" "Types must either be default constructible or define either a member or non member Construct function.\n"
"Construct functions generally have the signature:\n\n" "Construct functions generally have the signature:\n\n"
"template <class Archive>\n" "template <class Archive>\n"
"static void load_and_allocate(Archive & ar, cereal::allocate<T> & allocate)\n" "static void load_and_construct(Archive & ar, cereal::construct<T> & construct)\n"
"{\n" "{\n"
" var a;\n" " var a;\n"
" ar( a )\n" " ar( a )\n"
" allocate( a );\n" " construct( a );\n"
"}\n\n" ); "}\n\n" );
static T * load_andor_allocate() static T * load_andor_construct()
{ return new T(); } { return new T(); }
}; };
template <class T, class A> template <class T, class A>
struct Load<T, A, true, false> struct Construct<T, A, true, false>
{ {
static void load_andor_allocate( A & ar, allocate<T> & allocate ) static void load_andor_construct( A & ar, construct<T> & construct )
{ {
access::load_and_allocate<T>( ar, allocate ); access::load_and_construct<T>( ar, construct );
} }
}; };
template <class T, class A> template <class T, class A>
struct Load<T, A, false, true> struct Construct<T, A, false, true>
{ {
static void load_andor_allocate( A & ar, allocate<T> & allocate ) static void load_andor_construct( A & ar, construct<T> & construct )
{ {
LoadAndAllocate<T>::load_and_allocate( ar, allocate ); LoadAndConstruct<T>::load_and_construct( ar, construct );
} }
}; };
} // namespace detail } // namespace detail

View File

@@ -56,26 +56,26 @@ namespace cereal
return {std::forward<T>(t)}; return {std::forward<T>(t)};
} }
//! A struct that acts as a wrapper around calling load_andor_allocate //! A struct that acts as a wrapper around calling load_andor_construct
/*! The purpose of this is to allow a load_and_allocate call to properly enter into the /*! The purpose of this is to allow a load_and_construct call to properly enter into the
'data' NVP of the ptr_wrapper 'data' NVP of the ptr_wrapper
@internal */ @internal */
template <class Archive, class T> template <class Archive, class T>
struct LoadAndAllocateLoadWrapper struct LoadAndConstructLoadWrapper
{ {
LoadAndAllocateLoadWrapper( T * ptr ) : LoadAndConstructLoadWrapper( T * ptr ) :
allocate( ptr ) construct( ptr )
{ } { }
inline void serialize( Archive & ar ) inline void serialize( Archive & ar )
{ {
::cereal::detail::Load<T, Archive>::load_andor_allocate( ar, allocate ); ::cereal::detail::Construct<T, Archive>::load_andor_construct( ar, construct );
} }
::cereal::allocate<T> allocate; ::cereal::construct<T> construct;
}; };
//! Performs loading and allocation for a shared pointer that is NOT derived from //! Performs loading and construction for a shared pointer that is NOT derived from
//! std::enable_shared_from_this //! std::enable_shared_from_this
/*! This is the typical case, where we simply pass the load wrapper to the /*! This is the typical case, where we simply pass the load wrapper to the
archive archive
@@ -84,15 +84,15 @@ namespace cereal
@param ptr Raw pointer held by the shared_ptr @param ptr Raw pointer held by the shared_ptr
@internal */ @internal */
template <class Archive, class T> inline template <class Archive, class T> inline
void loadAndAllocateSharedPtr( Archive & ar, T * ptr, std::false_type /* has_shared_from_this */ ) void loadAndConstructSharedPtr( Archive & ar, T * ptr, std::false_type /* has_shared_from_this */ )
{ {
memory_detail::LoadAndAllocateLoadWrapper<Archive, T> loadWrapper( ptr ); memory_detail::LoadAndConstructLoadWrapper<Archive, T> loadWrapper( ptr );
ar( _CEREAL_NVP("data", loadWrapper) ); ar( _CEREAL_NVP("data", loadWrapper) );
} }
//! Performs loading and allocation for a shared pointer that is derived from //! Performs loading and construction for a shared pointer that is derived from
//! std::enable_shared_from_this //! std::enable_shared_from_this
/*! This special case is necessary because when a user uses load_and_allocate, /*! This special case is necessary because when a user uses load_and_construct,
the weak_ptr (or whatever implementation defined variant) that allows the weak_ptr (or whatever implementation defined variant) that allows
enable_shared_from_this to function correctly will not be initialized properly. enable_shared_from_this to function correctly will not be initialized properly.
@@ -110,9 +110,9 @@ namespace cereal
@param ptr Raw pointer held by the shared_ptr @param ptr Raw pointer held by the shared_ptr
@internal */ @internal */
template <class Archive, class T> inline template <class Archive, class T> inline
void loadAndAllocateSharedPtr( Archive & ar, T * ptr, std::true_type /* has_shared_from_this */ ) void loadAndConstructSharedPtr( Archive & ar, T * ptr, std::true_type /* has_shared_from_this */ )
{ {
memory_detail::LoadAndAllocateLoadWrapper<Archive, T> loadWrapper( ptr ); memory_detail::LoadAndConstructLoadWrapper<Archive, T> loadWrapper( ptr );
// typedefs for parent type and storage type // typedefs for parent type and storage type
using BaseType = typename ::cereal::traits::get_shared_from_this_base<T>::type; using BaseType = typename ::cereal::traits::get_shared_from_this_base<T>::type;
@@ -143,7 +143,7 @@ namespace cereal
ar( _CEREAL_NVP("ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) ); ar( _CEREAL_NVP("ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
} }
//! Loading std::shared_ptr, case when no user load and allocate for non polymorphic types //! Loading std::shared_ptr, case when no user load and construct for non polymorphic types
template <class Archive, class T> inline template <class Archive, class T> inline
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
load( Archive & ar, std::shared_ptr<T> & ptr ) load( Archive & ar, std::shared_ptr<T> & ptr )
@@ -178,7 +178,7 @@ namespace cereal
ar( _CEREAL_NVP("ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) ); ar( _CEREAL_NVP("ptr_wrapper", memory_detail::make_ptr_wrapper( ptr )) );
} }
//! Loading std::unique_ptr, case when user provides load_and_allocate for non polymorphic types //! Loading std::unique_ptr, case when user provides load_and_construct for non polymorphic types
template <class Archive, class T, class D> inline template <class Archive, class T, class D> inline
typename std::enable_if<!std::is_polymorphic<T>::value, void>::type typename std::enable_if<!std::is_polymorphic<T>::value, void>::type
load( Archive & ar, std::unique_ptr<T, D> & ptr ) load( Archive & ar, std::unique_ptr<T, D> & ptr )
@@ -205,10 +205,10 @@ namespace cereal
} }
} }
//! Loading std::shared_ptr, case when user load and allocate (wrapper implementation) //! Loading std::shared_ptr, case when user load and construct (wrapper implementation)
/*! @internal */ /*! @internal */
template <class Archive, class T> inline template <class Archive, class T> inline
typename std::enable_if<traits::has_load_and_allocate<T, Archive>::value, void>::type typename std::enable_if<traits::has_load_and_construct<T, Archive>::value, void>::type
load( Archive & ar, memory_detail::PtrWrapper<std::shared_ptr<T> &> & wrapper ) load( Archive & ar, memory_detail::PtrWrapper<std::shared_ptr<T> &> & wrapper )
{ {
auto & ptr = wrapper.ptr; auto & ptr = wrapper.ptr;
@@ -243,7 +243,7 @@ namespace cereal
ar.registerSharedPointer( id, ptr ); ar.registerSharedPointer( id, ptr );
// Perform the actual loading and allocation // Perform the actual loading and allocation
memory_detail::loadAndAllocateSharedPtr( ar, ptr.get(), typename ::cereal::traits::has_shared_from_this<T>::type() ); memory_detail::loadAndConstructSharedPtr( ar, ptr.get(), typename ::cereal::traits::has_shared_from_this<T>::type() );
// Mark pointer as valid (initialized) // Mark pointer as valid (initialized)
*valid = true; *valid = true;
@@ -252,10 +252,10 @@ namespace cereal
ptr = std::static_pointer_cast<T>(ar.getSharedPointer(id)); ptr = std::static_pointer_cast<T>(ar.getSharedPointer(id));
} }
//! Loading std::shared_ptr, case when no user load and allocate (wrapper implementation) //! Loading std::shared_ptr, case when no user load and construct (wrapper implementation)
/*! @internal */ /*! @internal */
template <class Archive, class T> inline template <class Archive, class T> inline
typename std::enable_if<!traits::has_load_and_allocate<T, Archive>::value, void>::type typename std::enable_if<!traits::has_load_and_construct<T, Archive>::value, void>::type
load( Archive & ar, memory_detail::PtrWrapper<std::shared_ptr<T> &> & wrapper ) load( Archive & ar, memory_detail::PtrWrapper<std::shared_ptr<T> &> & wrapper )
{ {
auto & ptr = wrapper.ptr; auto & ptr = wrapper.ptr;
@@ -266,7 +266,7 @@ namespace cereal
if( id & detail::msb_32bit ) if( id & detail::msb_32bit )
{ {
ptr.reset( detail::Load<T, Archive>::load_andor_allocate() ); ptr.reset( detail::Construct<T, Archive>::load_andor_construct() );
ar.registerSharedPointer( id, ptr ); ar.registerSharedPointer( id, ptr );
ar( _CEREAL_NVP("data", *ptr) ); ar( _CEREAL_NVP("data", *ptr) );
} }
@@ -294,10 +294,10 @@ namespace cereal
} }
} }
//! Loading std::unique_ptr, case when user provides load_and_allocate (wrapper implementation) //! Loading std::unique_ptr, case when user provides load_and_construct (wrapper implementation)
/*! @internal */ /*! @internal */
template <class Archive, class T, class D> inline template <class Archive, class T, class D> inline
typename std::enable_if<traits::has_load_and_allocate<T, Archive>::value, void>::type typename std::enable_if<traits::has_load_and_construct<T, Archive>::value, void>::type
load( Archive & ar, memory_detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper ) load( Archive & ar, memory_detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper )
{ {
uint8_t isValid; uint8_t isValid;
@@ -316,7 +316,7 @@ namespace cereal
std::unique_ptr<ST> stPtr( new ST() ); std::unique_ptr<ST> stPtr( new ST() );
// Use wrapper to enter into "data" nvp of ptr_wrapper // Use wrapper to enter into "data" nvp of ptr_wrapper
memory_detail::LoadAndAllocateLoadWrapper<Archive, T> loadWrapper( reinterpret_cast<T *>( stPtr.get() ) ); memory_detail::LoadAndConstructLoadWrapper<Archive, T> loadWrapper( reinterpret_cast<T *>( stPtr.get() ) );
// Initialize storage // Initialize storage
ar( _CEREAL_NVP("data", loadWrapper) ); ar( _CEREAL_NVP("data", loadWrapper) );
@@ -328,10 +328,10 @@ namespace cereal
ptr.reset( nullptr ); ptr.reset( nullptr );
} }
//! Loading std::unique_ptr, case when no load_and_allocate (wrapper implementation) //! Loading std::unique_ptr, case when no load_and_construct (wrapper implementation)
/*! @internal */ /*! @internal */
template <class Archive, class T, class D> inline template <class Archive, class T, class D> inline
typename std::enable_if<!traits::has_load_and_allocate<T, Archive>::value, void>::type typename std::enable_if<!traits::has_load_and_construct<T, Archive>::value, void>::type
load( Archive & ar, memory_detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper ) load( Archive & ar, memory_detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper )
{ {
uint8_t isValid; uint8_t isValid;
@@ -341,7 +341,7 @@ namespace cereal
if( isValid ) if( isValid )
{ {
ptr.reset( detail::Load<T, Archive>::load_andor_allocate() ); ptr.reset( detail::Construct<T, Archive>::load_andor_construct() );
ar( *ptr ); ar( *ptr );
} }
else else

View File

@@ -133,7 +133,7 @@ namespace cereal
@internal */ @internal */
template<class Archive, class T> inline template<class Archive, class T> inline
typename std::enable_if<(std::is_default_constructible<T>::value typename std::enable_if<(std::is_default_constructible<T>::value
|| traits::has_load_and_allocate<T, Archive>::value) || traits::has_load_and_construct<T, Archive>::value)
&& !std::is_abstract<T>::value, bool>::type && !std::is_abstract<T>::value, bool>::type
serialize_wrapper(Archive & ar, std::shared_ptr<T> & ptr, std::uint32_t const nameid) serialize_wrapper(Archive & ar, std::shared_ptr<T> & ptr, std::uint32_t const nameid)
{ {
@@ -151,7 +151,7 @@ namespace cereal
@internal */ @internal */
template<class Archive, class T, class D> inline template<class Archive, class T, class D> inline
typename std::enable_if<(std::is_default_constructible<T>::value typename std::enable_if<(std::is_default_constructible<T>::value
|| traits::has_load_and_allocate<T, Archive>::value) || traits::has_load_and_construct<T, Archive>::value)
&& !std::is_abstract<T>::value, bool>::type && !std::is_abstract<T>::value, bool>::type
serialize_wrapper(Archive & ar, std::unique_ptr<T, D> & ptr, std::uint32_t const nameid) serialize_wrapper(Archive & ar, std::unique_ptr<T, D> & ptr, std::uint32_t const nameid)
{ {
@@ -171,12 +171,12 @@ namespace cereal
@internal */ @internal */
template<class Archive, class T> inline template<class Archive, class T> inline
typename std::enable_if<(!std::is_default_constructible<T>::value typename std::enable_if<(!std::is_default_constructible<T>::value
&& !traits::has_load_and_allocate<T, Archive>::value) && !traits::has_load_and_construct<T, Archive>::value)
|| std::is_abstract<T>::value, bool>::type || std::is_abstract<T>::value, bool>::type
serialize_wrapper(Archive &, std::shared_ptr<T> &, std::uint32_t const nameid) serialize_wrapper(Archive &, std::shared_ptr<T> &, std::uint32_t const nameid)
{ {
if(nameid & detail::msb2_32bit) if(nameid & detail::msb2_32bit)
throw cereal::Exception("Cannot load a polymorphic type that is not default constructable and does not have a load_and_allocate function"); throw cereal::Exception("Cannot load a polymorphic type that is not default constructable and does not have a load_and_construct function");
return false; return false;
} }
@@ -188,12 +188,12 @@ namespace cereal
@internal */ @internal */
template<class Archive, class T, class D> inline template<class Archive, class T, class D> inline
typename std::enable_if<(!std::is_default_constructible<T>::value typename std::enable_if<(!std::is_default_constructible<T>::value
&& !traits::has_load_and_allocate<T, Archive>::value) && !traits::has_load_and_construct<T, Archive>::value)
|| std::is_abstract<T>::value, bool>::type || std::is_abstract<T>::value, bool>::type
serialize_wrapper(Archive &, std::unique_ptr<T, D> &, std::uint32_t const nameid) serialize_wrapper(Archive &, std::unique_ptr<T, D> &, std::uint32_t const nameid)
{ {
if(nameid & detail::msb2_32bit) if(nameid & detail::msb2_32bit)
throw cereal::Exception("Cannot load a polymorphic type that is not default constructable and does not have a load_and_allocate function"); throw cereal::Exception("Cannot load a polymorphic type that is not default constructable and does not have a load_and_construct function");
return false; return false;
} }
} // polymorphic_detail } // polymorphic_detail
@@ -360,7 +360,7 @@ namespace cereal
binding->second.unique_ptr(&ar, ptr.get()); binding->second.unique_ptr(&ar, ptr.get());
} }
//! Loading std::unique_ptr, case when user provides load_and_allocate for polymorphic types //! Loading std::unique_ptr, case when user provides load_and_construct for polymorphic types
template <class Archive, class T, class D> inline template <class Archive, class T, class D> inline
typename std::enable_if<std::is_polymorphic<T>::value, void>::type typename std::enable_if<std::is_polymorphic<T>::value, void>::type
load( Archive & ar, std::unique_ptr<T, D> & ptr ) load( Archive & ar, std::unique_ptr<T, D> & ptr )

View File

@@ -261,27 +261,27 @@ public:
} }
template <class Archive> template <class Archive>
static void load_and_allocate( Archive & ar, cereal::allocate<NoDefaultCtor> & allocate ) static void load_and_construct( Archive & ar, cereal::construct<NoDefaultCtor> & construct )
{ {
int y; int y;
ar( y ); ar( y );
allocate( y ); construct( y );
allocate->z = 33; construct->z = 33;
allocate.ptr()->z = 33; construct.ptr()->z = 33;
} }
}; };
//namespace cereal //namespace cereal
//{ //{
// template <> // template <>
// struct LoadAndAllocate<NoDefaultCtor> // struct LoadAndConstruct<NoDefaultCtor>
// { // {
// template <class Archive> // template <class Archive>
// static void load_and_allocate( Archive & ar, cereal::allocate<NoDefaultCtor> & allocate ) // static void load_and_construct( Archive & ar, cereal::construct<NoDefaultCtor> & construct )
// { // {
// int y; // int y;
// ar( y ); // ar( y );
// allocate( y ); // construct( y );
// } // }
// }; // };
//} //}

View File

@@ -63,7 +63,7 @@ struct Test
} }
template <class Archive> template <class Archive>
static Test * load_and_allocate( Archive & ) static Test * load_and_construct( Archive & )
{ {
return new Test(); return new Test();
} }
@@ -84,12 +84,12 @@ void save( Archive &, Test const & )
namespace cereal namespace cereal
{ {
template <> template <>
struct LoadAndAllocate<Test> struct LoadAndConstruct<Test>
{ {
template <class Archive> template <class Archive>
static void load_and_allocate( Archive &, cereal::allocate<Test> & allocate ) static void load_and_construct( Archive &, cereal::construct<Test> & construct )
{ {
allocate(); construct();
} }
}; };
} }
@@ -130,10 +130,10 @@ int main()
typedef Test T; typedef Test T;
std::cout << std::boolalpha; std::cout << std::boolalpha;
// Test Load and Allocate internal/external // Test Load and Construct internal/external
std::cout << "\tload_and_allocate" << std::endl; std::cout << "\tload_and_construct" << std::endl;
std::cout << cereal::traits::has_member_load_and_allocate<T, Archive>::value << std::endl; std::cout << cereal::traits::has_member_load_and_construct<T, Archive>::value << std::endl;
std::cout << cereal::traits::has_non_member_load_and_allocate<T, Archive>::value << std::endl; std::cout << cereal::traits::has_non_member_load_and_construct<T, Archive>::value << std::endl;
// serialize // serialize
std::cout << "\tserialize" << std::endl; std::cout << "\tserialize" << std::endl;
@@ -172,7 +172,7 @@ int main()
// array size // array size
std::cout << typeid(A).name() << std::endl; std::cout << typeid(A).name() << std::endl;
std::cout << typeid(cereal::traits::has_load_and_allocate<int, bool>).name() << std::endl; std::cout << typeid(cereal::traits::has_load_and_construct<int, bool>).name() << std::endl;
// extra testing // extra testing

View File

@@ -1042,20 +1042,20 @@ std::ostream& operator<<(std::ostream& os, MemoryCycle const & s)
return os; return os;
} }
class MemoryCycleLoadAndAllocate class MemoryCycleLoadAndConstruct
{ {
public: public:
MemoryCycleLoadAndAllocate( int v ) : MemoryCycleLoadAndConstruct( int v ) :
value( v ) value( v )
{ } { }
MemoryCycleLoadAndAllocate( int v, MemoryCycleLoadAndConstruct( int v,
std::weak_ptr<MemoryCycleLoadAndAllocate> p ) : std::weak_ptr<MemoryCycleLoadAndConstruct> p ) :
value( v ), value( v ),
ptr( p ) ptr( p )
{ } { }
bool operator==( MemoryCycleLoadAndAllocate const & other ) const bool operator==( MemoryCycleLoadAndConstruct const & other ) const
{ {
return value == other.value && ptr.lock() == other.ptr.lock(); return value == other.value && ptr.lock() == other.ptr.lock();
} }
@@ -1067,20 +1067,20 @@ class MemoryCycleLoadAndAllocate
} }
template <class Archive> template <class Archive>
static void load_and_allocate( Archive & ar, cereal::allocate<MemoryCycleLoadAndAllocate> & allocate ) static void load_and_construct( Archive & ar, cereal::construct<MemoryCycleLoadAndConstruct> & construct )
{ {
int value; int value;
std::weak_ptr<MemoryCycleLoadAndAllocate> ptr; std::weak_ptr<MemoryCycleLoadAndConstruct> ptr;
ar( value, ptr ); ar( value, ptr );
allocate( value, ptr ); construct( value, ptr );
} }
int value; int value;
std::weak_ptr<MemoryCycleLoadAndAllocate> ptr; std::weak_ptr<MemoryCycleLoadAndConstruct> ptr;
}; };
std::ostream& operator<<(std::ostream& os, MemoryCycleLoadAndAllocate const & s) std::ostream& operator<<(std::ostream& os, MemoryCycleLoadAndConstruct const & s)
{ {
os << "[value: " << s.value << " ptr: " << s.ptr.lock() << "]"; os << "[value: " << s.value << " ptr: " << s.ptr.lock() << "]";
return os; return os;
@@ -1096,7 +1096,7 @@ void test_memory_cycles()
{ {
auto o_ptr1 = std::make_shared<MemoryCycle>( random_value<int>(gen) ); auto o_ptr1 = std::make_shared<MemoryCycle>( random_value<int>(gen) );
o_ptr1->ptr = o_ptr1; o_ptr1->ptr = o_ptr1;
auto o_ptr2 = std::make_shared<MemoryCycleLoadAndAllocate>( random_value<int>(gen) ); auto o_ptr2 = std::make_shared<MemoryCycleLoadAndConstruct>( random_value<int>(gen) );
o_ptr2->ptr = o_ptr2; o_ptr2->ptr = o_ptr2;
std::ostringstream os; std::ostringstream os;
@@ -1157,11 +1157,11 @@ struct OneLA
{ ar( x ); } { ar( x ); }
template <class Archive> template <class Archive>
static void load_and_allocate( Archive & ar, cereal::allocate<OneLA> & allocate ) static void load_and_construct( Archive & ar, cereal::construct<OneLA> & construct )
{ {
int xx; int xx;
ar( xx ); ar( xx );
allocate( xx ); construct( xx );
} }
bool operator==( OneLA const & other ) const bool operator==( OneLA const & other ) const
@@ -1197,14 +1197,14 @@ std::ostream& operator<<(std::ostream& os, TwoLA const & s)
namespace cereal namespace cereal
{ {
template <> template <>
struct LoadAndAllocate<TwoLA> struct LoadAndConstruct<TwoLA>
{ {
template <class Archive> template <class Archive>
static void load_and_allocate( Archive & ar, cereal::allocate<TwoLA> & allocate ) static void load_and_construct( Archive & ar, cereal::construct<TwoLA> & construct )
{ {
int xx; int xx;
ar( xx ); ar( xx );
allocate( xx ); construct( xx );
} }
}; };
} }
@@ -1223,11 +1223,11 @@ struct ThreeLA : std::enable_shared_from_this<ThreeLA>
{ return x == other.x; } { return x == other.x; }
template <class Archive> template <class Archive>
static void load_and_allocate( Archive & ar, cereal::allocate<ThreeLA> & allocate ) static void load_and_construct( Archive & ar, cereal::construct<ThreeLA> & construct )
{ {
int xx; int xx;
ar( xx ); ar( xx );
allocate( xx ); construct( xx );
} }
}; };
@@ -1238,7 +1238,7 @@ std::ostream& operator<<(std::ostream& os, ThreeLA const & s)
} }
template <class IArchive, class OArchive> template <class IArchive, class OArchive>
void test_memory_load_allocate() void test_memory_load_construct()
{ {
std::random_device rd; std::random_device rd;
std::mt19937 gen(rd()); std::mt19937 gen(rd());
@@ -1290,24 +1290,24 @@ void test_memory_load_allocate()
} }
} }
BOOST_AUTO_TEST_CASE( binary_memory_load_allocate ) BOOST_AUTO_TEST_CASE( binary_memory_load_construct )
{ {
test_memory_load_allocate<cereal::BinaryInputArchive, cereal::BinaryOutputArchive>(); test_memory_load_construct<cereal::BinaryInputArchive, cereal::BinaryOutputArchive>();
} }
BOOST_AUTO_TEST_CASE( portable_binary_memory_load_allocate ) BOOST_AUTO_TEST_CASE( portable_binary_memory_load_construct )
{ {
test_memory_load_allocate<cereal::PortableBinaryInputArchive, cereal::PortableBinaryOutputArchive>(); test_memory_load_construct<cereal::PortableBinaryInputArchive, cereal::PortableBinaryOutputArchive>();
} }
BOOST_AUTO_TEST_CASE( xml_memory_load_allocate ) BOOST_AUTO_TEST_CASE( xml_memory_load_construct )
{ {
test_memory_load_allocate<cereal::XMLInputArchive, cereal::XMLOutputArchive>(); test_memory_load_construct<cereal::XMLInputArchive, cereal::XMLOutputArchive>();
} }
BOOST_AUTO_TEST_CASE( json_memory_load_allocate ) BOOST_AUTO_TEST_CASE( json_memory_load_construct )
{ {
test_memory_load_allocate<cereal::JSONInputArchive, cereal::JSONOutputArchive>(); test_memory_load_construct<cereal::JSONInputArchive, cereal::JSONOutputArchive>();
} }
// ###################################################################### // ######################################################################
@@ -3152,11 +3152,11 @@ struct PolyDerivedLA : public PolyLA
} }
template <class Archive> template <class Archive>
static void load_and_allocate( Archive & ar, cereal::allocate<PolyDerivedLA> & allocate ) static void load_and_construct( Archive & ar, cereal::construct<PolyDerivedLA> & construct )
{ {
int xx; int xx;
ar( xx ); ar( xx );
allocate( xx ); construct( xx );
} }
void foo() {} void foo() {}