• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 
test_static_reference_cast_2()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 
test_static_reference_cast_1()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 
test_static_pointer_cast()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:
~VBase1()124     virtual ~VBase1(){};
125 };
126 
127 class VBase2
128 {
129     int b;
130 public:
~VBase2()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:
~VDerived()143     virtual ~VDerived(){};
144 };
145 
146 #ifdef BOOST_MSVC
147 #pragma warning(pop)
148 #endif
149 
150 // see above
151 
test_dynamic_reference_cast_2()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 
test_dynamic_reference_cast_1()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 
test_dynamic_pointer_cast()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
test_main(int,char * [])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 }
237