1 #ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP
2 #define BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP
3 
4 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
5 //
6 // demo_gps.hpp
7 //
8 // (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
9 // Use, modification and distribution is subject to the Boost Software
10 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12 
13 #include <iomanip>
14 #include <iostream>
15 #include <fstream>
16 
17 #include <boost/serialization/string.hpp>
18 #include <boost/serialization/nvp.hpp>
19 #include <boost/serialization/utility.hpp>
20 #include <boost/serialization/list.hpp>
21 #include <boost/serialization/version.hpp>
22 #include <boost/serialization/assume_abstract.hpp>
23 
24 // This illustration models the bus system of a small city.
25 // This includes, multiple bus stops,  bus routes and schedules.
26 // There are different kinds of stops.  Bus stops in general will
27 // will appear on multiple routes.  A schedule will include
28 // muliple trips on the same route.
29 
30 /////////////////////////////////////////////////////////////
31 // gps coordinate
32 //
33 // llustrates serialization for a simple type
34 //
35 class gps_position
36 {
37     friend class boost::serialization::access;
38     friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
39 
40     int degrees;
41     int minutes;
42     float seconds;
43 
44     template<class Archive>
serialize(Archive & ar,const unsigned int)45     void serialize(Archive & ar, const unsigned int /* file_version */){
46         ar  & BOOST_SERIALIZATION_NVP(degrees)
47             & BOOST_SERIALIZATION_NVP(minutes)
48             & BOOST_SERIALIZATION_NVP(seconds);
49     }
50 
51 public:
52     // every serializable class needs a constructor
gps_position()53     gps_position(){};
gps_position(int _d,int _m,float _s)54     gps_position(int _d, int _m, float _s) :
55         degrees(_d), minutes(_m), seconds(_s)
56     {}
57 };
58 
operator <<(std::ostream & os,const gps_position & gp)59 std::ostream & operator<<(std::ostream &os, const gps_position &gp)
60 {
61     return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
62 }
63 
64 /////////////////////////////////////////////////////////////
65 // One bus stop
66 //
67 // illustrates serialization of serializable members
68 //
69 
70 class bus_stop
71 {
72     friend class boost::serialization::access;
73     virtual std::string description() const = 0;
74     gps_position latitude;
75     gps_position longitude;
76 
77     template<class Archive>
serialize(Archive & ar,const unsigned int version)78     void serialize(Archive &ar, const unsigned int version)
79     {
80         ar & BOOST_SERIALIZATION_NVP(latitude);
81         ar & BOOST_SERIALIZATION_NVP(longitude);
82     }
83 
84 protected:
bus_stop(const gps_position & _lat,const gps_position & _long)85     bus_stop(const gps_position & _lat, const gps_position & _long) :
86         latitude(_lat), longitude(_long)
87     {}
88 public:
bus_stop()89     bus_stop(){}
90     friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
~bus_stop()91     virtual ~bus_stop(){}
92 };
93 
94 BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)
95 
96 std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
97 {
98     return os << bs.latitude << bs.longitude << ' ' << bs.description();
99 }
100 
101 /////////////////////////////////////////////////////////////
102 // Several kinds of bus stops
103 //
104 // illustrates serialization of derived types
105 //
106 class bus_stop_corner : public bus_stop
107 {
108     friend class boost::serialization::access;
109     std::string street1;
110     std::string street2;
description() const111     virtual std::string description() const
112     {
113         return street1 + " and " + street2;
114     }
115     template<class Archive>
serialize(Archive & ar,const unsigned int version)116     void serialize(Archive &ar, const unsigned int version)
117     {
118         // save/load base class information
119         ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop);
120         ar & BOOST_SERIALIZATION_NVP(street1);
121         ar & BOOST_SERIALIZATION_NVP(street2);
122     }
123 public:
bus_stop_corner()124     bus_stop_corner(){}
bus_stop_corner(const gps_position & _lat,const gps_position & _long,const std::string & _s1,const std::string & _s2)125     bus_stop_corner(const gps_position & _lat, const gps_position & _long,
126         const std::string & _s1, const std::string & _s2
127     ) :
128         bus_stop(_lat, _long), street1(_s1), street2(_s2)
129     {
130     }
131 };
132 
133 class bus_stop_destination : public bus_stop
134 {
135     friend class boost::serialization::access;
136     std::string name;
description() const137     virtual std::string description() const
138     {
139         return name;
140     }
141     template<class Archive>
serialize(Archive & ar,const unsigned int version)142     void serialize(Archive &ar, const unsigned int version)
143     {
144         ar  & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop)
145             & BOOST_SERIALIZATION_NVP(name);
146     }
147 public:
bus_stop_destination()148     bus_stop_destination(){}
bus_stop_destination(const gps_position & _lat,const gps_position & _long,const std::string & _name)149     bus_stop_destination(
150         const gps_position & _lat, const gps_position & _long, const std::string & _name
151     ) :
152         bus_stop(_lat, _long), name(_name)
153     {
154     }
155 };
156 
157 /////////////////////////////////////////////////////////////
158 // a bus route is a collection of bus stops
159 //
160 // illustrates serialization of STL collection templates.
161 //
162 // illustrates serialzation of polymorphic pointer (bus stop *);
163 //
164 // illustrates storage and recovery of shared pointers is correct
165 // and efficient.  That is objects pointed to by more than one
166 // pointer are stored only once.  In such cases only one such
167 // object is restored and pointers are restored to point to it
168 //
169 class bus_route
170 {
171     friend class boost::serialization::access;
172     friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
173     typedef bus_stop * bus_stop_pointer;
174     std::list<bus_stop_pointer> stops;
175     template<class Archive>
serialize(Archive & ar,const unsigned int version)176     void serialize(Archive &ar, const unsigned int version)
177     {
178         // in this program, these classes are never serialized directly but rather
179         // through a pointer to the base class bus_stop. So we need a way to be
180         // sure that the archive contains information about these derived classes.
181         //ar.template register_type<bus_stop_corner>();
182         ar.register_type(static_cast<bus_stop_corner *>(NULL));
183         //ar.template register_type<bus_stop_destination>();
184         ar.register_type(static_cast<bus_stop_destination *>(NULL));
185         // serialization of stl collections is already defined
186         // in the header
187         ar & BOOST_SERIALIZATION_NVP(stops);
188     }
189 public:
bus_route()190     bus_route(){}
append(bus_stop * _bs)191     void append(bus_stop *_bs)
192     {
193         stops.insert(stops.end(), _bs);
194     }
195 };
operator <<(std::ostream & os,const bus_route & br)196 std::ostream & operator<<(std::ostream &os, const bus_route &br)
197 {
198     std::list<bus_stop *>::const_iterator it;
199     // note: we're displaying the pointer to permit verification
200     // that duplicated pointers are properly restored.
201     for(it = br.stops.begin(); it != br.stops.end(); it++){
202         os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
203     }
204     return os;
205 }
206 
207 /////////////////////////////////////////////////////////////
208 // a bus schedule is a collection of routes each with a starting time
209 //
210 // Illustrates serialization of STL objects(pair) in a non-intrusive way.
211 // See definition of operator<< <pair<F, S> >(ar, pair)
212 //
213 // illustrates nesting of serializable classes
214 //
215 // illustrates use of version number to automatically grandfather older
216 // versions of the same class.
217 
218 class bus_schedule
219 {
220     friend class boost::serialization::access;
221     friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
222     template<class Archive>
serialize(Archive & ar,const unsigned int version)223     void serialize(Archive &ar, const unsigned int version)
224     {
225         ar & BOOST_SERIALIZATION_NVP(schedule);
226     }
227     // note: this structure was made public. because the friend declarations
228     // didn't seem to work as expected.
229 public:
230     struct trip_info
231     {
232         template<class Archive>
serializebus_schedule::trip_info233         void serialize(Archive &ar, const unsigned int file_version)
234         {
235             // in versions 2 or later
236             if(file_version >= 2)
237                 // read the drivers name
238                 ar & BOOST_SERIALIZATION_NVP(driver);
239             // all versions have the follwing info
240             ar  & BOOST_SERIALIZATION_NVP(hour)
241                 & BOOST_SERIALIZATION_NVP(minute);
242         }
243 
244         // starting time
245         int hour;
246         int minute;
247         // only after system shipped was the driver's name added to the class
248         std::string driver;
249 
trip_infobus_schedule::trip_info250         trip_info(){}
trip_infobus_schedule::trip_info251         trip_info(int _h, int _m, const std::string &_d) :
252             hour(_h), minute(_m), driver(_d)
253         {}
~trip_infobus_schedule::trip_info254         ~trip_info(){
255         }
256     };
257 //  friend std::ostream & operator<<(std::ostream &os, const trip_info &ti);
258 private:
259     std::list<std::pair<trip_info, bus_route *> > schedule;
260 public:
append(const std::string & _d,int _h,int _m,bus_route * _br)261     void append(const std::string &_d, int _h, int _m, bus_route *_br)
262     {
263         schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
264     }
bus_schedule()265     bus_schedule(){}
266 };
267 
268 BOOST_CLASS_VERSION(bus_schedule::trip_info, 3)
269 BOOST_CLASS_VERSION(bus_schedule, 2)
270 
operator <<(std::ostream & os,const bus_schedule::trip_info & ti)271 std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
272 {
273     return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
274 }
operator <<(std::ostream & os,const bus_schedule & bs)275 std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
276 {
277     std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
278     for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
279         os << it->first << *(it->second);
280     }
281     return os;
282 }
283 
284 #endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP
285