]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
2 | // test_shared_ptr.cpp | |
3 | ||
f67539c2 | 4 | // (C) Copyright 2002 Robert Ramey- http://www.rrsd.com - David Tonge . |
7c673cae FG |
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 | // See http://www.boost.org for updates, documentation, and revision history. | |
10 | ||
11 | #include <cstddef> // NULL | |
12 | #include <fstream> | |
13 | ||
14 | #include <cstdio> // remove | |
15 | #include <boost/config.hpp> | |
16 | #if defined(BOOST_NO_STDC_NAMESPACE) | |
f67539c2 | 17 | namespace std{ |
7c673cae FG |
18 | using ::remove; |
19 | } | |
20 | #endif | |
21 | ||
22 | #include "test_tools.hpp" | |
23 | ||
24 | #include <boost/serialization/shared_ptr_132.hpp> | |
25 | #include <boost/serialization/shared_ptr.hpp> | |
26 | #include <boost/serialization/weak_ptr.hpp> | |
27 | #include <boost/serialization/split_member.hpp> | |
28 | ||
29 | #include <boost/preprocessor/stringize.hpp> | |
30 | ||
31 | #include <boost/serialization/nvp.hpp> | |
32 | #include <boost/serialization/export.hpp> | |
33 | ||
34 | // This is a simple class. It contains a counter of the number | |
35 | // of objects of this class which have been instantiated. | |
36 | class A | |
37 | { | |
38 | private: | |
39 | friend class boost::serialization::access; | |
40 | int x; | |
41 | template<class Archive> | |
42 | void save(Archive & ar, const unsigned int /* file_version */) const { | |
43 | ar << BOOST_SERIALIZATION_NVP(x); | |
44 | } | |
45 | template<class Archive> | |
46 | void load(Archive & ar, const unsigned int /* file_version */) { | |
47 | ar >> BOOST_SERIALIZATION_NVP(x); | |
48 | } | |
49 | BOOST_SERIALIZATION_SPLIT_MEMBER() | |
50 | public: | |
51 | static int count; | |
52 | bool operator==(const A & rhs) const { | |
53 | return x == rhs.x; | |
54 | } | |
55 | A(){++count;} // default constructor | |
56 | virtual ~A(){--count;} // default destructor | |
57 | }; | |
58 | ||
59 | BOOST_SERIALIZATION_SHARED_PTR(A) | |
60 | ||
61 | // B is a subclass of A | |
62 | class B : public A | |
63 | { | |
64 | private: | |
65 | friend class boost::serialization::access; | |
66 | template<class Archive> | |
67 | void save(Archive & ar, const unsigned int /* file_version */ )const { | |
68 | ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); | |
69 | } | |
70 | template<class Archive> | |
71 | void load(Archive & ar, const unsigned int /* file_version */){ | |
72 | ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); | |
73 | } | |
74 | BOOST_SERIALIZATION_SPLIT_MEMBER() | |
75 | public: | |
76 | static int count; | |
77 | B() : A() {}; | |
78 | virtual ~B() {}; | |
79 | }; | |
80 | ||
81 | // B needs to be exported because its serialized via a base class pointer | |
82 | BOOST_SHARED_POINTER_EXPORT(B) | |
83 | BOOST_SERIALIZATION_SHARED_PTR(B) | |
84 | ||
85 | int A::count = 0; | |
86 | ||
87 | template<class T> | |
88 | void save(const char * testfile, const T & spa) | |
89 | { | |
90 | test_ostream os(testfile, TEST_STREAM_FLAGS); | |
91 | test_oarchive oa(os, TEST_ARCHIVE_FLAGS); | |
92 | oa << BOOST_SERIALIZATION_NVP(spa); | |
93 | } | |
94 | ||
95 | template<class T> | |
96 | void load(const char * testfile, T & spa) | |
97 | { | |
98 | test_istream is(testfile, TEST_STREAM_FLAGS); | |
99 | test_iarchive ia(is, TEST_ARCHIVE_FLAGS); | |
100 | ia >> BOOST_SERIALIZATION_NVP(spa); | |
101 | } | |
102 | ||
103 | // trivial test | |
104 | template<class T> | |
105 | void save_and_load(const T & spa) | |
106 | { | |
107 | const char * testfile = boost::archive::tmpnam(NULL); | |
108 | BOOST_REQUIRE(NULL != testfile); | |
109 | save(testfile, spa); | |
110 | ||
f67539c2 | 111 | // note that we're loading to a current version of shared_ptr |
7c673cae FG |
112 | // regardless of the orignal saved type - this tests backward |
113 | // archive compatibility | |
114 | boost::shared_ptr<A> spa1; | |
115 | load(testfile, spa1); | |
116 | ||
117 | BOOST_CHECK( | |
118 | (spa.get() == NULL && spa1.get() == NULL) | |
119 | || * spa == * spa1 | |
120 | ); | |
121 | std::remove(testfile); | |
122 | } | |
123 | ||
124 | template<class T> | |
125 | void save2( | |
f67539c2 TL |
126 | const char * testfile, |
127 | const T & first, | |
7c673cae FG |
128 | const T & second |
129 | ){ | |
130 | test_ostream os(testfile, TEST_STREAM_FLAGS); | |
131 | test_oarchive oa(os, TEST_ARCHIVE_FLAGS); | |
132 | oa << BOOST_SERIALIZATION_NVP(first); | |
133 | oa << BOOST_SERIALIZATION_NVP(second); | |
134 | } | |
135 | ||
136 | template<class T> | |
137 | void load2( | |
f67539c2 TL |
138 | const char * testfile, |
139 | T & first, | |
7c673cae FG |
140 | T & second) |
141 | { | |
142 | test_istream is(testfile, TEST_STREAM_FLAGS); | |
143 | test_iarchive ia(is, TEST_ARCHIVE_FLAGS); | |
144 | ia >> BOOST_SERIALIZATION_NVP(first); | |
145 | ia >> BOOST_SERIALIZATION_NVP(second); | |
146 | } | |
147 | ||
148 | // Run tests by serializing two shared_ptrs into an archive, | |
149 | // clearing them (deleting the objects) and then reloading the | |
150 | // objects back from an archive. | |
151 | template<class T> | |
152 | void save_and_load2(T & first, T & second) | |
153 | { | |
154 | const char * testfile = boost::archive::tmpnam(NULL); | |
155 | BOOST_REQUIRE(NULL != testfile); | |
156 | ||
157 | save2(testfile, first, second); | |
158 | ||
159 | // Clear the pointers, thereby destroying the objects they contain | |
160 | first.reset(); | |
161 | second.reset(); | |
162 | ||
163 | boost::shared_ptr<A> first1, second1; | |
164 | load2(testfile, first1, second1); | |
165 | ||
166 | BOOST_CHECK(first1 == second1); | |
167 | std::remove(testfile); | |
168 | } | |
169 | ||
170 | template<class T> | |
171 | void save3( | |
f67539c2 TL |
172 | const char * testfile, |
173 | const T & first, | |
7c673cae FG |
174 | const T & second, |
175 | const T & third | |
176 | ){ | |
177 | test_ostream os(testfile, TEST_STREAM_FLAGS); | |
178 | test_oarchive oa(os, TEST_ARCHIVE_FLAGS); | |
179 | oa << BOOST_SERIALIZATION_NVP(third); | |
180 | oa << BOOST_SERIALIZATION_NVP(first); | |
181 | oa << BOOST_SERIALIZATION_NVP(second); | |
182 | } | |
183 | ||
184 | template<class T> | |
185 | void load3( | |
f67539c2 TL |
186 | const char * testfile, |
187 | T & first, | |
7c673cae FG |
188 | T & second, |
189 | T & third | |
190 | ){ | |
191 | test_istream is(testfile, TEST_STREAM_FLAGS); | |
192 | test_iarchive ia(is, TEST_ARCHIVE_FLAGS); | |
193 | // note that we serialize the weak pointer first | |
194 | ia >> BOOST_SERIALIZATION_NVP(third); | |
195 | // inorder to test that a temporarily solitary weak pointer | |
196 | // correcttly restored. | |
197 | ia >> BOOST_SERIALIZATION_NVP(first); | |
198 | ia >> BOOST_SERIALIZATION_NVP(second); | |
199 | } | |
200 | ||
201 | // This does the tests | |
202 | int test_main(int /* argc */, char * /* argv */[]) | |
203 | { | |
204 | // These are our shared_ptrs | |
205 | boost_132::shared_ptr<A> spa; | |
206 | ||
207 | // trivial test 1 | |
208 | save_and_load(spa); | |
209 | ||
210 | //trivial test 2 | |
211 | spa.reset(); | |
212 | spa = boost_132::shared_ptr<A>(new A); | |
213 | save_and_load(spa); | |
214 | ||
215 | // Try to save and load pointers to As, to a text archive | |
216 | spa = boost_132::shared_ptr<A>(new A); | |
217 | boost_132::shared_ptr<A> spa1 = spa; | |
218 | save_and_load2(spa, spa1); | |
f67539c2 | 219 | |
7c673cae FG |
220 | // Try to save and load pointers to Bs, to a text archive |
221 | spa = boost_132::shared_ptr<A>(new B); | |
222 | save_and_load(spa); | |
223 | ||
224 | spa1 = spa; | |
225 | save_and_load2(spa, spa1); | |
226 | ||
227 | // obj of type B gets destroyed | |
228 | // as smart_ptr goes out of scope | |
229 | return EXIT_SUCCESS; | |
230 | } |