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 <fstream>
13
14#include <cstdio> // remove
15#include <boost/config.hpp>
16#if defined(BOOST_NO_STDC_NAMESPACE)
17namespace std{
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.
36class A
37{
38private:
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()
50public:
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
59BOOST_SERIALIZATION_SHARED_PTR(A)
60
61// B is a subclass of A
62class B : public A
63{
64private:
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()
75public:
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
82BOOST_SHARED_POINTER_EXPORT(B)
83BOOST_SERIALIZATION_SHARED_PTR(B)
84
85int A::count = 0;
86
87template<class T>
88void 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
95template<class T>
96void 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
104template<class T>
105void 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
111 // note that we're loading to a current version of shared_ptr
112 // regardless of the original saved type - this tests backward
113 // archive compatibility
114 boost::shared_ptr<A> spa1;
115 load(testfile, spa&: spa1);
116
117 BOOST_CHECK(
118 (spa.get() == NULL && spa1.get() == NULL)
119 || * spa == * spa1
120 );
121 std::remove(filename: testfile);
122}
123
124template<class T>
125void save2(
126 const char * testfile,
127 const T & first,
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
136template<class T>
137void load2(
138 const char * testfile,
139 T & first,
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.
151template<class T>
152void 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, first&: first1, second&: second1);
165
166 BOOST_CHECK(first1 == second1);
167 std::remove(filename: testfile);
168}
169
170template<class T>
171void save3(
172 const char * testfile,
173 const T & first,
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
184template<class T>
185void load3(
186 const char * testfile,
187 T & first,
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 // correctly restored.
197 ia >> BOOST_SERIALIZATION_NVP(first);
198 ia >> BOOST_SERIALIZATION_NVP(second);
199}
200
201// This does the tests
202int 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(first&: spa, second&: spa1);
219
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(first&: spa, second&: spa1);
226
227 // obj of type B gets destroyed
228 // as smart_ptr goes out of scope
229 return EXIT_SUCCESS;
230}
231

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