#include #include #include #include #include #include #include #include #include #include #include #include using boost::any_cast; using std::cout; using std::endl; // ------------------------------------------------------------------------- // intrusive serialization of fooA, fooB struct fooA { fooA (int t = 0) : t_ (t) {}; int t_; friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & t_; }; }; struct fooB { fooB (double t = 0) : t_ (t) {}; double t_; friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & t_; }; }; // uncomment this to get into trouble deserializing fooA after the first call // //BOOST_CLASS_EXPORT (fooA) // // ------------------------------------------------------------------------- // wrapper class used as interface for reg_serialize/reg_deserialize template struct wo_base { // cannot instantiate pure virtual in container as base, stay virtual virtual void serialize(Archive & , boost::any ) {}; virtual void deserialize(Archive & , boost::any &) {}; }; template struct wo_impl : public wo_base { virtual void serialize(Archive & ar, boost::any data) { T t = any_cast (data); cout << "(archive) serializing value ((" << t.t_ << ")) " << __PRETTY_FUNCTION__ << endl; ar & t; } virtual void deserialize(Archive & ar, boost::any &data) { T t; ar & t; data = t; cout << "(archive) deserialized value ((" << t.t_ << ")) " << __PRETTY_FUNCTION__ << endl; } }; template struct register_all { // ctor register_all () { register_type ("fooA"); register_type ("fooB"); }; template void register_type (std::string name) { p [name] = new wo_impl (); t [typeid (T).name ()] = name; } // assign object to registered name std::map *> p; // mapping from registered name to typeid std::map t; }; template void reg_serialize ( register_all reg, Archive & ar, boost::any data ) { typename std::map *>::iterator it; typename std::map ::iterator itt; itt = reg.t.find (data.type ().name ()); if (itt != reg.t.end ()) { std::string id = itt->second; it = reg.p.find (id); if (it != reg.p.end ()) { // typename ar << id; // data it->second->serialize (ar, data); } else cout << __PRETTY_FUNCTION__ << " type lookup failed." << endl; } else cout << __PRETTY_FUNCTION__ << " typeid lookup failed." << endl; } template void reg_deserialize ( register_all reg, Archive & ar, boost::any & data ) { typename std::map *>::iterator it; std::string id; ar >> id; it = reg.p.find (id); if (it != reg.p.end ()) it->second->deserialize (ar, data); }; // ------------------------------------------------------------------------- int main () { // create a typeid-typename mapping register_all ore; boost::any t1 = fooA (10); boost::any t2 = fooB (1.5); boost::any t3 = fooB (2.5); boost::any t4 = fooA (20); std::ofstream os ("test.txt"); boost::archive::text_oarchive oa (os); reg_serialize (ore, oa, t1); reg_serialize (ore, oa, t2); reg_serialize (ore, oa, t3); reg_serialize (ore, oa, t4); os.close (); // create a typeid-typename mapping register_all ire; std::ifstream is ("test.txt"); boost::archive::text_iarchive ia (is); boost::any to; reg_deserialize (ire, ia, to); reg_deserialize (ire, ia, to); reg_deserialize (ire, ia, to); reg_deserialize (ire, ia, to); is.close (); }