1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// test_smart_cast.cpp:
3
4// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
5// Use, modification and distribution is subject to the Boost Software
6// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8// <gennadiy.rozental@tfn.com>
9
10#include <exception>
11#include <boost/serialization/smart_cast.hpp>
12
13#include "test_tools.hpp"
14#include <boost/noncopyable.hpp>
15
16using namespace boost::serialization;
17
18class Base1 : public boost::noncopyable
19{
20 char a;
21};
22
23class Base2
24{
25 int b;
26};
27
28#ifdef BOOST_MSVC
29# pragma warning(push)
30# pragma warning(disable : 4511 4512)
31#endif
32
33class Derived : public Base1, public Base2
34{
35 long c;
36};
37
38#ifdef BOOST_MSVC
39#pragma warning(pop)
40#endif
41
42// if compiler doesn't support TPS, the smart_cast syntax doesn't
43// work for references. One has to use the smart_cast_reference
44// syntax (tested below ) instead.
45
46void test_static_reference_cast_2(){
47 Derived d;
48 Base1 & b1 = static_cast<Base1 &>(d);
49 Base2 & b2 = static_cast<Base2 &>(d);
50
51 Base1 & scb1 = smart_cast<Base1 &, Derived &>(u&: d);
52 Base2 & scb2 = smart_cast<Base2 &, Derived &>(u&: d);
53 BOOST_CHECK_EQUAL(& b1, & scb1);
54 BOOST_CHECK_EQUAL(& b2, & scb2);
55
56 // downcast
57// BOOST_CHECK_EQUAL(& d, & (smart_cast<Derived &, Base1 &>(b1)));
58// BOOST_CHECK_EQUAL(& d, & (smart_cast<Derived &, Base2 &>(b2)));
59
60 // crosscast pointers fails at compiler time
61 // BOOST_CHECK_EQUAL(pB2,smart_cast<B2 *>(pB1));
62 // though explicit cross cast will always work
63 BOOST_CHECK_EQUAL(& b2,(
64 & smart_cast<Base2 &, Derived &>(
65 smart_cast<Derived &, Base1 &>(b1)
66 ))
67 );
68}
69
70void test_static_reference_cast_1(){
71 Derived d;
72 Base1 & b1 = static_cast<Base1 &>(d);
73 Base2 & b2 = static_cast<Base2 &>(d);
74
75 Base1 & scb1 = smart_cast_reference<Base1 &>(u&: d);
76 Base2 & scb2 = smart_cast_reference<Base2 &>(u&: d);
77 BOOST_CHECK_EQUAL(& b1, & scb1);
78 BOOST_CHECK_EQUAL(& b2, & scb2);
79
80 // downcast
81 BOOST_CHECK_EQUAL(& d, & (smart_cast_reference<Derived &>(b1)));
82 BOOST_CHECK_EQUAL(& d, & (smart_cast_reference<Derived &>(b2)));
83
84 // crosscast pointers fails at compiler time
85 // BOOST_CHECK_EQUAL(pB2,smart_cast<B2 *>(pB1));
86 // though explicit cross cast will always work
87 BOOST_CHECK_EQUAL(& b2,(
88 & smart_cast_reference<Base2 &>(
89 smart_cast_reference<Derived &>(b1)
90 ))
91 );
92}
93
94void test_static_pointer_cast(){
95 // pointers
96 Derived d;
97 Derived *pD = & d;
98 Base1 *pB1 = pD;
99 Base2 *pB2 = pD;
100
101 // upcast
102 BOOST_CHECK_EQUAL(pB1, smart_cast<Base1 *>(pD));
103 BOOST_CHECK_EQUAL(pB2, smart_cast<Base2 *>(pD));
104
105 // downcast
106 BOOST_CHECK_EQUAL(pD, smart_cast<Derived *>(pB1));
107 BOOST_CHECK_EQUAL(pD, smart_cast<Derived *>(pB2));
108
109 // crosscast pointers fails at compiler time
110 // BOOST_CHECK_EQUAL(pB2, smart_cast<Base2 *>(pB1));
111
112 // though explicit cross cast will always work
113 BOOST_CHECK_EQUAL(pB2,
114 smart_cast<Base2 *>(
115 smart_cast<Derived *>(pB1)
116 )
117 );
118}
119
120class VBase1 : public boost::noncopyable
121{
122 char a;
123public:
124 virtual ~VBase1(){};
125};
126
127class VBase2
128{
129 int b;
130public:
131 virtual ~VBase2(){};
132};
133
134#ifdef BOOST_MSVC
135# pragma warning(push)
136# pragma warning(disable : 4511 4512)
137#endif
138
139class VDerived : public VBase1, public VBase2
140{
141 long c;
142public:
143 virtual ~VDerived(){};
144};
145
146#ifdef BOOST_MSVC
147#pragma warning(pop)
148#endif
149
150// see above
151
152void test_dynamic_reference_cast_2(){
153 VDerived d;
154 VBase1 &b1 = dynamic_cast<VBase1 &>(d);
155 VBase2 &b2 = static_cast<VBase2 &>(d);
156
157 VBase1 & vb1 = smart_cast<VBase1 &, VDerived &>(u&: d);
158 BOOST_CHECK_EQUAL(& b1, & vb1);
159 BOOST_CHECK_EQUAL(& b2, (& smart_cast<VBase2 &, VDerived &>(d)));
160
161 // downcast
162 BOOST_CHECK_EQUAL(& d, (& smart_cast<VDerived &, VBase1 &>(b1)));
163 BOOST_CHECK_EQUAL(& d, (& smart_cast<VDerived &, VBase2 &>(b2)));
164
165 // crosscast
166 BOOST_CHECK_EQUAL(& b2, (& smart_cast<VBase2 &, VBase1 &>(b1)));
167
168 // explicit cross cast should always work
169 BOOST_CHECK_EQUAL(& b2, (
170 & smart_cast<VBase2 &, VDerived &>(
171 smart_cast<VDerived &, VBase1 &>(b1)
172 ))
173 );
174}
175
176void test_dynamic_reference_cast_1(){
177 VDerived d;
178 VBase1 &b1 = dynamic_cast<VBase1 &>(d);
179 VBase2 &b2 = static_cast<VBase2 &>(d);
180
181 VBase1 & vb1 = smart_cast_reference<VBase1 &>(u&: d);
182 BOOST_CHECK_EQUAL(& b1, & vb1);
183 BOOST_CHECK_EQUAL(& b2, (& smart_cast_reference<VBase2 &>(d)));
184
185 // downcast
186 BOOST_CHECK_EQUAL(& d, (& smart_cast_reference<VDerived &>(b1)));
187 BOOST_CHECK_EQUAL(& d, (& smart_cast_reference<VDerived &>(b2)));
188
189 // crosscast
190 BOOST_CHECK_EQUAL(& b2, (& smart_cast_reference<VBase2 &>(b1)));
191
192 // explicit cross cast should always work
193 BOOST_CHECK_EQUAL(& b2, (
194 & smart_cast_reference<VBase2 &>(
195 smart_cast_reference<VDerived &>(b1)
196 ))
197 );
198}
199
200void test_dynamic_pointer_cast(){
201 // pointers
202 VDerived d;
203 VDerived *pD = & d;
204 VBase1 *pB1 = pD;
205 VBase2 *pB2 = pD;
206
207 // upcast
208 BOOST_CHECK_EQUAL(pB1, smart_cast<VBase1 *>(pD));
209 BOOST_CHECK_EQUAL(pB2, smart_cast<VBase2 *>(pD));
210
211 // downcast
212 BOOST_CHECK_EQUAL(pD, smart_cast<VDerived *>(pB1));
213 BOOST_CHECK_EQUAL(pD, smart_cast<VDerived *>(pB2));
214
215 // crosscast pointers fails at compiler time
216 BOOST_CHECK_EQUAL(pB2, smart_cast<VBase2 *>(pB1));
217 // though explicit cross cast will always work
218 BOOST_CHECK_EQUAL(pB2,
219 smart_cast<VBase2 *>(
220 smart_cast<VDerived *>(pB1)
221 )
222 );
223}
224
225int
226test_main(int /* argc */, char * /* argv */[])
227{
228 test_static_reference_cast_2();
229 test_static_reference_cast_1();
230 test_static_pointer_cast();
231 test_dynamic_reference_cast_2();
232 test_dynamic_reference_cast_1();
233 test_dynamic_pointer_cast();
234
235 return EXIT_SUCCESS;
236}
237

source code of boost/libs/serialization/test/test_smart_cast.cpp