]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/conversion/test/polymorphic_cast_test.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / conversion / test / polymorphic_cast_test.cpp
1 //
2 // Test boost::polymorphic_cast, boost::polymorphic_downcast and
3 // boost::polymorphic_pointer_cast, boost::polymorphic_pointer_downcast
4 //
5 // Copyright 1999 Beman Dawes
6 // Copyright 1999 Dave Abrahams
7 // Copyright 2014 Peter Dimov
8 // Copyright 2014 Boris Rasin, Antony Polukhin
9 //
10 // Distributed under the Boost Software License, Version 1.0.
11 //
12 // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
13 //
14
15 #define BOOST_ENABLE_ASSERT_HANDLER
16 #include <boost/polymorphic_cast.hpp>
17 #include <boost/polymorphic_pointer_cast.hpp>
18 #include <boost/smart_ptr/shared_ptr.hpp>
19 #include <boost/smart_ptr/intrusive_ptr.hpp>
20 #include <boost/smart_ptr/intrusive_ref_counter.hpp>
21 #include <boost/core/lightweight_test.hpp>
22 #include <string>
23 #include <memory>
24
25 static bool expect_assertion = false;
26 static int assertion_failed_count = 0;
27
28 //assertion handler throws it to exit like assert, but to be able to catch it and stop
29 //usage: BOOST_TEST_THROWS( function_with_assert(), expected_assertion );
30 struct expected_assertion {};
31
32 // BOOST_ASSERT custom handler
33 void boost::assertion_failed( char const * expr, char const * function, char const * file, long line )
34 {
35 if( expect_assertion )
36 {
37 ++assertion_failed_count;
38 throw expected_assertion();
39 }
40 else
41 {
42 BOOST_ERROR( "unexpected assertion" );
43
44 BOOST_LIGHTWEIGHT_TEST_OSTREAM
45 << file << "(" << line << "): assertion '" << expr << "' failed in function '"
46 << function << "'" << std::endl;
47 }
48 }
49
50 //
51
52 struct Base : boost::intrusive_ref_counter<Base>
53 {
54 virtual ~Base() {}
55 virtual std::string kind() { return "Base"; }
56 };
57
58 struct Base2
59 {
60 virtual ~Base2() {}
61 virtual std::string kind2() { return "Base2"; }
62 };
63
64 struct Derived : public Base, Base2
65 {
66 virtual std::string kind() { return "Derived"; }
67 };
68
69 static void test_polymorphic_cast()
70 {
71 Base * base = new Derived;
72
73 Derived * derived;
74
75 try
76 {
77 derived = boost::polymorphic_cast<Derived*>( base );
78
79 BOOST_TEST( derived != 0 );
80
81 if( derived != 0 )
82 {
83 BOOST_TEST_EQ( derived->kind(), "Derived" );
84 }
85 }
86 catch( std::bad_cast const& )
87 {
88 BOOST_ERROR( "boost::polymorphic_cast<Derived*>( base ) threw std::bad_cast" );
89 }
90
91 Base2 * base2;
92
93 try
94 {
95 base2 = boost::polymorphic_cast<Base2*>( base ); // crosscast
96
97 BOOST_TEST( base2 != 0 );
98
99 if( base2 != 0 )
100 {
101 BOOST_TEST_EQ( base2->kind2(), "Base2" );
102 }
103 }
104 catch( std::bad_cast const& )
105 {
106 BOOST_ERROR( "boost::polymorphic_cast<Base2*>( base ) threw std::bad_cast" );
107 }
108
109 delete base;
110 }
111
112 static void test_polymorphic_pointer_cast()
113 {
114 Base * base = new Derived;
115
116 Derived * derived;
117
118 try
119 {
120 derived = boost::polymorphic_pointer_cast<Derived>( base );
121
122 BOOST_TEST( derived != 0 );
123
124 if( derived != 0 )
125 {
126 BOOST_TEST_EQ( derived->kind(), "Derived" );
127 }
128 }
129 catch( std::bad_cast const& )
130 {
131 BOOST_ERROR( "boost::polymorphic_pointer_cast<Derived>( base ) threw std::bad_cast" );
132 }
133
134 Base2 * base2;
135
136 try
137 {
138 base2 = boost::polymorphic_pointer_cast<Base2>( base ); // crosscast
139
140 BOOST_TEST( base2 != 0 );
141
142 if( base2 != 0 )
143 {
144 BOOST_TEST_EQ( base2->kind2(), "Base2" );
145 }
146 }
147 catch( std::bad_cast const& )
148 {
149 BOOST_ERROR( "boost::polymorphic_pointer_cast<Base2>( base ) threw std::bad_cast" );
150 }
151
152 boost::shared_ptr<Base> sp_base( base );
153 boost::shared_ptr<Base2> sp_base2;
154 try
155 {
156 sp_base2 = boost::polymorphic_pointer_cast<Base2>( sp_base ); // crosscast
157
158 BOOST_TEST( sp_base2 != 0 );
159
160 if( sp_base2 != 0 )
161 {
162 BOOST_TEST_EQ( sp_base2->kind2(), "Base2" );
163 }
164 }
165 catch( std::bad_cast const& )
166 {
167 BOOST_ERROR( "boost::polymorphic_pointer_cast<Base2>( sp_base ) threw std::bad_cast" );
168 }
169
170 // we do not `delete base;` because sahred_ptr is holding base
171 }
172
173 static void test_polymorphic_downcast()
174 {
175 Base * base = new Derived;
176
177 Derived * derived = boost::polymorphic_downcast<Derived*>( base );
178
179 BOOST_TEST( derived != 0 );
180
181 if( derived != 0 )
182 {
183 BOOST_TEST_EQ( derived->kind(), "Derived" );
184 }
185
186 // polymorphic_downcast can't do crosscasts
187
188 delete base;
189 }
190
191 static void test_polymorphic_pointer_downcast_builtin()
192 {
193 Base * base = new Derived;
194
195 Derived * derived = boost::polymorphic_pointer_downcast<Derived>( base );
196
197 BOOST_TEST( derived != 0 );
198
199 if( derived != 0 )
200 {
201 BOOST_TEST_EQ( derived->kind(), "Derived" );
202 }
203
204 // polymorphic_pointer_downcast can't do crosscasts
205
206 delete base;
207 }
208
209 static void test_polymorphic_pointer_downcast_boost_shared()
210 {
211 boost::shared_ptr<Base> base (new Derived);
212
213 boost::shared_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base );
214
215 BOOST_TEST( derived != 0 );
216
217 if( derived != 0 )
218 {
219 BOOST_TEST_EQ( derived->kind(), "Derived" );
220 }
221 }
222
223 static void test_polymorphic_pointer_downcast_intrusive()
224 {
225 boost::intrusive_ptr<Base> base (new Derived);
226
227 boost::intrusive_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base );
228
229 BOOST_TEST( derived != 0 );
230
231 if( derived != 0 )
232 {
233 BOOST_TEST_EQ( derived->kind(), "Derived" );
234 }
235 }
236
237 #ifndef BOOST_NO_CXX11_SMART_PTR
238
239 static void test_polymorphic_pointer_downcast_std_shared()
240 {
241 std::shared_ptr<Base> base (new Derived);
242
243 std::shared_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base );
244
245 BOOST_TEST( derived != 0 );
246
247 if( derived != 0 )
248 {
249 BOOST_TEST_EQ( derived->kind(), "Derived" );
250 }
251 }
252
253 #endif
254
255 static void test_polymorphic_cast_fail()
256 {
257 Base * base = new Base;
258
259 BOOST_TEST_THROWS( boost::polymorphic_cast<Derived*>( base ), std::bad_cast );
260
261 delete base;
262 }
263
264 static void test_polymorphic_pointer_cast_fail()
265 {
266 Base * base = new Base;
267 BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( base ), std::bad_cast );
268 delete base;
269
270 BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( boost::shared_ptr<Base>(new Base) ), std::bad_cast );
271
272 #ifndef BOOST_NO_CXX11_SMART_PTR
273 BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( std::shared_ptr<Base>(new Base) ), std::bad_cast );
274 #endif
275
276 BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( boost::intrusive_ptr<Base>(new Base) ), std::bad_cast );
277 }
278
279 static void test_polymorphic_downcast_fail()
280 {
281 Base * base = new Base;
282
283 int old_count = assertion_failed_count;
284 expect_assertion = true;
285
286 BOOST_TEST_THROWS( boost::polymorphic_downcast<Derived*>( base ), expected_assertion ); // should assert
287
288 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
289 expect_assertion = false;
290
291 delete base;
292 }
293
294 static void test_polymorphic_pointer_downcast_builtin_fail()
295 {
296 Base * base = new Base;
297
298 int old_count = assertion_failed_count;
299 expect_assertion = true;
300
301 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
302
303 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
304 expect_assertion = false;
305
306 delete base;
307 }
308
309 static void test_polymorphic_pointer_downcast_boost_shared_fail()
310 {
311 boost::shared_ptr<Base> base (new Base);
312
313 int old_count = assertion_failed_count;
314 expect_assertion = true;
315
316 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
317
318 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
319 expect_assertion = false;
320 }
321
322 #ifndef BOOST_NO_CXX11_SMART_PTR
323
324 static void test_polymorphic_pointer_downcast_std_shared_fail()
325 {
326 std::shared_ptr<Base> base (new Base);
327
328 int old_count = assertion_failed_count;
329 expect_assertion = true;
330
331 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
332
333 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
334 expect_assertion = false;
335 }
336
337 #endif
338
339 static void test_polymorphic_pointer_downcast_intrusive_fail()
340 {
341 boost::intrusive_ptr<Base> base (new Base);
342
343 int old_count = assertion_failed_count;
344 expect_assertion = true;
345
346 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion); // should assert
347
348 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
349 expect_assertion = false;
350 }
351
352 int main()
353 {
354 test_polymorphic_cast();
355 test_polymorphic_pointer_cast();
356 test_polymorphic_downcast();
357 test_polymorphic_pointer_downcast_builtin();
358 test_polymorphic_pointer_downcast_boost_shared();
359 test_polymorphic_pointer_downcast_intrusive();
360 test_polymorphic_cast_fail();
361 test_polymorphic_pointer_cast_fail();
362 test_polymorphic_downcast_fail();
363 test_polymorphic_pointer_downcast_builtin_fail();
364 test_polymorphic_pointer_downcast_boost_shared_fail();
365 test_polymorphic_pointer_downcast_intrusive_fail();
366
367 #ifndef BOOST_NO_CXX11_SMART_PTR
368 test_polymorphic_pointer_downcast_std_shared();
369 test_polymorphic_pointer_downcast_std_shared_fail();
370 #endif
371
372 return boost::report_errors();
373 }