]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/conversion/test/polymorphic_cast_test.cpp
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / boost / libs / conversion / test / polymorphic_cast_test.cpp
CommitLineData
7c673cae
FG
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
25static bool expect_assertion = false;
26static int assertion_failed_count = 0;
27
b32b8144
FG
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 );
30struct expected_assertion {};
31
7c673cae
FG
32// BOOST_ASSERT custom handler
33void boost::assertion_failed( char const * expr, char const * function, char const * file, long line )
34{
35 if( expect_assertion )
36 {
37 ++assertion_failed_count;
b32b8144 38 throw expected_assertion();
7c673cae
FG
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
52struct Base : boost::intrusive_ref_counter<Base>
53{
54 virtual ~Base() {}
55 virtual std::string kind() { return "Base"; }
56};
57
58struct Base2
59{
60 virtual ~Base2() {}
61 virtual std::string kind2() { return "Base2"; }
62};
63
64struct Derived : public Base, Base2
65{
66 virtual std::string kind() { return "Derived"; }
67};
68
69static 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
112static 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
173static void test_polymorphic_downcast()
174{
f67539c2 175 Base *base_pointer = new Derived;
7c673cae 176
f67539c2
TL
177 // test raw pointer cast
178 Derived *derived_pointer = boost::polymorphic_downcast<Derived *>(base_pointer);
7c673cae 179
f67539c2 180 BOOST_TEST(derived_pointer != 0);
7c673cae 181
f67539c2 182 if (derived_pointer != 0)
7c673cae 183 {
f67539c2 184 BOOST_TEST_EQ(derived_pointer->kind(), "Derived");
7c673cae
FG
185 }
186
f67539c2
TL
187 // test reference cast
188 Derived& derived_ref = boost::polymorphic_downcast<Derived&>(*base_pointer);
189 BOOST_TEST_EQ(derived_ref.kind(), "Derived");
7c673cae 190
f67539c2 191 delete base_pointer;
7c673cae
FG
192}
193
194static 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
212static 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
226static 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
242static 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
258static 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
267static 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
282static void test_polymorphic_downcast_fail()
283{
f67539c2 284 Base * base_pointer = new Base;
7c673cae 285
f67539c2
TL
286 {
287 // test raw pointer cast
7c673cae 288
f67539c2
TL
289 int old_count = assertion_failed_count;
290 expect_assertion = true;
7c673cae 291
f67539c2 292 BOOST_TEST_THROWS(boost::polymorphic_downcast<Derived *>(base_pointer), expected_assertion); // should assert
7c673cae 293
f67539c2
TL
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;
7c673cae
FG
310}
311
312static 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
b32b8144 319 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
7c673cae
FG
320
321 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
322 expect_assertion = false;
323
324 delete base;
325}
326
327static 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
b32b8144 334 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
7c673cae
FG
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
342static 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
b32b8144 349 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
7c673cae
FG
350
351 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
352 expect_assertion = false;
353}
354
355#endif
356
357static 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
b32b8144 364 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion); // should assert
7c673cae
FG
365
366 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
367 expect_assertion = false;
368}
369
370int 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}