Subject: Re: [Boost-bugs] [Boost C++ Libraries] #7047: Deriving custom archive classes from boost::archive::text_oarchive_impl and boost::archive::text_iarchive_impl
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-08-24 14:09:23
#7047: Deriving custom archive classes from boost::archive::text_oarchive_impl and
boost::archive::text_iarchive_impl
-------------------------------+---------------------------
Reporter: zachais.vawter@⦠| Owner: ramey
Type: Bugs | Status: new
Milestone: To Be Determined | Component: serialization
Version: Boost 1.48.0 | Severity: Problem
Resolution: | Keywords:
-------------------------------+---------------------------
Comment (by anonymous):
I had the same problem tying to implement custom archive for my library.
I've found a possible solution trick, it seems to works well so I'll share
with you:
There is no way to export a class with a modified serialization syntax in
boost archive, so we have to avoid it at all.
boost archive registration uses a properly overloaded function to make a
pointer serialization type instance ( as in
boost/archive/detail/register_archive.hpp )
{{{
# define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \
namespace boost { namespace archive { namespace detail { \
\
template <class Serializable> \
BOOST_DEDUCED_TYPENAME _ptr_serialization_support<Archive,
Serializable>::type \
instantiate_ptr_serialization( Serializable*, Archive*, adl_tag );
\
\
} } }
}}}
Note that adl_tag adds a cool overload feature that can be used to make
boost able to look inside our implementation. Simply put a new
registration declaration as this:
{{{
// ARCHIVES REGISTRATION //
namespace MyLib {
struct adl_tag {};
}
namespace boost { namespace archive { namespace detail {
template <class Serializable>
void instantiate_ptr_serialization(Serializable*, int, MyLib::adl_tag ) {}
} } }
# define MYLIB_SERIALIZATION_REGISTER_ARCHIVE(_Archive)
\
namespace boost { namespace archive { namespace detail { \
template <class Serializable> \
BOOST_DEDUCED_TYPENAME _ptr_serialization_support<_Archive,
Serializable>::type \
instantiate_ptr_serialization( Serializable*, _Archive*, MyLib::adl_tag );
} } }
}}}
Now you have to make your own EXPORT macro as in
(/boost/serialization/export.hpp):
{{{
namespace MyLib {
namespace extra_detail {
template<class T>
struct guid_initializer
{
void export_guid(mpl::false_) const {
// generates the statically-initialized objects whose constructors
// register the information allowing serialization of T objects
// through pointers to their base classes.
boost::archive::detail::
instantiate_ptr_serialization((T*)0, 0,
MyLib::adl_tag());
}
void export_guid(mpl::true_) const {
}
guid_initializer const & export_guid() const {
BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value);
// note: exporting an abstract base class will have no effect
// and cannot be used to instantitiate serialization code
// (one might be using this in a DLL to instantiate code)
//BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T
>::value);
export_guid(boost::serialization::is_abstract< T >());
return *this;
}
};
template<typename T>
struct init_guid;
} // extra_detail
} // namespace MyLib
#define MYLIB_CLASS_EXPORT_IMPLEMENT(T) \
namespace MyLib { \
namespace extra_detail { \
template<> \
struct init_guid< T > { \
static guid_initializer< T > const & g; \
}; \
guid_initializer< T > const & init_guid< T >::g = \
::boost::serialization::singleton< \
guid_initializer< T > \
>::get_mutable_instance().export_guid(); \
}} \
/**/
}}}
Ok it's all, now you can define your custom archive and register it with:
{{{
MYLIB_SERIALIZATION_REGISTER_ARCHIVE(MyLib::xml_iarchive)
}}}
and anytime you define a serialization for your class that has a
particular syntax only readable by MyLib::custom_archive you can use your
export implementation
{{{
BOOST_CLASS_EXPORT_KEY(MyClass) // in header
MYLIB_CLASS_EXPORT_IMPLEMENT(MyClass) // in cpp
}}}
(Note that exporting of Key remains the same of boost ... )
This is really cool because lets your custom archives and boost archives
live together without errors.. Anytime you wants a boost serialization
simply use BOOST_CLASS_EXPORT, and anytime you have your class to be
serialized use MYLIB_CLASS_EXPORT.
Hope that this could be useful !
Andrea Rigoni Garola
(OpenCMT - Cosmic Muon Tomography library)
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/7047#comment:3> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:13 UTC