Skip to content

Instantly share code, notes, and snippets.

@atifkarim
Created October 19, 2020 14:31
Show Gist options
  • Save atifkarim/6f59a1073ca272e1128d1cb7f85215ef to your computer and use it in GitHub Desktop.
Save atifkarim/6f59a1073ca272e1128d1cb7f85215ef to your computer and use it in GitHub Desktop.
change code on 19 Oct
/////////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