]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
f67539c2 | 2 | // test_smart_cast.cpp: |
7c673cae | 3 | |
f67539c2 | 4 | // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . |
7c673cae FG |
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 | ||
16 | using namespace boost::serialization; | |
17 | ||
18 | class Base1 : public boost::noncopyable | |
19 | { | |
20 | char a; | |
21 | }; | |
22 | ||
23 | class Base2 | |
24 | { | |
25 | int b; | |
26 | }; | |
27 | ||
28 | #ifdef BOOST_MSVC | |
29 | # pragma warning(push) | |
30 | # pragma warning(disable : 4511 4512) | |
31 | #endif | |
32 | ||
33 | class 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 | ||
46 | void 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 &>(d); | |
52 | Base2 & scb2 = smart_cast<Base2 &, Derived &>(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 | ||
70 | void 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 &>(d); | |
76 | Base2 & scb2 = smart_cast_reference<Base2 &>(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 | ||
94 | void 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 | ||
120 | class VBase1 : public boost::noncopyable | |
121 | { | |
122 | char a; | |
123 | public: | |
124 | virtual ~VBase1(){}; | |
125 | }; | |
126 | ||
127 | class VBase2 | |
128 | { | |
129 | int b; | |
130 | public: | |
131 | virtual ~VBase2(){}; | |
132 | }; | |
133 | ||
134 | #ifdef BOOST_MSVC | |
135 | # pragma warning(push) | |
136 | # pragma warning(disable : 4511 4512) | |
137 | #endif | |
138 | ||
139 | class VDerived : public VBase1, public VBase2 | |
140 | { | |
141 | long c; | |
142 | public: | |
143 | virtual ~VDerived(){}; | |
144 | }; | |
145 | ||
146 | #ifdef BOOST_MSVC | |
147 | #pragma warning(pop) | |
148 | #endif | |
149 | ||
150 | // see above | |
151 | ||
152 | void 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 &>(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 | ||
176 | void 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 &>(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 | ||
200 | void 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 | ||
225 | int | |
226 | test_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 | } |