c++ - Registering user-provided derived types with Boost Serialization -
i writing library handle storing , serializing user-defined types. user-defined types required serializable.
however library uses templates create containers of user types. don't know how export container types boost::serialization through templates. way can force user of library boost_class_export_guid() every container type.
i've tried unpacking macro looking @ boost/serialization/export.hpp, complex... there way export class part of template instantiation? or way write library serialize containers of user-defined types?
#include <iostream> #include <vector> #include <boost/foreach.hpp> #include <boost/serialization/access.hpp> #include <boost/serialization/vector.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> #include <boost/archive/text_oarchive.hpp> ////////////////////////////////////////////////////////////////////////////// // example code reside in library ////////////////////////////////////////////////////////////////////////////// struct type_container_base { private: virtual void make_abstract() const {} friend class ::boost::serialization::access; template <typename archive> void serialize(archive &, const unsigned int) {} }; boost_serialization_assume_abstract(type_container_base) template <typename user_type> struct type_container : type_container_base { void add(const user_type& d) { _vector.push_back(d); } private: std::vector<user_type> _vector; friend class ::boost::serialization::access; template <typename archive> void serialize(archive & ar, const unsigned int) { ar & ::boost::serialization::base_object<type_container_base>(*this); ar & _vector; } }; ////////////////////////////////////////////////////////////////////////////// // example user code use library ////////////////////////////////////////////////////////////////////////////// struct user_type { user_type(int i) : _val(i) {} private: int _val; friend class ::boost::serialization::access; template <typename archive> void serialize(archive & ar, const unsigned int) { ar & _val; } }; // *** there better way forcing user every // *** user_type want use library? boost_class_export_guid(type_container<user_type>, "type_container<user_type>") int main() { std::vector<type_container_base*> containers; type_container<user_type>* tc = new type_container<user_type>(); tc->add(user_type(7)); tc->add(user_type(42)); tc->add(user_type(1776)); containers.push_back(tc); { boost::archive::text_oarchive ar(std::cout); const std::size_t size = containers.size(); ar << size; boost_foreach(type_container_base* p, containers) ar << p; } return 0; }
maybe along lines:
#define boost_class_template_export_implement(t) \ namespace boost { \ namespace archive { \ namespace detail { \ namespace { \ template<typename u> \ struct init_guid< t<u> > { \ static guid_initializer< t<u> > const & g; \ }; \ template<typename u> \ guid_initializer< t<u> > const & init_guid< t<u> >::g = \ ::boost::serialization::singleton< \ guid_initializer< t<u> > \ >::get_mutable_instance().export_guid(); \ }}}} \ /**/ #define boost_class_template_export_key2(t, k) \ namespace boost { \ namespace serialization { \ template<typename u> \ struct guid_defined< t<u> > : boost::mpl::true_ {}; \ template<typename u> \ inline const char * guid< t<u> >(){ \ return k + "<" + guid<u>() + ">"; //this doesn't work, know! \ } \ } /* serialization */ \ } /* boost */ \ /**/ #define boost_class_template_export_key(t) \ boost_class_template_export_key2(t, boost_pp_stringize(t)) \ /**/ #define boost_class_template_export_guid(t, k) \ boost_class_template_export_key2(t, k) \ boost_class_template_export_implement(t) \ /**/
it might work additional tweaks it. of course, assume user_type exported already. still, reduce combinatorial dimension, need 1 export per class , 1 export per class template, not 1 export per template instantiation (number of classes x number of class templates).
this kind of thing should asked / requested / proposed guy in charge of boost.serialization library (i guess robert ramey).
Comments
Post a Comment