Report problems to ATLAS LXR Team (with time and IP address indicated)

The LXR Cross Referencer

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Architecture: linux ]
Version: head ] [ nightly ] [ GaudiDev ]
  Links to LXR source navigation pages for stable releases [ 12.*.* ]   [ 13.*.* ]   [ 14.*.* ] 

001 #ifndef BOOST_SMART_CAST_HPP
002 #define BOOST_SMART_CAST_HPP
003 
004 // MS compatible compilers support #pragma once
005 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
006 # pragma once
007 #endif
008 
009 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
010 // smart_cast.hpp:
011 
012 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 
013 // Use, modification and distribution is subject to the Boost Software
014 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
015 // http://www.boost.org/LICENSE_1_0.txt)
016 
017 //  See http://www.boost.org for updates, documentation, and revision history.
018 
019 // casting of pointers and references.  
020 
021 // In casting between different C++ classes, there are a number of
022 // rules that have to be kept in mind in deciding whether to use
023 // static_cast or dynamic_cast.  
024 
025 // a) dynamic casting can only be applied when one of the types is polymorphic
026 // Otherwise static_cast must be used.
027 // b) only dynamic casting can do runtime error checking
028 // use of static_cast is generally un checked even when compiled for debug
029 // c) static_cast would be considered faster than dynamic_cast.
030 
031 // If casting is applied to a template parameter, there is no apriori way
032 // to know which of the two casting methods will be permitted or convenient.
033 
034 // smart_cast uses C++ type_traits, and program debug mode to select the
035 // most convenient cast to use.
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                 // if we're in debug mode
083                 #if ! defined(NDEBUG)                               \
084                 || defined(__BORLANDC__) && (__BORLANDC__ <= 0x560) \
085                 || defined(__MWERKS__)
086                     // do a checked dynamic cast
087                     return cross::cast(u);
088                 #else
089                     // borland 5.51 chokes here so we can't use it
090                     // note: if remove_reference isn't function for these types
091                     // cross casting will be selected this will work but will
092                     // not be the most efficient method. This will conflict with
093                     // the original smart_cast motivation.
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                             // borland chokes w/o full qualification here
106                             mpl::identity<cross>,
107                             mpl::identity<linear>
108                     >::type typex;
109                     // typex works around gcc 2.95 issue
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             // unfortunately, this below fails to work for virtual base 
145             // classes.  need has_virtual_base to do this.
146             // Subject for further study
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                 // if we're in debug mode
169                 #if ! defined(NDEBUG) || defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
170                     // do a checked dynamic cast
171                     return cross::cast(u);
172                 #else
173                     // borland 5.51 chokes here so we can't use it
174                     // note: if remove_pointer isn't function for these types
175                     // cross casting will be selected this will work but will
176                     // not be the most efficient method. This will conflict with
177                     // the original smart_cast motivation.
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                             // borland chokes w/o full qualification here
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         // if we get here, its because we are using one argument in the
247         // cast on a system which doesn't support partial template 
248         // specialization
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 } // smart_cast_impl
257 
258 // this implements:
259 // smart_cast<Target *, Source *>(Source * s)
260 // smart_cast<Target &, Source &>(s)
261 // note that it will fail with
262 // smart_cast<Target &>(s)
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         // else
275         BOOST_DEDUCED_TYPENAME mpl::eval_if<boost::is_pointer<U>,
276             mpl::identity<smart_cast_impl::pointer<T> >,
277         // else
278         BOOST_DEDUCED_TYPENAME mpl::eval_if<boost::is_reference<U>,
279             mpl::identity<smart_cast_impl::reference<T> >,
280         // else
281             mpl::identity<smart_cast_impl::error<T>
282         >
283         >
284         >
285         >::type typex;
286     return typex::cast(u);
287 }
288 
289 // this implements:
290 // smart_cast_reference<Target &>(Source & s)
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 } // namespace boost
297 
298 #endif // BOOST_SMART_CAST_HPP
299 

source navigation ] diff markup ] identifier search ] general search ]

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. Valid HTML 4.01!