]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #include <boost/config.hpp> |
2 | ||
3 | #if defined(BOOST_MSVC) | |
4 | ||
5 | #pragma warning(disable: 4786) // identifier truncated in debug info | |
6 | #pragma warning(disable: 4710) // function not inlined | |
7 | #pragma warning(disable: 4711) // function selected for automatic inline expansion | |
8 | #pragma warning(disable: 4514) // unreferenced inline removed | |
9 | #pragma warning(disable: 4355) // 'this' : used in base member initializer list | |
10 | ||
11 | #if (BOOST_MSVC >= 1310) | |
12 | #pragma warning(disable: 4675) // resolved overload found with Koenig lookup | |
13 | #endif | |
14 | ||
15 | #endif | |
16 | ||
17 | // | |
18 | // shared_ptr_basic_test.cpp | |
19 | // | |
20 | // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. | |
21 | // | |
22 | // Distributed under the Boost Software License, Version 1.0. (See | |
23 | // accompanying file LICENSE_1_0.txt or copy at | |
24 | // http://www.boost.org/LICENSE_1_0.txt) | |
25 | // | |
26 | ||
27 | #include <boost/detail/lightweight_test.hpp> | |
28 | ||
29 | #include <boost/shared_ptr.hpp> | |
30 | #include <boost/weak_ptr.hpp> | |
31 | ||
32 | int cnt = 0; | |
33 | ||
34 | struct X | |
35 | { | |
36 | X() | |
37 | { | |
38 | ++cnt; | |
39 | } | |
40 | ||
41 | ~X() // virtual destructor deliberately omitted | |
42 | { | |
43 | --cnt; | |
44 | } | |
45 | ||
46 | virtual int id() const | |
47 | { | |
48 | return 1; | |
49 | } | |
50 | ||
51 | private: | |
52 | ||
53 | X(X const &); | |
54 | X & operator= (X const &); | |
55 | }; | |
56 | ||
57 | struct Y: public X | |
58 | { | |
59 | Y() | |
60 | { | |
61 | ++cnt; | |
62 | } | |
63 | ||
64 | ~Y() | |
65 | { | |
66 | --cnt; | |
67 | } | |
68 | ||
69 | virtual int id() const | |
70 | { | |
71 | return 2; | |
72 | } | |
73 | ||
74 | private: | |
75 | ||
76 | Y(Y const &); | |
77 | Y & operator= (Y const &); | |
78 | }; | |
79 | ||
80 | int * get_object() | |
81 | { | |
82 | ++cnt; | |
83 | return &cnt; | |
84 | } | |
85 | ||
86 | void release_object(int * p) | |
87 | { | |
88 | BOOST_TEST(p == &cnt); | |
89 | --cnt; | |
90 | } | |
91 | ||
92 | template<class T> void test_is_X(boost::shared_ptr<T> const & p) | |
93 | { | |
94 | BOOST_TEST(p->id() == 1); | |
95 | BOOST_TEST((*p).id() == 1); | |
96 | } | |
97 | ||
98 | template<class T> void test_is_X(boost::weak_ptr<T> const & p) | |
99 | { | |
100 | BOOST_TEST(p.get() != 0); | |
101 | BOOST_TEST(p.get()->id() == 1); | |
102 | } | |
103 | ||
104 | template<class T> void test_is_Y(boost::shared_ptr<T> const & p) | |
105 | { | |
106 | BOOST_TEST(p->id() == 2); | |
107 | BOOST_TEST((*p).id() == 2); | |
108 | } | |
109 | ||
110 | template<class T> void test_is_Y(boost::weak_ptr<T> const & p) | |
111 | { | |
112 | boost::shared_ptr<T> q = p.lock(); | |
113 | BOOST_TEST(q.get() != 0); | |
114 | BOOST_TEST(q->id() == 2); | |
115 | } | |
116 | ||
117 | template<class T> void test_eq(T const & a, T const & b) | |
118 | { | |
119 | BOOST_TEST(a == b); | |
120 | BOOST_TEST(!(a != b)); | |
121 | BOOST_TEST(!(a < b)); | |
122 | BOOST_TEST(!(b < a)); | |
123 | } | |
124 | ||
125 | template<class T> void test_ne(T const & a, T const & b) | |
126 | { | |
127 | BOOST_TEST(!(a == b)); | |
128 | BOOST_TEST(a != b); | |
129 | BOOST_TEST(a < b || b < a); | |
130 | BOOST_TEST(!(a < b && b < a)); | |
131 | } | |
132 | ||
133 | template<class T, class U> void test_shared(boost::weak_ptr<T> const & a, boost::weak_ptr<U> const & b) | |
134 | { | |
135 | BOOST_TEST(!(a < b)); | |
136 | BOOST_TEST(!(b < a)); | |
137 | } | |
138 | ||
139 | template<class T, class U> void test_nonshared(boost::weak_ptr<T> const & a, boost::weak_ptr<U> const & b) | |
140 | { | |
141 | BOOST_TEST(a < b || b < a); | |
142 | BOOST_TEST(!(a < b && b < a)); | |
143 | } | |
144 | ||
145 | template<class T, class U> void test_eq2(T const & a, U const & b) | |
146 | { | |
147 | BOOST_TEST(a == b); | |
148 | BOOST_TEST(!(a != b)); | |
149 | } | |
150 | ||
151 | template<class T, class U> void test_ne2(T const & a, U const & b) | |
152 | { | |
153 | BOOST_TEST(!(a == b)); | |
154 | BOOST_TEST(a != b); | |
155 | } | |
156 | ||
157 | template<class T> void test_is_zero(boost::shared_ptr<T> const & p) | |
158 | { | |
159 | BOOST_TEST(!p); | |
160 | BOOST_TEST(p.get() == 0); | |
161 | } | |
162 | ||
163 | template<class T> void test_is_nonzero(boost::shared_ptr<T> const & p) | |
164 | { | |
165 | // p? true: false is used to test p in a boolean context. | |
166 | // BOOST_TEST(p) is not guaranteed to test the conversion, | |
167 | // as the macro might test !!p instead. | |
168 | BOOST_TEST(p? true: false); | |
169 | BOOST_TEST(p.get() != 0); | |
170 | } | |
171 | ||
172 | int main() | |
173 | { | |
174 | using namespace boost; | |
175 | ||
176 | { | |
177 | shared_ptr<X> p(new Y); | |
178 | shared_ptr<X> p2(new X); | |
179 | ||
180 | test_is_nonzero(p); | |
181 | test_is_nonzero(p2); | |
182 | test_is_Y(p); | |
183 | test_is_X(p2); | |
184 | test_ne(p, p2); | |
185 | ||
186 | { | |
187 | shared_ptr<X> q(p); | |
188 | test_eq(p, q); | |
189 | } | |
190 | ||
191 | #if !defined( BOOST_NO_RTTI ) | |
192 | shared_ptr<Y> p3 = dynamic_pointer_cast<Y>(p); | |
193 | shared_ptr<Y> p4 = dynamic_pointer_cast<Y>(p2); | |
194 | ||
195 | test_is_nonzero(p3); | |
196 | test_is_zero(p4); | |
197 | ||
198 | BOOST_TEST(p.use_count() == 2); | |
199 | BOOST_TEST(p2.use_count() == 1); | |
200 | BOOST_TEST(p3.use_count() == 2); | |
201 | ||
202 | test_is_Y(p3); | |
203 | test_eq2(p, p3); | |
204 | test_ne2(p2, p4); | |
205 | #endif | |
206 | ||
207 | shared_ptr<void> p5(p); | |
208 | ||
209 | test_is_nonzero(p5); | |
210 | test_eq2(p, p5); | |
211 | ||
212 | weak_ptr<X> wp1(p2); | |
213 | ||
214 | BOOST_TEST(!wp1.expired()); | |
215 | BOOST_TEST(wp1.use_count() != 0); | |
216 | ||
217 | p.reset(); | |
218 | p2.reset(); | |
219 | #if !defined( BOOST_NO_RTTI ) | |
220 | p3.reset(); | |
221 | p4.reset(); | |
222 | #endif | |
223 | ||
224 | test_is_zero(p); | |
225 | test_is_zero(p2); | |
226 | #if !defined( BOOST_NO_RTTI ) | |
227 | test_is_zero(p3); | |
228 | test_is_zero(p4); | |
229 | #endif | |
230 | ||
231 | BOOST_TEST(p5.use_count() == 1); | |
232 | ||
233 | BOOST_TEST(wp1.expired()); | |
234 | BOOST_TEST(wp1.use_count() == 0); | |
235 | ||
236 | try | |
237 | { | |
238 | shared_ptr<X> sp1(wp1); | |
239 | BOOST_ERROR("shared_ptr<X> sp1(wp1) failed to throw"); | |
240 | } | |
241 | catch(boost::bad_weak_ptr const &) | |
242 | { | |
243 | } | |
244 | ||
245 | test_is_zero(wp1.lock()); | |
246 | ||
247 | weak_ptr<X> wp2 = static_pointer_cast<X>(p5); | |
248 | ||
249 | BOOST_TEST(wp2.use_count() == 1); | |
250 | test_is_Y(wp2); | |
251 | test_nonshared(wp1, wp2); | |
252 | ||
253 | // Scoped to not affect the subsequent use_count() tests. | |
254 | { | |
255 | shared_ptr<X> sp2(wp2); | |
256 | test_is_nonzero(wp2.lock()); | |
257 | } | |
258 | ||
259 | #if !defined( BOOST_NO_RTTI ) | |
260 | weak_ptr<Y> wp3 = dynamic_pointer_cast<Y>(wp2.lock()); | |
261 | ||
262 | BOOST_TEST(wp3.use_count() == 1); | |
263 | test_shared(wp2, wp3); | |
264 | ||
265 | weak_ptr<X> wp4(wp3); | |
266 | ||
267 | BOOST_TEST(wp4.use_count() == 1); | |
268 | test_shared(wp2, wp4); | |
269 | #endif | |
270 | ||
271 | wp1 = p2; | |
272 | test_is_zero(wp1.lock()); | |
273 | ||
274 | #if !defined( BOOST_NO_RTTI ) | |
275 | wp1 = p4; | |
276 | wp1 = wp3; | |
277 | #endif | |
278 | wp1 = wp2; | |
279 | ||
280 | BOOST_TEST(wp1.use_count() == 1); | |
281 | test_shared(wp1, wp2); | |
282 | ||
283 | weak_ptr<X> wp5; | |
284 | ||
285 | bool b1 = wp1 < wp5; | |
286 | bool b2 = wp5 < wp1; | |
287 | ||
288 | p5.reset(); | |
289 | ||
290 | BOOST_TEST(wp1.use_count() == 0); | |
291 | BOOST_TEST(wp2.use_count() == 0); | |
292 | #if !defined( BOOST_NO_RTTI ) | |
293 | BOOST_TEST(wp3.use_count() == 0); | |
294 | #endif | |
295 | ||
296 | // Test operator< stability for std::set< weak_ptr<> > | |
297 | // Thanks to Joe Gottman for pointing this out | |
298 | ||
299 | BOOST_TEST(b1 == (wp1 < wp5)); | |
300 | BOOST_TEST(b2 == (wp5 < wp1)); | |
301 | ||
302 | { | |
303 | // note that both get_object and release_object deal with int* | |
304 | shared_ptr<void> p6(get_object(), release_object); | |
305 | } | |
306 | } | |
307 | ||
308 | BOOST_TEST(cnt == 0); | |
309 | ||
310 | return boost::report_errors(); | |
311 | } |