]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 |