Ticket #4660: demo.cpp

File demo.cpp, 11.6 KB (added by Sergey Voropaev <serge-voropaev@…>, 12 years ago)

demo.cpp with my modification

Line 
1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// demo.cpp
3//
4// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
5// Use, modification and distribution is subject to the Boost Software
6// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9
10#include <cstddef> // NULL
11#include <iomanip>
12#include <iostream>
13#include <fstream>
14#include <string>
15
16#include <boost/archive/tmpdir.hpp>
17
18#include <boost/archive/binary_iarchive.hpp>
19#include <boost/archive/binary_oarchive.hpp>
20
21#include <boost/serialization/base_object.hpp>
22#include <boost/serialization/utility.hpp>
23#include <boost/serialization/list.hpp>
24#include <boost/serialization/assume_abstract.hpp>
25
26/////////////////////////////////////////////////////////////
27// The intent of this program is to serve as a tutorial for
28// users of the serialization package. An attempt has been made
29// to illustrate most of the facilities of the package.
30//
31// The intent is to create an example suffciently complete to
32// illustrate the usage and utility of the package while
33// including a minimum of other code.
34//
35// This illustration models the bus system of a small city.
36// This includes, multiple bus stops, bus routes and schedules.
37// There are different kinds of stops. Bus stops in general will
38// will appear on multiple routes. A schedule will include
39// muliple trips on the same route.
40
41/////////////////////////////////////////////////////////////
42// gps coordinate
43//
44// llustrates serialization for a simple type
45//
46class gps_position
47{
48 friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
49 friend class boost::serialization::access;
50 int degrees;
51 int minutes;
52 float seconds;
53 template<class Archive>
54 void serialize(Archive & ar, const unsigned int /* file_version */){
55 ar & degrees & minutes & seconds;
56 }
57public:
58 // every serializable class needs a constructor
59 gps_position(){};
60 gps_position(int _d, int _m, float _s) :
61 degrees(_d), minutes(_m), seconds(_s)
62 {}
63};
64std::ostream & operator<<(std::ostream &os, const gps_position &gp)
65{
66 return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
67}
68
69/////////////////////////////////////////////////////////////
70// One bus stop
71//
72// illustrates serialization of serializable members
73//
74
75class bus_stop
76{
77 friend class boost::serialization::access;
78 friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
79 virtual std::string description() const = 0;
80 gps_position latitude;
81 gps_position longitude;
82 template<class Archive>
83 void serialize(Archive &ar, const unsigned int version)
84 {
85 ar & latitude;
86 ar & longitude;
87 }
88protected:
89 bus_stop(const gps_position & _lat, const gps_position & _long) :
90 latitude(_lat), longitude(_long)
91 {}
92public:
93 bus_stop(){}
94 virtual ~bus_stop(){}
95};
96
97BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)
98
99std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
100{
101 return os << bs.latitude << bs.longitude << ' ' << bs.description();
102}
103
104/////////////////////////////////////////////////////////////
105// Several kinds of bus stops
106//
107// illustrates serialization of derived types
108//
109class bus_stop_corner : public bus_stop
110{
111 friend class boost::serialization::access;
112 std::string street1;
113 std::string street2;
114 virtual std::string description() const
115 {
116 return street1 + " and " + street2;
117 }
118 template<class Archive>
119 void serialize(Archive &ar, const unsigned int version)
120 {
121 // save/load base class information
122 ar & boost::serialization::base_object<bus_stop>(*this);
123 ar & street1 & street2;
124 }
125
126public:
127 bus_stop_corner(){}
128 bus_stop_corner(const gps_position & _lat, const gps_position & _long,
129 const std::string & _s1, const std::string & _s2
130 ) :
131 bus_stop(_lat, _long), street1(_s1), street2(_s2)
132 {
133 }
134};
135
136class bus_stop_destination : public bus_stop
137{
138 friend class boost::serialization::access;
139 std::string name;
140 virtual std::string description() const
141 {
142 return name;
143 }
144 template<class Archive>
145 void serialize(Archive &ar, const unsigned int version)
146 {
147 ar & boost::serialization::base_object<bus_stop>(*this) & name;
148 }
149public:
150
151 bus_stop_destination(){}
152 bus_stop_destination(
153 const gps_position & _lat, const gps_position & _long, const std::string & _name
154 ) :
155 bus_stop(_lat, _long), name(_name)
156 {
157 }
158};
159
160/////////////////////////////////////////////////////////////
161// a bus route is a collection of bus stops
162//
163// illustrates serialization of STL collection templates.
164//
165// illustrates serialzation of polymorphic pointer (bus stop *);
166//
167// illustrates storage and recovery of shared pointers is correct
168// and efficient. That is objects pointed to by more than one
169// pointer are stored only once. In such cases only one such
170// object is restored and pointers are restored to point to it
171//
172class bus_route
173{
174 friend class boost::serialization::access;
175 friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
176 typedef bus_stop * bus_stop_pointer;
177 std::list<bus_stop_pointer> stops;
178 template<class Archive>
179 void serialize(Archive &ar, const unsigned int version)
180 {
181 // in this program, these classes are never serialized directly but rather
182 // through a pointer to the base class bus_stop. So we need a way to be
183 // sure that the archive contains information about these derived classes.
184 //ar.template register_type<bus_stop_corner>();
185 ar.register_type(static_cast<bus_stop_corner *>(NULL));
186 //ar.template register_type<bus_stop_destination>();
187 ar.register_type(static_cast<bus_stop_destination *>(NULL));
188 // serialization of stl collections is already defined
189 // in the header
190 ar & stops;
191 }
192public:
193 bus_route(){}
194 void append(bus_stop *_bs)
195 {
196 stops.insert(stops.end(), _bs);
197 }
198};
199std::ostream & operator<<(std::ostream &os, const bus_route &br)
200{
201 std::list<bus_stop *>::const_iterator it;
202 // note: we're displaying the pointer to permit verification
203 // that duplicated pointers are properly restored.
204 for(it = br.stops.begin(); it != br.stops.end(); it++){
205 os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
206 }
207 return os;
208}
209
210/////////////////////////////////////////////////////////////
211// a bus schedule is a collection of routes each with a starting time
212//
213// Illustrates serialization of STL objects(pair) in a non-intrusive way.
214// See definition of operator<< <pair<F, S> >(ar, pair) and others in
215// serialization.hpp
216//
217// illustrates nesting of serializable classes
218//
219// illustrates use of version number to automatically grandfather older
220// versions of the same class.
221
222class bus_schedule
223{
224public:
225 // note: this structure was made public. because the friend declarations
226 // didn't seem to work as expected.
227 struct trip_info
228 {
229 template<class Archive>
230 void serialize(Archive &ar, const unsigned int file_version)
231 {
232 // in versions 2 or later
233 if(file_version >= 2)
234 // read the drivers name
235 ar & driver;
236 // all versions have the follwing info
237 ar & hour & minute;
238 }
239
240 // starting time
241 int hour;
242 int minute;
243 // only after system shipped was the driver's name added to the class
244 std::string driver;
245
246 trip_info(){}
247 trip_info(int _h, int _m, const std::string &_d) :
248 hour(_h), minute(_m), driver(_d)
249 {}
250 };
251private:
252 friend class boost::serialization::access;
253 friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
254 friend std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti);
255 std::list<std::pair<trip_info, bus_route *> > schedule;
256 template<class Archive>
257 void serialize(Archive &ar, const unsigned int version)
258 {
259 ar & schedule;
260 }
261public:
262 void append(const std::string &_d, int _h, int _m, bus_route *_br)
263 {
264 schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
265 }
266 bus_schedule(){}
267};
268BOOST_CLASS_VERSION(bus_schedule::trip_info, 2)
269
270std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
271{
272 return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
273}
274std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
275{
276 std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
277 for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
278 os << it->first << *(it->second);
279 }
280 return os;
281}
282
283void save_schedule(const bus_schedule &s, const char * filename){
284 // make an archive
285 std::ofstream ofs(filename);
286 boost::archive::binary_oarchive oa(ofs, std::ios::binary);
287 oa << s;
288}
289
290void
291restore_schedule(bus_schedule &s, const char * filename)
292{
293 // open the archive
294 std::ifstream ifs(filename);
295 boost::archive::binary_iarchive ia(ifs, std::ios::binary);
296
297 // restore the schedule from the archive
298 ia >> s;
299}
300
301int main(int argc, char *argv[])
302{
303 // make the schedule
304 bus_schedule original_schedule;
305
306 // fill in the data
307 // make a few stops
308 bus_stop *bs0 = new bus_stop_corner(
309 gps_position(34, 135, 52.560f),
310 gps_position(134, 22, 78.30f),
311 "24th Street", "10th Avenue"
312 );
313 bus_stop *bs1 = new bus_stop_corner(
314 gps_position(35, 137, 23.456f),
315 gps_position(133, 35, 54.12f),
316 "State street", "Cathedral Vista Lane"
317 );
318 bus_stop *bs2 = new bus_stop_destination(
319 gps_position(35, 136, 15.456f),
320 gps_position(133, 32, 15.300f),
321 "White House"
322 );
323 bus_stop *bs3 = new bus_stop_destination(
324 gps_position(35, 134, 48.789f),
325 gps_position(133, 32, 16.230f),
326 "Lincoln Memorial"
327 );
328
329 // make a routes
330 bus_route route0;
331 route0.append(bs0);
332 route0.append(bs1);
333 route0.append(bs2);
334
335 // add trips to schedule
336 original_schedule.append("bob", 6, 24, &route0);
337 original_schedule.append("bob", 9, 57, &route0);
338 original_schedule.append("alice", 11, 02, &route0);
339
340 // make aother routes
341 bus_route route1;
342 route1.append(bs3);
343 route1.append(bs2);
344 route1.append(bs1);
345
346 // add trips to schedule
347 original_schedule.append("ted", 7, 17, &route1);
348 original_schedule.append("ted", 9, 38, &route1);
349 original_schedule.append("alice", 11, 47, &route1);
350
351 // display the complete schedule
352 std::cout << "original schedule";
353 std::cout << original_schedule;
354
355 std::string filename/*(boost::archive::tmpdir())*/;
356 filename += "demofile.dat";
357
358 // save the schedule
359// save_schedule(original_schedule, filename.c_str());
360
361 // ... some time later
362 // make a new schedule
363 bus_schedule new_schedule;
364
365 restore_schedule(new_schedule, filename.c_str());
366
367 // and display
368 std::cout << "\nrestored schedule";
369 std::cout << new_schedule;
370 // should be the same as the old one. (except for the pointer values)
371
372 delete bs0;
373 delete bs1;
374 delete bs2;
375 delete bs3;
376 return 0;
377}