]> git.proxmox.com Git - ceph.git/blame - 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
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{
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
191static 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
209static 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
223static 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
239static 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
255static 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
264static 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
279static void test_polymorphic_downcast_fail()
280{
281 Base * base = new Base;
282
283 int old_count = assertion_failed_count;
284 expect_assertion = true;
285
b32b8144 286 BOOST_TEST_THROWS( boost::polymorphic_downcast<Derived*>( base ), expected_assertion ); // should assert
7c673cae
FG
287
288 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
289 expect_assertion = false;
290
291 delete base;
292}
293
294static 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
b32b8144 301 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
7c673cae
FG
302
303 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
304 expect_assertion = false;
305
306 delete base;
307}
308
309static 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
b32b8144 316 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
7c673cae
FG
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
324static 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
b32b8144 331 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
7c673cae
FG
332
333 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
334 expect_assertion = false;
335}
336
337#endif
338
339static 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
b32b8144 346 BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion); // should assert
7c673cae
FG
347
348 BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
349 expect_assertion = false;
350}
351
352int 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}