]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/serialization/example/demo.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / serialization / example / demo.cpp
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/text_iarchive.hpp>
19 #include <boost/archive/text_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 //
46 class 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 }
57 public:
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 };
64 std::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
75 class 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 }
88 protected:
89 bus_stop(const gps_position & _lat, const gps_position & _long) :
90 latitude(_lat), longitude(_long)
91 {}
92 public:
93 bus_stop(){}
94 virtual ~bus_stop(){}
95 };
96
97 BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)
98
99 std::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 //
109 class 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
126 public:
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
136 class 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 }
149 public:
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 //
172 class 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 }
192 public:
193 bus_route(){}
194 void append(bus_stop *_bs)
195 {
196 stops.insert(stops.end(), _bs);
197 }
198 };
199 std::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
222 class bus_schedule
223 {
224 public:
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 };
251 private:
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 }
261 public:
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 };
268 BOOST_CLASS_VERSION(bus_schedule::trip_info, 2)
269
270 std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
271 {
272 return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
273 }
274 std::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
283 void save_schedule(const bus_schedule &s, const char * filename){
284 // make an archive
285 std::ofstream ofs(filename);
286 boost::archive::text_oarchive oa(ofs);
287 oa << s;
288 }
289
290 void
291 restore_schedule(bus_schedule &s, const char * filename)
292 {
293 // open the archive
294 std::ifstream ifs(filename);
295 boost::archive::text_iarchive ia(ifs);
296
297 // restore the schedule from the archive
298 ia >> s;
299 }
300
301 int 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.txt";
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 }