• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
17 namespace 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.
36 class A
37 {
38 private:
39     friend class boost::serialization::access;
40     int x;
41     template<class Archive>
save(Archive & ar,const unsigned int) const42     void save(Archive & ar, const unsigned int /* file_version */) const {
43         ar << BOOST_SERIALIZATION_NVP(x);
44     }
45     template<class Archive>
load(Archive & ar,const unsigned int)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;
operator ==(const A & rhs) const52     bool operator==(const A & rhs) const {
53         return x == rhs.x;
54     }
A()55     A(){++count;}    // default constructor
~A()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>
save(Archive & ar,const unsigned int) const67     void save(Archive & ar, const unsigned int /* file_version */ )const {
68         ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
69     }
70     template<class Archive>
load(Archive & ar,const unsigned int)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;
B()77     B() : A() {};
~B()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>
save(const char * testfile,const T & spa)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>
load(const char * testfile,T & spa)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>
save_and_load(const T & spa)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 
111     // note that we're loading to a current version of shared_ptr
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>
save2(const char * testfile,const T & first,const T & second)125 void 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 
136 template<class T>
load2(const char * testfile,T & first,T & second)137 void 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.
151 template<class T>
save_and_load2(T & first,T & second)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>
save3(const char * testfile,const T & first,const T & second,const T & third)171 void 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 
184 template<class T>
load3(const char * testfile,T & first,T & second,T & third)185 void 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     // correcttly restored.
197     ia >> BOOST_SERIALIZATION_NVP(first);
198     ia >> BOOST_SERIALIZATION_NVP(second);
199 }
200 
201 // This does the tests
test_main(int,char * [])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);
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(spa, spa1);
226 
227     // obj of type B gets destroyed
228     // as smart_ptr goes out of scope
229     return EXIT_SUCCESS;
230 }
231