#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP #define BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // // demo_xml.hpp // // (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include #include #include // This illustration models the bus system of a small city. // This includes, multiple bus stops, bus routes and schedules. // There are different kinds of stops. Bus stops in general will // will appear on multiple routes. A schedule will include // muliple trips on the same route. ///////////////////////////////////////////////////////////// // gps coordinate // // llustrates serialization for a simple type // class gps_position { friend class boost::serialization::access; friend std::ostream & operator<<(std::ostream &os, const gps_position &gp); int degrees; int minutes; float seconds; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & BOOST_SERIALIZATION_NVP(degrees) & BOOST_SERIALIZATION_NVP(minutes) & BOOST_SERIALIZATION_NVP(seconds); } public: // every serializable class needs a constructor gps_position(){}; gps_position(int _d, int _m, float _s) : degrees(_d), minutes(_m), seconds(_s) {} }; std::ostream & operator<<(std::ostream &os, const gps_position &gp) { return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"'; } ///////////////////////////////////////////////////////////// // One bus stop // // illustrates serialization of serializable members // class bus_stop { friend class boost::serialization::access; virtual std::string description() const = 0; gps_position latitude; gps_position longitude; template void serialize(Archive &ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(latitude); ar & BOOST_SERIALIZATION_NVP(longitude); } protected: bus_stop(const gps_position & _lat, const gps_position & _long) : latitude(_lat), longitude(_long) {} public: bus_stop(){} friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp); virtual ~bus_stop(){} }; BOOST_IS_ABSTRACT(bus_stop) std::ostream & operator<<(std::ostream &os, const bus_stop &bs) { return os << bs.latitude << bs.longitude << ' ' << bs.description(); } ///////////////////////////////////////////////////////////// // Several kinds of bus stops // // illustrates serialization of derived types // class bus_stop_corner : public bus_stop { friend class boost::serialization::access; std::string street1; std::string street2; virtual std::string description() const { return street1 + " and " + street2; } template void serialize(Archive &ar, const unsigned int version) { // save/load base class information ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop); ar & BOOST_SERIALIZATION_NVP(street1); ar & BOOST_SERIALIZATION_NVP(street2); } public: bus_stop_corner(){} bus_stop_corner(const gps_position & _lat, const gps_position & _long, const std::string & _s1, const std::string & _s2 ) : bus_stop(_lat, _long), street1(_s1), street2(_s2) { } }; class bus_stop_destination : public bus_stop { friend class boost::serialization::access; std::string name; virtual std::string description() const { return name; } template void serialize(Archive &ar, const unsigned int version) { ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop) & BOOST_SERIALIZATION_NVP(name); } public: bus_stop_destination(){} bus_stop_destination( const gps_position & _lat, const gps_position & _long, const std::string & _name ) : bus_stop(_lat, _long), name(_name) { } }; ///////////////////////////////////////////////////////////// // a bus route is a collection of bus stops // // illustrates serialization of STL collection templates. // // illustrates serialzation of polymorphic pointer (bus stop *); // // illustrates storage and recovery of shared pointers is correct // and efficient. That is objects pointed to by more than one // pointer are stored only once. In such cases only one such // object is restored and pointers are restored to point to it // class bus_route { friend class boost::serialization::access; friend std::ostream & operator<<(std::ostream &os, const bus_route &br); typedef bus_stop * bus_stop_pointer; std::list stops; template void serialize(Archive &ar, const unsigned int version) { // in this program, these classes are never serialized directly but rather // through a pointer to the base class bus_stop. So we need a way to be // sure that the archive contains information about these derived classes. //ar.template register_type(); ar.register_type(static_cast(NULL)); //ar.template register_type(); ar.register_type(static_cast(NULL)); // serialization of stl collections is already defined // in the header ar & BOOST_SERIALIZATION_NVP(stops); } public: bus_route(){} void append(bus_stop *_bs) { stops.insert(stops.end(), _bs); } }; std::ostream & operator<<(std::ostream &os, const bus_route &br) { std::list::const_iterator it; // note: we're displaying the pointer to permit verification // that duplicated pointers are properly restored. for(it = br.stops.begin(); it != br.stops.end(); it++){ os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it; } return os; } ///////////////////////////////////////////////////////////// // a bus schedule is a collection of routes each with a starting time // // Illustrates serialization of STL objects(pair) in a non-intrusive way. // See definition of operator<< >(ar, pair) // // illustrates nesting of serializable classes // // illustrates use of version number to automatically grandfather older // versions of the same class. class bus_schedule { friend class boost::serialization::access; friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs); template void serialize(Archive &ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(schedule); } // note: this structure was made public. because the friend declarations // didn't seem to work as expected. public: struct trip_info { template void serialize(Archive &ar, const unsigned int file_version) { // in versions 2 or later if(file_version >= 2) // read the drivers name ar & BOOST_SERIALIZATION_NVP(driver); // all versions have the follwing info ar & BOOST_SERIALIZATION_NVP(hour) & BOOST_SERIALIZATION_NVP(minute); } // starting time int hour; int minute; // only after system shipped was the driver's name added to the class std::string driver; trip_info(){} trip_info(int _h, int _m, const std::string &_d) : hour(_h), minute(_m), driver(_d) {} ~trip_info(){ } }; // friend std::ostream & operator<<(std::ostream &os, const trip_info &ti); private: std::list > schedule; public: void append(const std::string &_d, int _h, int _m, bus_route *_br) { schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br)); } bus_schedule(){} }; BOOST_CLASS_VERSION(bus_schedule::trip_info, 3) BOOST_CLASS_VERSION(bus_schedule, 2) std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti) { return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' '; } std::ostream & operator<<(std::ostream &os, const bus_schedule &bs) { std::list >::const_iterator it; for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){ os << it->first << *(it->second); } return os; } #endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP