1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// test_shared_ptr.cpp
3
4// (C) Copyright 2002 Robert Ramey- http://www.rrsd.com - David Tonge .
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 <cstdio> // remove
13#include <fstream>
14
15#include <boost/config.hpp>
16#if defined(BOOST_NO_STDC_NAMESPACE)
17namespace std{
18 using ::remove;
19}
20#endif
21
22#include <boost/serialization/nvp.hpp>
23#include <boost/serialization/export.hpp>
24#include <boost/serialization/shared_ptr.hpp>
25#include <boost/serialization/weak_ptr.hpp>
26
27#include "test_tools.hpp"
28
29// This is a simple class. It contains a counter of the number
30// of objects of this class which have been instantiated.
31class A
32{
33private:
34 friend class boost::serialization::access;
35 int x;
36 template<class Archive>
37 void serialize(Archive & ar, const unsigned int /* file_version */){
38 ar & BOOST_SERIALIZATION_NVP(x);
39 }
40 A(A const & rhs);
41 A& operator=(A const & rhs);
42public:
43 static int count;
44 bool operator==(const A & rhs) const {
45 return x == rhs.x;
46 }
47 A(){++count;} // default constructor
48 virtual ~A(){--count;} // default destructor
49};
50
51BOOST_SERIALIZATION_SHARED_PTR(A)
52
53int A::count = 0;
54
55// B is a subclass of A
56class B : public A
57{
58private:
59 friend class boost::serialization::access;
60 template<class Archive>
61 void serialize(Archive & ar, const unsigned int /* file_version */){
62 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
63 }
64public:
65 static int count;
66 B() : A() {};
67 virtual ~B() {};
68};
69
70// B needs to be exported because its serialized via a base class pointer
71BOOST_CLASS_EXPORT(B)
72BOOST_SERIALIZATION_SHARED_PTR(B)
73
74// test a non-polymorphic class
75class C
76{
77private:
78 friend class boost::serialization::access;
79 int z;
80 template<class Archive>
81 void serialize(Archive & ar, const unsigned int /* file_version */){
82 ar & BOOST_SERIALIZATION_NVP(z);
83 }
84public:
85 static int count;
86 bool operator==(const C & rhs) const {
87 return z == rhs.z;
88 }
89 C() :
90 z(++count) // default constructor
91 {}
92 virtual ~C(){--count;} // default destructor
93};
94
95int C::count = 0;
96
97template<class SP>
98void save(const char * testfile, const SP & spa)
99{
100 test_ostream os(testfile, TEST_STREAM_FLAGS);
101 test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
102 oa << BOOST_SERIALIZATION_NVP(spa);
103}
104
105template<class SP>
106void load(const char * testfile, SP & spa)
107{
108 test_istream is(testfile, TEST_STREAM_FLAGS);
109 test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
110 ia >> BOOST_SERIALIZATION_NVP(spa);
111}
112
113// trivial test
114template<class SP>
115void save_and_load(SP & spa)
116{
117 const char * testfile = boost::archive::tmpnam(NULL);
118 BOOST_REQUIRE(NULL != testfile);
119 save(testfile, spa);
120 SP spa1;
121 load(testfile, spa1);
122
123 BOOST_CHECK(
124 (spa.get() == NULL && spa1.get() == NULL)
125 || * spa == * spa1
126 );
127 std::remove(filename: testfile);
128}
129
130template<class SP>
131void save2(
132 const char * testfile,
133 const SP & first,
134 const SP & second
135){
136 test_ostream os(testfile, TEST_STREAM_FLAGS);
137 test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
138 oa << BOOST_SERIALIZATION_NVP(first);
139 oa << BOOST_SERIALIZATION_NVP(second);
140}
141
142template<class SP>
143void load2(
144 const char * testfile,
145 SP & first,
146 SP & second)
147{
148 test_istream is(testfile, TEST_STREAM_FLAGS);
149 test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
150 ia >> BOOST_SERIALIZATION_NVP(first);
151 ia >> BOOST_SERIALIZATION_NVP(second);
152}
153
154// Run tests by serializing two shared_ptrs into an archive,
155// clearing them (deleting the objects) and then reloading the
156// objects back from an archive.
157template<class SP>
158void save_and_load2(SP & first, SP & second)
159{
160 const char * testfile = boost::archive::tmpnam(NULL);
161 BOOST_REQUIRE(NULL != testfile);
162
163 save2(testfile, first, second);
164
165 // Clear the pointers, thereby destroying the objects they contain
166 first.reset();
167 second.reset();
168
169 load2(testfile, first, second);
170
171 BOOST_CHECK(first == second);
172 std::remove(filename: testfile);
173}
174
175template<class SP, class WP>
176void save3(
177 const char * testfile,
178 SP & first,
179 SP & second,
180 WP & third
181){
182 test_ostream os(testfile, TEST_STREAM_FLAGS);
183 test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
184 oa << BOOST_SERIALIZATION_NVP(third);
185 oa << BOOST_SERIALIZATION_NVP(first);
186 oa << BOOST_SERIALIZATION_NVP(second);
187}
188
189template<class SP, class WP>
190void load3(
191 const char * testfile,
192 SP & first,
193 SP & second,
194 WP & third
195){
196 test_istream is(testfile, TEST_STREAM_FLAGS);
197 test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
198 // note that we serialize the weak pointer first
199 ia >> BOOST_SERIALIZATION_NVP(third);
200 // inorder to test that a temporarily solitary weak pointer
201 // correctly restored.
202 ia >> BOOST_SERIALIZATION_NVP(first);
203 ia >> BOOST_SERIALIZATION_NVP(second);
204}
205
206template<class SP, class WP>
207void save_and_load3(
208 SP & first,
209 SP & second,
210 WP & third
211){
212 const char * testfile = boost::archive::tmpnam(NULL);
213 BOOST_REQUIRE(NULL != testfile);
214
215 save3(testfile, first, second, third);
216
217 // Clear the pointers, thereby destroying the objects they contain
218 first.reset();
219 second.reset();
220 third.reset();
221
222 load3(testfile, first, second, third);
223
224 BOOST_CHECK(first == second);
225 BOOST_CHECK(first == third.lock());
226 std::remove(filename: testfile);
227}
228
229template<class SP>
230void save4(const char * testfile, const SP & spc)
231{
232 test_ostream os(testfile, TEST_STREAM_FLAGS);
233 test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
234 oa << BOOST_SERIALIZATION_NVP(spc);
235}
236
237template<class SP>
238void load4(const char * testfile, SP & spc)
239{
240 test_istream is(testfile, TEST_STREAM_FLAGS);
241 test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
242 ia >> BOOST_SERIALIZATION_NVP(spc);
243}
244
245// trivial test
246template<class SP>
247void save_and_load4(SP & spc)
248{
249 const char * testfile = boost::archive::tmpnam(NULL);
250 BOOST_REQUIRE(NULL != testfile);
251 save4(testfile, spc);
252 SP spc1;
253 load4(testfile, spc1);
254
255 BOOST_CHECK(
256 (spc.get() == NULL && spc1.get() == NULL)
257 || * spc == * spc1
258 );
259 std::remove(filename: testfile);
260}
261
262// This does the tests
263template<template<class T> class SPT , template<class T> class WPT >
264bool test(){
265 {
266 SPT<A> spa;
267 // These are our shared_ptrs
268 spa = SPT<A>(new A);
269 SPT<A> spa1 = spa;
270 spa1 = spa;
271 }
272 {
273 // These are our shared_ptrs
274 SPT<A> spa;
275
276 // trivial test 1
277 save_and_load(spa);
278
279 // trivial test 2
280 spa = SPT<A>(new A);
281 save_and_load(spa);
282
283 // Try to save and load pointers to As
284 spa = SPT<A>(new A);
285 SPT<A> spa1 = spa;
286 save_and_load2(spa, spa1);
287
288 // Try to save and load pointers to Bs
289 spa = SPT<A>(new B);
290 spa1 = spa;
291 save_and_load2(spa, spa1);
292
293 // test a weak pointer
294 spa = SPT<A>(new A);
295 spa1 = spa;
296 WPT<A> wp = spa;
297 save_and_load3(spa, spa1, wp);
298
299 // obj of type B gets destroyed
300 // as smart_ptr goes out of scope
301 }
302 BOOST_CHECK(A::count == 0);
303 {
304 // Try to save and load pointers to Cs
305 SPT<C> spc;
306 spc = SPT<C>(new C);
307 save_and_load4(spc);
308 }
309 BOOST_CHECK(C::count == 0);
310 return true;
311}
312// This does the tests
313int test_main(int /* argc */, char * /* argv */[])
314{
315 bool result = true;
316 result &= test<boost::shared_ptr, boost::weak_ptr>();
317 #ifndef BOOST_NO_CXX11_SMART_PTR
318 result &= test<std::shared_ptr, std::weak_ptr>();
319 #endif
320 return result ? EXIT_SUCCESS : EXIT_FAILURE;
321}
322
323

source code of boost/libs/serialization/test/test_shared_ptr.cpp