123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
- // demo.cpp
- //
- // (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 <cstddef> // NULL
- #include <iomanip>
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <boost/archive/tmpdir.hpp>
- #include <boost/archive/text_iarchive.hpp>
- #include <boost/archive/text_oarchive.hpp>
- #include <boost/serialization/base_object.hpp>
- #include <boost/serialization/utility.hpp>
- #include <boost/serialization/list.hpp>
- #include <boost/serialization/assume_abstract.hpp>
- /////////////////////////////////////////////////////////////
- // The intent of this program is to serve as a tutorial for
- // users of the serialization package. An attempt has been made
- // to illustrate most of the facilities of the package.
- //
- // The intent is to create an example suffciently complete to
- // illustrate the usage and utility of the package while
- // including a minimum of other code.
- //
- // 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 std::ostream & operator<<(std::ostream &os, const gps_position &gp);
- friend class boost::serialization::access;
- int degrees;
- int minutes;
- float seconds;
- template<class Archive>
- void serialize(Archive & ar, const unsigned int /* file_version */){
- ar & degrees & minutes & 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;
- friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
- virtual std::string description() const = 0;
- gps_position latitude;
- gps_position longitude;
- template<class Archive>
- void serialize(Archive &ar, const unsigned int version)
- {
- ar & latitude;
- ar & longitude;
- }
- protected:
- bus_stop(const gps_position & _lat, const gps_position & _long) :
- latitude(_lat), longitude(_long)
- {}
- public:
- bus_stop(){}
- virtual ~bus_stop(){}
- };
- BOOST_SERIALIZATION_ASSUME_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<class Archive>
- void serialize(Archive &ar, const unsigned int version)
- {
- // save/load base class information
- ar & boost::serialization::base_object<bus_stop>(*this);
- ar & street1 & 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<class Archive>
- void serialize(Archive &ar, const unsigned int version)
- {
- ar & boost::serialization::base_object<bus_stop>(*this) & 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<bus_stop_pointer> stops;
- template<class Archive>
- 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<bus_stop_corner>();
- ar.register_type(static_cast<bus_stop_corner *>(NULL));
- //ar.template register_type<bus_stop_destination>();
- ar.register_type(static_cast<bus_stop_destination *>(NULL));
- // serialization of stl collections is already defined
- // in the header
- ar & 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<bus_stop *>::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<< <pair<F, S> >(ar, pair) and others in
- // serialization.hpp
- //
- // illustrates nesting of serializable classes
- //
- // illustrates use of version number to automatically grandfather older
- // versions of the same class.
- class bus_schedule
- {
- public:
- // note: this structure was made public. because the friend declarations
- // didn't seem to work as expected.
- struct trip_info
- {
- template<class Archive>
- void serialize(Archive &ar, const unsigned int file_version)
- {
- // in versions 2 or later
- if(file_version >= 2)
- // read the drivers name
- ar & driver;
- // all versions have the follwing info
- ar & hour & 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)
- {}
- };
- private:
- friend class boost::serialization::access;
- friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
- friend std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti);
- std::list<std::pair<trip_info, bus_route *> > schedule;
- template<class Archive>
- void serialize(Archive &ar, const unsigned int version)
- {
- ar & 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, 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<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
- for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
- os << it->first << *(it->second);
- }
- return os;
- }
- void save_schedule(const bus_schedule &s, const char * filename){
- // make an archive
- std::ofstream ofs(filename);
- boost::archive::text_oarchive oa(ofs);
- oa << s;
- }
- void
- restore_schedule(bus_schedule &s, const char * filename)
- {
- // open the archive
- std::ifstream ifs(filename);
- boost::archive::text_iarchive ia(ifs);
- // restore the schedule from the archive
- ia >> s;
- }
- int main(int argc, char *argv[])
- {
- // make the schedule
- bus_schedule original_schedule;
- // fill in the data
- // make a few stops
- bus_stop *bs0 = new bus_stop_corner(
- gps_position(34, 135, 52.560f),
- gps_position(134, 22, 78.30f),
- "24th Street", "10th Avenue"
- );
- bus_stop *bs1 = new bus_stop_corner(
- gps_position(35, 137, 23.456f),
- gps_position(133, 35, 54.12f),
- "State street", "Cathedral Vista Lane"
- );
- bus_stop *bs2 = new bus_stop_destination(
- gps_position(35, 136, 15.456f),
- gps_position(133, 32, 15.300f),
- "White House"
- );
- bus_stop *bs3 = new bus_stop_destination(
- gps_position(35, 134, 48.789f),
- gps_position(133, 32, 16.230f),
- "Lincoln Memorial"
- );
- // make a routes
- bus_route route0;
- route0.append(bs0);
- route0.append(bs1);
- route0.append(bs2);
- // add trips to schedule
- original_schedule.append("bob", 6, 24, &route0);
- original_schedule.append("bob", 9, 57, &route0);
- original_schedule.append("alice", 11, 02, &route0);
- // make aother routes
- bus_route route1;
- route1.append(bs3);
- route1.append(bs2);
- route1.append(bs1);
- // add trips to schedule
- original_schedule.append("ted", 7, 17, &route1);
- original_schedule.append("ted", 9, 38, &route1);
- original_schedule.append("alice", 11, 47, &route1);
- // display the complete schedule
- std::cout << "original schedule";
- std::cout << original_schedule;
-
- std::string filename(boost::archive::tmpdir());
- filename += "/demofile.txt";
- // save the schedule
- save_schedule(original_schedule, filename.c_str());
- // ... some time later
- // make a new schedule
- bus_schedule new_schedule;
- restore_schedule(new_schedule, filename.c_str());
- // and display
- std::cout << "\nrestored schedule";
- std::cout << new_schedule;
- // should be the same as the old one. (except for the pointer values)
- delete bs0;
- delete bs1;
- delete bs2;
- delete bs3;
- return 0;
- }
|