Created
October 19, 2020 14:31
-
-
Save atifkarim/6f59a1073ca272e1128d1cb7f85215ef to your computer and use it in GitHub Desktop.
change code on 19 Oct
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////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 <list> | |
#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> | |
using namespace std; | |
///////////////////////////////////////////////////////////// | |
// 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 | |
void getval() | |
{ | |
cout<<"degrees: "<<degrees<<" , minutes: "<<minutes<<" , seconds: "<<seconds<<endl; | |
} | |
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); | |
/** | |
* it is a syntax of filling an empty LIST. create an empty list and | |
* then point to the end postion with the iterator and then fill it | |
*/ | |
} | |
void do_print() | |
{ | |
cout<<"I am in bus_route class\n"; | |
} | |
std::list<bus_stop_pointer> return_stops() | |
{ | |
return stops; | |
} | |
}; | |
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) | |
{} | |
}; | |
struct trip_info STRUCT_TRIP; | |
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)); | |
/**it is a syntax of filling an empty LIST. create an empty list and | |
* then point to the end postion with the iterator and then fill it | |
*/ | |
} | |
void print_list_schedule() | |
{ | |
for(auto k = schedule.begin();k!=schedule.end();++k) | |
{ | |
cout<<(*k).first<<" ____ "<<(*k).second<<endl; | |
} | |
cout<<"\n"; | |
} | |
std::list<std::pair<trip_info, bus_route *> > return_schedule() | |
{ | |
return schedule; | |
} | |
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); // print first and second element of the pair | |
} | |
return os; | |
} | |
/** | |
* removed static type for save and relaod object | |
*/ | |
template<typename T1> | |
void save_schedule(const T1 &s, const char * filename){ | |
// make an archive | |
std::ofstream ofs(filename); | |
boost::archive::text_oarchive oa(ofs); | |
oa << s; | |
} | |
template<typename T1> | |
void restore_schedule(T1 &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 | |
/** | |
* Following object is the updated or will update the program finally. This class has 3 member variable and one function | |
* which require those 3 member and one pointer type object as the arguments. That pointer type data will come from bus route | |
* class's object | |
*/ | |
bus_schedule original_schedule; | |
// fill in the data | |
// make a few stops | |
/** bus_stop class is a ABSTRAC_CLASS so it canot create object but it can instatiate pointer type object | |
* in the following lines this is happening. And look about the constructor of bus_stop_corner and bus_stop_destination | |
* class. both child class inherited bus_stop class "publicly". bus_stop class has two member variable whose types | |
* are of gps_position class's type. Again both child class's has their own member. Just they are called in the following cases | |
*/ | |
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 | |
/** | |
* this class require only a default constructor | |
* this class bus_route has a append function which require pointer type variable to fill and the type is bus_stop class | |
**/ | |
bus_route route0; | |
route0.append(bs0); | |
route0.append(bs1); | |
route0.append(bs2); | |
// add trips to schedule | |
/** | |
* Go to the class bus_schedule and you will find that it has one struct named trip_info whose has 3 member. | |
* this class has one private member whose type is LIST, name is schedule | |
* one public function which takes the 4 arguments to append in the LIST. | |
* (first 3 passes to the STRUCT's constructor), (second argument is the bus_route type pointer) | |
* they make noting but a PAIR and fill the LIST | |
*/ | |
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()); | |
// save_schedule(route0, filename.c_str()); | |
// ... some time later | |
// make a new schedule | |
bus_schedule new_schedule; | |
// bus_route route0_reload; | |
restore_schedule(new_schedule, filename.c_str()); | |
// restore_schedule(route0_reload, 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) | |
std::cout<<"\n\nDeserializing Started\n"<<std::endl; | |
// decltype (auto) x; | |
// std::cout<<new_schedule[0]<<std::endl; | |
// auto x = new_schedule.STRUCT_TRIP; | |
// new_schedule.print_list_schedule(); | |
// cout<<x<<endl; | |
auto returning_schedule = new_schedule.return_schedule(); // returning list from bus_schedule class | |
// returning_schedule::iterator it_a; | |
for(auto i:returning_schedule) | |
{ | |
// cout<<(i.first)<<" ~~~~~~~ "<<(i.first).driver<<" ~~~~~~~ "<<(i.second)<<endl; | |
// cout<<(i.second)<<" ~~~~~~ "<<*(i.second)<<endl; | |
// cout<<(i.second)<<endl; | |
// (i.second)->do_print(); // this works to access member function of bus_route class | |
auto x_a = (i.second)->return_stops(); | |
for(auto j : x_a) | |
{ | |
cout<<j<<" ******* "<<*j<<endl; | |
} | |
// *(i.second) and *(i.second) are same | |
} | |
/** | |
* In the following line I have tried to fetch the object data using the class named bus_stop | |
*/ | |
// cout<<route0_reload<<endl; | |
// bus_stop * here_pointer_bus_stop; | |
// auto x = route0_reload.return_stops(); | |
// for (auto i : x) // iterating through the ist that returned from the bus_route class | |
// std::cout <<i<<" and the value: "<< *i <<" ******* "<<endl; // using i->latitude you can get value of latitude but it is private. make it public, works | |
delete bs0; | |
delete bs1; | |
delete bs2; | |
delete bs3; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment