#include <algorithm>
#include <iostream>
#include <cstddef>
#include <fstream>
#include <string>
#include <cstdio>
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::remove;
}
#endif
#include <boost/archive/tmpdir.hpp>
#ifndef BOOST_NO_EXCEPTIONS
#include <exception>
#endif
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/split_member.hpp>
template<class TPTR>
struct deleter
{
void operator()(TPTR t){
delete t;
}
};
class Course;
class Student;
class Student
{
public:
static int count;
Student(){
count++;
}
~Student(){
some_courses.clear();
count--;
}
std::list<Course *> some_courses;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int ){
ar & some_courses;
}
};
int Student::count = 0;
class Course
{
public:
static int count;
Course(){
count++;
}
~Course(){
some_students.clear();
count--;
}
std::list<Student *> some_students;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int ){
ar & some_students;
}
};
int Course::count = 0;
class School
{
public:
~School(){
std::for_each(all_students.begin(), all_students.end(), deleter<Student *>());
all_students.clear();
std::for_each(all_courses.begin(), all_courses.end(), deleter<Course *>());
all_courses.clear();
}
std::list<Student *> all_students;
std::list<Course *> all_courses;
private:
friend class boost::serialization::access;
BOOST_SERIALIZATION_SPLIT_MEMBER()
template<class Archive>
void save(Archive & ar, const unsigned int file_version) const;
template<class Archive>
void load(Archive & ar, const unsigned int file_version);
};
#if 0#endif
template<class Archive>
void School::save(Archive & ar, const unsigned int ) const {
ar << all_students;
ar << all_courses;
}
template<class Archive>
void School::load(Archive & ar, const unsigned int ){
try{
ar >> all_courses;
ar >> all_students; }
catch(std::exception){
all_courses.clear();
all_students.clear();
throw;
}
}
void init(School *school){
Student *bob = new Student();
Student *ted = new Student();
Student *carol = new Student();
Student *alice = new Student();
school->all_students.push_back(bob);
school->all_students.push_back(ted);
school->all_students.push_back(carol);
school->all_students.push_back(alice);
Course *math = new Course();
Course *history = new Course();
Course *literature = new Course();
Course *gym = new Course();
school->all_courses.push_back(math);
school->all_courses.push_back(history);
school->all_courses.push_back(literature);
school->all_courses.push_back(gym);
bob->some_courses.push_back(math);
math->some_students.push_back(bob);
bob->some_courses.push_back(literature);
literature->some_students.push_back(bob);
ted->some_courses.push_back(math);
math->some_students.push_back(ted);
ted->some_courses.push_back(history);
history->some_students.push_back(ted);
alice->some_courses.push_back(literature);
literature->some_students.push_back(alice);
alice->some_courses.push_back(history);
history->some_students.push_back(alice);
}
void save(const School * const school, const char *filename){
std::ofstream ofile(filename);
boost::archive::text_oarchive ar(ofile);
ar << school;
}
void load(School * & school, const char *filename){
std::ifstream ifile(filename);
boost::archive::text_iarchive ar(ifile);
try{
ar >> school;
}
catch(std::exception){
school = NULL;
}
}
int main(int argc, char *argv[]){
std::string filename(boost::archive::tmpdir());
filename += "/demofile.txt";
School *school = new School();
std::cout << "1. student count = " << Student::count << std::endl;
std::cout << "2. class count = " << Course::count << std::endl;
init(school);
std::cout << "3. student count = " << Student::count << std::endl;
std::cout << "4. class count = " << Course::count << std::endl;
save(school, filename.c_str());
delete school;
school = NULL;
std::cout << "5. student count = " << Student::count << std::endl;
std::cout << "6. class count = " << Course::count << std::endl;
load(school, filename.c_str());
std::cout << "7. student count = " << Student::count << std::endl;
std::cout << "8. class count = " << Course::count << std::endl;
delete school;
std::cout << "9. student count = " << Student::count << std::endl;
std::cout << "10. class count = " << Course::count << std::endl;
std::remove(filename.c_str());
return Student::count + Course::count;
}