]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/conversion/test/polymorphic_cast_test.cpp
bump version to 18.2.2-pve1
[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_pointer = new Derived;
176
177 // test raw pointer cast
178 Derived *derived_pointer = boost::polymorphic_downcast<Derived *>(base_pointer);
179
180 BOOST_TEST(derived_pointer != 0);
181
182 if (derived_pointer != 0)
183 {
184 BOOST_TEST_EQ(derived_pointer->kind(), "Derived");
185 }
186
187 // test reference cast
188 Derived& derived_ref = boost::polymorphic_downcast<Derived&>(*base_pointer);
189 BOOST_TEST_EQ(derived_ref.kind(), "Derived");
190
191 delete base_pointer;
192 }
193
194 static void test_polymorphic_pointer_downcast_builtin()
195 {
196 Base * base = new Derived;
197
198 Derived * derived = boost::polymorphic_pointer_downcast<Derived>( base );
199
200 BOOST_TEST( derived != 0 );
201
202 if( derived != 0 )
203 {
204 BOOST_TEST_EQ( derived->kind(), "Derived" );
205 }
206
207 // polymorphic_pointer_downcast can't do crosscasts
208
209 delete base;
210 }
211
212 static void test_polymorphic_pointer_downcast_boost_shared()
213 {
214 boost::shared_ptr<Base> base (new Derived);
215
216 boost::shared_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base );
217
218 BOOST_TEST( derived != 0 );
219
220 if( derived != 0 )
221 {
222 BOOST_TEST_EQ( derived->kind(), "Derived" );
223 }
224 }
225
226 static void test_polymorphic_pointer_downcast_intrusive()
227 {
228 boost::intrusive_ptr<Base> base (new Derived);
229
230 boost::intrusive_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base );
231
232 BOOST_TEST( derived != 0 );
233
234 if( derived != 0 )
235 {
236 BOOST_TEST_EQ( derived->kind(), "Derived" );
237 }
238 }
239
240 #ifndef BOOST_NO_CXX11_SMART_PTR
241
242 static void test_polymorphic_pointer_downcast_std_shared()
243 {
244 std::shared_ptr<Base> base (new Derived);
245
246 std::shared_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base );
247
248 BOOST_TEST( derived != 0 );
249
250 if( derived != 0 )
251 {
252 BOOST_TEST_EQ( derived->kind(), "Derived" );
253 }
254 }
255
256 #endif
257
258 static void test_polymorphic_cast_fail()
259 {
260 Base * base = new Base;
261
262 BOOST_TEST_THROWS( boost::polymorphic_cast<Derived*>( base ), std::bad_cast );
263
264 delete base;
265 }
266
267 static void test_polymorphic_pointer_cast_fail()
268 {
269 Base * base = new Base;
270 BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( base ), std::bad_cast );
271 delete base;
272
273 BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( boost::shared_ptr<Base>(new Base) ), std::bad_cast );
274
275 #ifndef BOOST_NO_CXX11_SMART_PTR
276 BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( std::shared_ptr<Base>(new Base) ), std::bad_cast );
277 #endif
278
279 BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( boost::intrusive_ptr<Base>(new Base) ), std::bad_cast );
280 }
281
282 static void test_polymorphic_downcast_fail()
283 {
284 Base * base_pointer = new Base;
285
286 {
287 // test raw pointer cast
288
289 int old_count = assertion_failed_count;
290 expect_assertion = true;
291
292 BOOST_TEST_THROWS(boost::polymorphic_downcast<Derived *>(base_pointer), expected_assertion); // should assert
293
294 BOOST_TEST_EQ(assertion_failed_count, old_count + 1);
295 expect_assertion = false;
296 }
297 {
298 // test reference cast
299
300 int old_count = assertion_failed_count;
301 expect_assertion = true;
302
303 BOOST_TEST_THROWS(boost::polymorphic_downcast<Derived &>(*base_pointer), expected_assertion); // should assert
304
305 BOOST_TEST_EQ(assertion_failed_count, old_count + 1);
306 expect_assertion = false;
307 }
308
309 delete base_pointer;
310 }
311
312 static void test_polymorphic_pointer_downcast_builtin_fail()
313 {
314 Base * base = new Base;
315
316 int old_count = assertion_failed_count;
317 expect_assertion = true;
318
319 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
320
321 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
322 expect_assertion = false;
323
324 delete base;
325 }
326
327 static void test_polymorphic_pointer_downcast_boost_shared_fail()
328 {
329 boost::shared_ptr<Base> base (new Base);
330
331 int old_count = assertion_failed_count;
332 expect_assertion = true;
333
334 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
335
336 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
337 expect_assertion = false;
338 }
339
340 #ifndef BOOST_NO_CXX11_SMART_PTR
341
342 static void test_polymorphic_pointer_downcast_std_shared_fail()
343 {
344 std::shared_ptr<Base> base (new Base);
345
346 int old_count = assertion_failed_count;
347 expect_assertion = true;
348
349 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
350
351 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
352 expect_assertion = false;
353 }
354
355 #endif
356
357 static void test_polymorphic_pointer_downcast_intrusive_fail()
358 {
359 boost::intrusive_ptr<Base> base (new Base);
360
361 int old_count = assertion_failed_count;
362 expect_assertion = true;
363
364 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion); // should assert
365
366 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
367 expect_assertion = false;
368 }
369
370 int main()
371 {
372 test_polymorphic_cast();
373 test_polymorphic_pointer_cast();
374 test_polymorphic_downcast();
375 test_polymorphic_pointer_downcast_builtin();
376 test_polymorphic_pointer_downcast_boost_shared();
377 test_polymorphic_pointer_downcast_intrusive();
378 test_polymorphic_cast_fail();
379 test_polymorphic_pointer_cast_fail();
380 test_polymorphic_downcast_fail();
381 test_polymorphic_pointer_downcast_builtin_fail();
382 test_polymorphic_pointer_downcast_boost_shared_fail();
383 test_polymorphic_pointer_downcast_intrusive_fail();
384
385 #ifndef BOOST_NO_CXX11_SMART_PTR
386 test_polymorphic_pointer_downcast_std_shared();
387 test_polymorphic_pointer_downcast_std_shared_fail();
388 #endif
389
390 return boost::report_errors();
391 }