001 #ifndef BOOST_SMART_CAST_HPP
002 #define BOOST_SMART_CAST_HPP
003
004
005 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
006 # pragma once
007 #endif
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037 #include <exception>
038 #include <typeinfo>
039
040 #include <boost/config.hpp>
041 #include <boost/static_assert.hpp>
042
043 #include <boost/type_traits/is_base_and_derived.hpp>
044 #include <boost/type_traits/is_polymorphic.hpp>
045 #include <boost/type_traits/is_pointer.hpp>
046 #include <boost/type_traits/is_reference.hpp>
047 #include <boost/type_traits/is_same.hpp>
048 #include <boost/type_traits/remove_pointer.hpp>
049 #include <boost/type_traits/remove_reference.hpp>
050
051 #include <boost/mpl/eval_if.hpp>
052 #include <boost/mpl/if.hpp>
053 #include <boost/mpl/or.hpp>
054 #include <boost/mpl/and.hpp>
055 #include <boost/mpl/not.hpp>
056 #include <boost/mpl/identity.hpp>
057
058 namespace boost {
059 namespace smart_cast_impl {
060
061 template<class T>
062 struct reference {
063
064 struct polymorphic {
065
066 struct linear {
067 template<class U>
068 static T cast(U & u){
069 return static_cast<T>(u);
070 }
071 };
072
073 struct cross {
074 template<class U>
075 static T cast(U & u){
076 return dynamic_cast<T>(u);
077 }
078 };
079
080 template<class U>
081 static T cast(U & u){
082
083 #if ! defined(NDEBUG) \
084 || defined(__BORLANDC__) && (__BORLANDC__ <= 0x560) \
085 || defined(__MWERKS__)
086
087 return cross::cast(u);
088 #else
089
090
091
092
093
094 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
095 BOOST_DEDUCED_TYPENAME mpl::and_<
096 mpl::not_<is_base_and_derived<
097 BOOST_DEDUCED_TYPENAME remove_reference<T>::type,
098 U
099 > >,
100 mpl::not_<is_base_and_derived<
101 U,
102 BOOST_DEDUCED_TYPENAME remove_reference<T>::type
103 > >
104 >,
105
106 mpl::identity<cross>,
107 mpl::identity<linear>
108 >::type typex;
109
110 return typex::cast(u);
111 #endif
112 }
113 };
114
115 struct non_polymorphic {
116 template<class U>
117 static T cast(U & u){
118 return static_cast<T>(u);
119 }
120 };
121 template<class U>
122 static T cast(U & u){
123 #if defined(__BORLANDC__)
124 return mpl::eval_if<
125 boost::is_polymorphic<U>,
126 mpl::identity<polymorphic>,
127 mpl::identity<non_polymorphic>
128 >::type::cast(u);
129 #else
130 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
131 boost::is_polymorphic<U>,
132 mpl::identity<polymorphic>,
133 mpl::identity<non_polymorphic>
134 >::type typex;
135 return typex::cast(u);
136 #endif
137 }
138 };
139
140 template<class T>
141 struct pointer {
142
143 struct polymorphic {
144
145
146
147 #if 0
148 struct linear {
149 template<class U>
150 static T cast(U * u){
151 return static_cast<T>(u);
152 }
153 };
154
155 struct cross {
156 template<class U>
157 static T cast(U * u){
158 T tmp = dynamic_cast<T>(u);
159 #ifndef NDEBUG
160 if ( tmp == 0 ) throw std::bad_cast();
161 #endif
162 return tmp;
163 }
164 };
165
166 template<class U>
167 static T cast(U * u){
168
169 #if ! defined(NDEBUG) || defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
170
171 return cross::cast(u);
172 #else
173
174
175
176
177
178 typedef
179 BOOST_DEDUCED_TYPENAME mpl::eval_if<
180 BOOST_DEDUCED_TYPENAME mpl::and_<
181 mpl::not_<is_base_and_derived<
182 BOOST_DEDUCED_TYPENAME remove_pointer<T>::type,
183 U
184 > >,
185 mpl::not_<is_base_and_derived<
186 U,
187 BOOST_DEDUCED_TYPENAME remove_pointer<T>::type
188 > >
189 >,
190
191 mpl::identity<cross>,
192 mpl::identity<linear>
193 >::type typex;
194 return typex::cast(u);
195 #endif
196 }
197 #else
198 template<class U>
199 static T cast(U * u){
200 T tmp = dynamic_cast<T>(u);
201 #ifndef NDEBUG
202 if ( tmp == 0 ) throw std::bad_cast();
203 #endif
204 return tmp;
205 }
206 #endif
207 };
208
209 struct non_polymorphic {
210 template<class U>
211 static T cast(U * u){
212 return static_cast<T>(u);
213 }
214 };
215
216 template<class U>
217 static T cast(U * u){
218 #if defined(__BORLANDC__)
219 return mpl::eval_if<
220 boost::is_polymorphic<U>,
221 mpl::identity<polymorphic>,
222 mpl::identity<non_polymorphic>
223 >::type::cast(u);
224 #else
225 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
226 boost::is_polymorphic<U>,
227 mpl::identity<polymorphic>,
228 mpl::identity<non_polymorphic>
229 >::type typex;
230 return typex::cast(u);
231 #endif
232 }
233
234 };
235
236 template<class TPtr>
237 struct void_pointer {
238 template<class UPtr>
239 static TPtr cast(UPtr uptr){
240 return static_cast<TPtr>(uptr);
241 }
242 };
243
244 template<class T>
245 struct error {
246
247
248
249 template<class U>
250 static T cast(U u){
251 BOOST_STATIC_ASSERT(sizeof(T)==0);
252 return * static_cast<T *>(NULL);
253 }
254 };
255
256 }
257
258
259
260
261
262
263 template<class T, class U>
264 T smart_cast(U u) {
265 typedef
266 BOOST_DEDUCED_TYPENAME mpl::eval_if<
267 BOOST_DEDUCED_TYPENAME mpl::or_<
268 boost::is_same<void *, U>,
269 boost::is_same<void *, T>,
270 boost::is_same<const void *, U>,
271 boost::is_same<const void *, T>
272 >,
273 mpl::identity<smart_cast_impl::void_pointer<T> >,
274
275 BOOST_DEDUCED_TYPENAME mpl::eval_if<boost::is_pointer<U>,
276 mpl::identity<smart_cast_impl::pointer<T> >,
277
278 BOOST_DEDUCED_TYPENAME mpl::eval_if<boost::is_reference<U>,
279 mpl::identity<smart_cast_impl::reference<T> >,
280
281 mpl::identity<smart_cast_impl::error<T>
282 >
283 >
284 >
285 >::type typex;
286 return typex::cast(u);
287 }
288
289
290
291 template<class T, class U>
292 T smart_cast_reference(U & u) {
293 return smart_cast_impl::reference<T>::cast(u);
294 }
295
296 }
297
298 #endif
299
| Due to the LXR bug, the updates fail sometimes to remove references to deleted files. The Saturday's full rebuilds fix these problems |
|
This page was automatically generated by the
LXR engine.
|
|