1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// test_diamond.cpp
// (C) Copyright 2002-2009 Vladimir Prus and Robert Ramey.
// 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)
// test of serialization library for diamond inheritence situations
#include <cstddef> // NULL
#include <fstream>
#include <iostream>
#include <boost/config.hpp>
#include <cstdio> // remove
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::remove;
}
#endif
#include "test_tools.hpp"
#include <boost/serialization/map.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/export.hpp>
int save_count = 0; // used to detect when base class is saved multiple times
int load_count = 0; // used to detect when base class is loaded multiple times
class base {
public:
base() : i(0) {}
base(int i) : i(i)
{
m[i] = "text";
}
template<class Archive>
void save(Archive &ar, const unsigned int /* file_version */) const
{
std::cout << "Saving base\n";
ar << BOOST_SERIALIZATION_NVP(i);
ar << BOOST_SERIALIZATION_NVP(m);
++save_count;
}
template<class Archive>
void load(Archive & ar, const unsigned int /* file_version */)
{
std::cout << "Restoring base\n";
ar >> BOOST_SERIALIZATION_NVP(i);
ar >> BOOST_SERIALIZATION_NVP(m);
++load_count;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
bool operator==(const base& another) const
{
return i == another.i && m == another.m;
}
// make polymorphic by marking at least one function virtual
virtual ~base() {};
private:
int i;
std::map<int, std::string> m;
};
// note: the default is for object tracking to be performed if and only
// if and object of the corresponding class is anywhere serialized
// through a pointer. In this example, that doesn't occur so
// by default, the shared base object wouldn't normally be tracked.
// This would leave to multiple save/load operation of the data in
// this shared base class. This wouldn't cause an error, but it would
// be a waste of time. So set the tracking behavior trait of the base
// class to always track serialized objects of that class. This permits
// the system to detect and elminate redundent save/load operations.
// (It is concievable that this might someday be detected automatically
// but for now, this is not done so we have to rely on the programmer
// to specify this trait)
BOOST_CLASS_TRACKING(base, track_always)
class derived1 : virtual public base {
public:
template<class Archive>
void save(Archive &ar, const unsigned int /* file_version */) const
{
std::cout << "Saving derived1\n";
ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(base);
}
template<class Archive>
void load(Archive & ar, const unsigned int /* file_version */)
{
std::cout << "Restoring derived1\n";
ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(base);
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
class derived2 : virtual public base {
public:
template<class Archive>
void save(Archive &ar, const unsigned int /* file_version */) const
{
std::cout << "Saving derived2\n";
ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(base);
}
template<class Archive>
void load(Archive & ar, const unsigned int /* file_version */)
{
std::cout << "Restoring derived2\n";
ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(base);
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
class final : public derived1, public derived2 {
public:
final() {}
final(int i) : base(i) {}
template<class Archive>
void save(Archive &ar, const unsigned int /* file_version */) const
{
std::cout << "Saving final\n";
ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(derived1);
ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(derived2);
}
template<class Archive>
void load(Archive & ar, const unsigned int /* file_version */)
{
std::cout << "Restoring final\n";
ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(derived1);
ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(derived2);
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
BOOST_CLASS_EXPORT(final)
int
test_main( int /* argc */, char* /* argv */[] )
{
const char * testfile = boost::archive::tmpnam(NULL);
BOOST_REQUIRE(NULL != testfile);
const final b(3);
{
test_ostream ofs(testfile, TEST_STREAM_FLAGS);
test_oarchive oa(ofs);
oa << boost::serialization::make_nvp("b", b);
}
final b2;
{
test_istream ifs(testfile, TEST_STREAM_FLAGS);
test_iarchive ia(ifs);
ia >> boost::serialization::make_nvp("b2", b2);
}
BOOST_CHECK(1 == save_count);
BOOST_CHECK(1 == load_count);
BOOST_CHECK(b2 == b);
std::remove(testfile);
// do the same test with pointers
testfile = boost::archive::tmpnam(NULL);
BOOST_REQUIRE(NULL != testfile);
save_count = 0;
load_count = 0;
const base* bp = new final( 3 );
{
test_ostream ofs(testfile);
test_oarchive oa(ofs);
oa << BOOST_SERIALIZATION_NVP(bp);
}
base* bp2;
{
test_istream ifs(testfile);
test_iarchive ia(ifs);
ia >> BOOST_SERIALIZATION_NVP(bp2);
}
BOOST_CHECK(1 == save_count);
BOOST_CHECK(1 == load_count);
BOOST_CHECK(*bp2 == *bp);
delete bp;
std::remove(testfile);
return EXIT_SUCCESS;
}
|