1 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
2 | // test_void_cast.cpp: test implementation of run-time casting of void pointers |
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 <cstddef> // NULL |
11 | #include "test_tools.hpp" |
12 | #include <boost/serialization/extended_type_info_typeid.hpp> |
13 | #include <boost/serialization/void_cast.hpp> |
14 | #include <boost/serialization/singleton.hpp> |
15 | |
16 | class Base1 |
17 | { |
18 | char a; |
19 | }; |
20 | |
21 | class Base2 |
22 | { |
23 | int b; |
24 | }; |
25 | |
26 | class Derived : public Base1, public Base2 |
27 | { |
28 | long c; |
29 | }; |
30 | |
31 | class MostDerived : public Derived |
32 | { |
33 | char d[32]; |
34 | }; |
35 | |
36 | template<class T> |
37 | const boost::serialization::extended_type_info & eti(){ |
38 | return boost::serialization::singleton< |
39 | boost::serialization::extended_type_info_typeid< T > |
40 | >::get_const_instance(); |
41 | } |
42 | |
43 | int |
44 | test_main( int /* argc */, char* /* argv */[] ) |
45 | { |
46 | MostDerived md; |
47 | MostDerived* pmd =& md; |
48 | Derived* pd = static_cast<Derived*>(pmd); |
49 | |
50 | Base2* pb2 = static_cast<Base2*>(pmd); |
51 | Base1* pb1 = static_cast<Base1*>(pd); |
52 | |
53 | void* vpmd = static_cast<void*>(pmd); |
54 | void* vpb1 = static_cast<void*>(pb1); |
55 | void* vpb2 = static_cast<void*>(pb2); |
56 | void* vpd = static_cast<void*>(pd); |
57 | |
58 | // simple casts only requiring table lookup |
59 | BOOST_CHECK(vpd == boost::serialization::void_downcast( |
60 | eti<Derived>(), |
61 | eti<Base1>(), |
62 | vpb1 |
63 | )); |
64 | BOOST_CHECK(vpb1 == boost::serialization::void_upcast( |
65 | eti<Derived>(), |
66 | eti<Base1>(), |
67 | vpd |
68 | )); |
69 | BOOST_CHECK(vpd == boost::serialization::void_downcast( |
70 | eti<Derived>(), |
71 | eti<Base2>(), |
72 | vpb2 |
73 | )); |
74 | BOOST_CHECK(vpb2 == boost::serialization::void_upcast( |
75 | eti<Derived>(), |
76 | eti<Base2>(), |
77 | vpd |
78 | )); |
79 | BOOST_CHECK(vpmd == boost::serialization::void_downcast( |
80 | eti<MostDerived>(), |
81 | eti<Derived>(), |
82 | vpd |
83 | )); |
84 | BOOST_CHECK(vpd == boost::serialization::void_upcast( |
85 | eti<MostDerived>(), |
86 | eti<Derived>(), |
87 | vpmd |
88 | )); |
89 | // note relationship between MostDerived and Base1 is automatically derived |
90 | BOOST_CHECK(vpmd == boost::serialization::void_downcast( |
91 | eti<MostDerived>(), |
92 | eti<Base1>(), |
93 | vpb1 |
94 | )); |
95 | BOOST_CHECK(vpb1 == boost::serialization::void_upcast( |
96 | eti<MostDerived>(), |
97 | eti<Base1>(), |
98 | vpmd |
99 | )); |
100 | |
101 | // note relationship between MostDerived and Base2 is automatically derived |
102 | BOOST_CHECK(vpmd == boost::serialization::void_downcast( |
103 | eti<MostDerived>(), |
104 | eti<Base2>(), |
105 | vpb2 |
106 | )); |
107 | BOOST_CHECK(vpb2 == boost::serialization::void_upcast( |
108 | eti<MostDerived>(), |
109 | eti<Base2>(), |
110 | vpmd |
111 | )); |
112 | |
113 | // note: currently derivations are not optimised. See void_cast.cpp |
114 | // for and explanation. These should still work though. |
115 | |
116 | // need to double check to validate speed up optimization of derivations |
117 | BOOST_CHECK(vpmd == boost::serialization::void_downcast( |
118 | eti<MostDerived>(), |
119 | eti<Base1>(), |
120 | vpb1 |
121 | )); |
122 | BOOST_CHECK(vpb1 == boost::serialization::void_upcast( |
123 | eti<MostDerived>(), |
124 | eti<Base1>(), |
125 | vpmd |
126 | )); |
127 | BOOST_CHECK(vpmd == boost::serialization::void_downcast( |
128 | eti<MostDerived>(), |
129 | eti<Base2>(), |
130 | vpb2 |
131 | )); |
132 | BOOST_CHECK(vpb2 == boost::serialization::void_upcast( |
133 | eti<MostDerived>(), |
134 | eti<Base2>(), |
135 | vpmd |
136 | )); |
137 | |
138 | // check things that should fail |
139 | BOOST_CHECK(NULL == boost::serialization::void_downcast( |
140 | eti<Base2>(), |
141 | eti<Base1>(), |
142 | vpb1 |
143 | )); |
144 | |
145 | // note that a fundamental feature is that derived/base pairs are created |
146 | // at compiler time so that all are registered before the main program starts |
147 | // so leave the registration here at the end to verify this. Note bogus arguments |
148 | // to workaround msvc 6 bug |
149 | boost::serialization::void_cast_register<Derived, Base1>( |
150 | static_cast<Derived *>(NULL), |
151 | static_cast<Base1 *>(NULL) |
152 | ); |
153 | boost::serialization::void_cast_register<Derived, Base2>( |
154 | static_cast<Derived *>(NULL), |
155 | static_cast<Base2 *>(NULL) |
156 | ); |
157 | boost::serialization::void_cast_register<MostDerived, Derived>( |
158 | static_cast<MostDerived *>(NULL), |
159 | static_cast<Derived *>(NULL) |
160 | ); |
161 | |
162 | return EXIT_SUCCESS; |
163 | } |
164 | |
165 | // EOF |
166 | |