#include #include #include #include #include // std::size_t #include #include #include #include #include #include #include #include //#define NVP BOOST_SERIALIZATION_NVP #define NVP(f) boost::serialization::make_nvp(#f, f ## _); namespace internal { class entity { public: enum { is_pimpl = 1 }; entity(int id) : id_(id) { } template void serialize(Archive& ar, const unsigned int version) { ar & NVP(id); } private: int id_; }; class unit : public entity { public: unit() : entity(0) { } unit(int id, const std::string& name) : entity(id), name_(name) { } template void serialize(Archive& ar, const unsigned int version) { //ar & boost::serialization::base_object(*this); ar & NVP(name); } private: std::string name_; }; } class entity { }; class unit : public entity { public: enum { is_sql_object = 1 }; unit(int id, const std::string& name) : data_(new internal::unit(id, name)) { } ~unit() { delete data_; } template void serialize(Archive& ar, const unsigned int version) { ar & NVP(data); } private: internal::unit* data_; }; class sql_oarchive : public boost::archive::detail::common_oarchive { // permit serialization system privileged access to permit // implementation of inline templates for maximum speed. friend class boost::archive::save_access; friend class boost::archive::detail::interface_oarchive; public: sql_oarchive(std::ostream& out, const std::string& table_name) : out_(out), table_name_(table_name), first_(true) { } void save_binary(void* address, std::size_t count) { std::cout << "save_binary" << std::endl; } // member template for saving primitive types. // Specialize for any types/templates that special treatment template void save(T& t) { out_ << t; } template void save_override(T& t, int, typename boost::enable_if_c< T::is_sql_object >::type* = 0) { out_ << "UPDATE " << table_name_.c_str() << " SET "; typedef boost::archive::detail::common_oarchive detail_common_oarchive; this->detail_common_oarchive::save_override(t, 0); out_ << ";\n"; } template void save_override(const boost::serialization::nvp& nvp, int) { typedef boost::archive::detail::common_oarchive detail_common_oarchive; if (not first_) out_ << ", "; out_ << nvp.name() << " = '"; this->detail_common_oarchive::save_override(nvp.const_value(), 0); out_ << "'"; first_ = false; } void save_override(const boost::archive::object_id_type & t, int) { } void save_override(const boost::archive::object_reference_type & t, int) { } void save_override(const boost::archive::version_type & t, int) { } void save_override(const boost::archive::class_id_type & t, int) { } void save_override(const boost::archive::class_id_optional_type & t, int) { } void save_override(const boost::archive::class_id_reference_type & t, int) { } void save_override(const boost::archive::class_name_type & t, int) { } void save_override(const boost::archive::tracking_type & t, int) { } private: std::ostream& out_; const std::string& table_name_; bool first_; }; BOOST_SERIALIZATION_REGISTER_ARCHIVE(sql_oarchive) BOOST_CLASS_EXPORT(internal::unit) #if 0 namespace boost { namespace archive { namespace detail { template <> bool archive_serializer_map::insert(boost::archive::detail::basic_serializer const*) { } template <> void archive_serializer_map::erase(boost::archive::detail::basic_serializer const*) { } } } } #endif int main() { { boost::archive::detail::archive_serializer_map junk; } unit u(42, "John Doe"); { boost::archive::xml_oarchive oa(std::cout); oa << BOOST_SERIALIZATION_NVP(u); } std::cout << "-------------------------" << std::endl; { sql_oarchive sql(std::cout, "unit"); sql << u; } }