summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/serialization/example/demo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/serialization/example/demo.cpp')
-rw-r--r--src/boost/libs/serialization/example/demo.cpp377
1 files changed, 377 insertions, 0 deletions
diff --git a/src/boost/libs/serialization/example/demo.cpp b/src/boost/libs/serialization/example/demo.cpp
new file mode 100644
index 000000000..cfd212770
--- /dev/null
+++ b/src/boost/libs/serialization/example/demo.cpp
@@ -0,0 +1,377 @@
+/////////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;
+}