]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/smart_ptr/test/shared_ptr_basic_test.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / smart_ptr / test / shared_ptr_basic_test.cpp
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 }