Go to the documentation of this file.00001
00002
00003
00004
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
00189
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
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