exception.hpp
Go to the documentation of this file.
00001 //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
00002 
00003 //Distributed under the Boost Software License, Version 1.0. (See accompanying
00004 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00005 
00006 #ifndef UUID_274DA366004E11DCB1DDFE2E56D89593
00007 #define UUID_274DA366004E11DCB1DDFE2E56D89593
00008 
00009 namespace
00010 boost
00011     {
00012     namespace
00013     exception_detail
00014         {
00015         template <class T>
00016         class
00017         refcount_ptr
00018             {
00019             public:
00020 
00021             refcount_ptr():
00022                 px_(0)
00023                 {
00024                 }
00025 
00026             ~refcount_ptr()
00027                 {
00028                 release();
00029                 }
00030 
00031             refcount_ptr( refcount_ptr const & x ):
00032                 px_(x.px_)
00033                 {
00034                 add_ref();
00035                 }
00036 
00037             refcount_ptr &
00038             operator=( refcount_ptr const & x )
00039                 {
00040                 adopt(x.px_);
00041                 return *this;
00042                 }
00043 
00044             void
00045             adopt( T * px )
00046                 {
00047                 release();
00048                 px_=px;
00049                 add_ref();
00050                 }
00051 
00052             T *
00053             get() const
00054                 {
00055                 return px_;
00056                 }
00057 
00058             private:
00059 
00060             T * px_;
00061 
00062             void
00063             add_ref()
00064                 {
00065                 if( px_ )
00066                     px_->add_ref();
00067                 }
00068 
00069             void
00070             release()
00071                 {
00072                 if( px_ )
00073                     px_->release();
00074                 }
00075             };
00076         }
00077 
00079 
00080     template <class Tag,class T>
00081     class error_info;
00082 
00083     typedef error_info<struct tag_throw_function,char const *> throw_function;
00084     typedef error_info<struct tag_throw_file,char const *> throw_file;
00085     typedef error_info<struct tag_throw_line,int> throw_line;
00086 
00087     template <>
00088     class
00089     error_info<tag_throw_function,char const *>
00090         {
00091         public:
00092         typedef char const * value_type;
00093         value_type v_;
00094         explicit
00095         error_info( value_type v ):
00096             v_(v)
00097             {
00098             }
00099         };
00100 
00101     template <>
00102     class
00103     error_info<tag_throw_file,char const *>
00104         {
00105         public:
00106         typedef char const * value_type;
00107         value_type v_;
00108         explicit
00109         error_info( value_type v ):
00110             v_(v)
00111             {
00112             }
00113         };
00114 
00115     template <>
00116     class
00117     error_info<tag_throw_line,int>
00118         {
00119         public:
00120         typedef int value_type;
00121         value_type v_;
00122         explicit
00123         error_info( value_type v ):
00124             v_(v)
00125             {
00126             }
00127         };
00128 
00129     template <class E,class Tag,class T>
00130     E const & operator<<( E const &, error_info<Tag,T> const & );
00131 
00132     class exception;
00133 
00134     template <class>
00135     class shared_ptr;
00136 
00137     namespace
00138     exception_detail
00139         {
00140         class error_info_base;
00141         struct type_info_;
00142 
00143         struct
00144         error_info_container
00145             {
00146             virtual char const * diagnostic_information() const = 0;
00147             virtual shared_ptr<error_info_base const> get( type_info_ const & ) const = 0;
00148             virtual void set( shared_ptr<error_info_base const> const &, type_info_ const & ) = 0;
00149             virtual void add_ref() const = 0;
00150             virtual void release() const = 0;
00151 
00152             protected:
00153 
00154             virtual
00155             ~error_info_container() throw()
00156                 {
00157                 }
00158             };
00159 
00160         template <class>
00161         struct get_info;
00162 
00163         template <>
00164         struct get_info<throw_function>;
00165 
00166         template <>
00167         struct get_info<throw_file>;
00168 
00169         template <>
00170         struct get_info<throw_line>;
00171 
00172         char const * get_diagnostic_information( exception const & );
00173         }
00174 
00175     class
00176     exception
00177         {
00178         protected:
00179 
00180         exception():
00181             throw_function_(0),
00182             throw_file_(0),
00183             throw_line_(-1)
00184             {
00185             }
00186 
00187 #ifdef __HP_aCC
00188         //On HP aCC, this protected copy constructor prevents throwing boost::exception.
00189         //On all other platforms, the same effect is achieved by the pure virtual destructor.
00190         exception( exception const & x ) throw():
00191             data_(x.data_),
00192             throw_function_(x.throw_function_),
00193             throw_file_(x.throw_file_),
00194             throw_line_(x.throw_line_)
00195             {
00196             }
00197 #endif
00198 
00199         virtual ~exception() throw()
00200 #ifndef __HP_aCC
00201             = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors.
00202 #endif
00203             ;
00204 
00205         private:
00206 
00207         template <class E>
00208         friend
00209         E const &
00210         operator<<( E const & x, throw_function const & y )
00211             {
00212             x.throw_function_=y.v_;
00213             return x;
00214             }
00215 
00216         template <class E>
00217         friend
00218         E const &
00219         operator<<( E const & x, throw_file const & y )
00220             {
00221             x.throw_file_=y.v_;
00222             return x;
00223             }
00224 
00225         template <class E>
00226         friend
00227         E const &
00228         operator<<( E const & x, throw_line const & y )
00229             {
00230             x.throw_line_=y.v_;
00231             return x;
00232             }
00233 
00234         friend char const * exception_detail::get_diagnostic_information( exception const & );
00235 
00236         template <class E,class Tag,class T>
00237         friend E const & operator<<( E const &, error_info<Tag,T> const & );
00238 
00239         template <class>
00240         friend struct exception_detail::get_info;
00241         friend struct exception_detail::get_info<throw_function>;
00242         friend struct exception_detail::get_info<throw_file>;
00243         friend struct exception_detail::get_info<throw_line>;
00244 
00245         mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;
00246         mutable char const * throw_function_;
00247         mutable char const * throw_file_;
00248         mutable int throw_line_;
00249         };
00250 
00251     inline
00252     exception::
00253     ~exception() throw()
00254         {
00255         }
00256 
00258 
00259     namespace
00260     exception_detail
00261         {
00262         template <class T>
00263         struct
00264         error_info_injector:
00265             public T,
00266             public exception
00267             {
00268             explicit
00269             error_info_injector( T const & x ):
00270                 T(x)
00271                 {
00272                 }
00273 
00274             ~error_info_injector() throw()
00275                 {
00276                 }
00277             };
00278 
00279         struct large_size { char c[256]; };
00280         large_size dispatch( exception * );
00281 
00282         struct small_size { };
00283         small_size dispatch( void * );
00284 
00285         template <class,int>
00286         struct enable_error_info_helper;
00287 
00288         template <class T>
00289         struct
00290         enable_error_info_helper<T,sizeof(large_size)>
00291             {
00292             typedef T type;
00293             };
00294 
00295         template <class T>
00296         struct
00297         enable_error_info_helper<T,sizeof(small_size)>
00298             {
00299             typedef error_info_injector<T> type;
00300             };
00301 
00302         template <class T>
00303         struct
00304         enable_error_info_return_type
00305             {
00306             typedef typename enable_error_info_helper<T,sizeof(dispatch((T*)0))>::type type;
00307             };
00308         }
00309 
00310     template <class T>
00311     inline
00312     typename
00313     exception_detail::enable_error_info_return_type<T>::type
00314     enable_error_info( T const & x )
00315         {
00316         typedef typename exception_detail::enable_error_info_return_type<T>::type rt;
00317         return rt(x);
00318         }
00319 
00321 
00322     namespace
00323     exception_detail
00324         {
00325         class
00326         clone_base
00327             {
00328             public:
00329 
00330             virtual clone_base const * clone() const = 0;
00331             virtual void rethrow() const = 0;
00332 
00333             virtual
00334             ~clone_base() throw()
00335                 {
00336                 }
00337             };
00338 
00339         inline
00340         void
00341         copy_boost_exception( exception * a, exception const * b )
00342             {
00343             *a = *b;
00344             }
00345 
00346         inline
00347         void
00348         copy_boost_exception( void *, void const * )
00349             {
00350             }
00351 
00352         template <class T>
00353         class
00354         clone_impl:
00355             public T,
00356             public clone_base
00357             {
00358             public:
00359 
00360             explicit
00361             clone_impl( T const & x ):
00362                 T(x)
00363                 {
00364                 copy_boost_exception(this,&x);
00365                 }
00366 
00367             ~clone_impl() throw()
00368                 {
00369                 }
00370 
00371             private:
00372 
00373             clone_base const *
00374             clone() const
00375                 {
00376                 return new clone_impl(*this);
00377                 }
00378 
00379             void
00380             rethrow() const
00381                 {
00382                 throw*this;
00383                 }
00384             };
00385         }
00386 
00387     template <class T>
00388     inline
00389     exception_detail::clone_impl<T>
00390     enable_current_exception( T const & x )
00391         {
00392         return exception_detail::clone_impl<T>(x);
00393         }
00394     }
00395 
00396 #endif


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29