File indexing completed on 2025-12-16 09:45:25
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_EXCEPTION_618474C2DE1511DEB74A388C56D89593
0008 #define BOOST_EXCEPTION_618474C2DE1511DEB74A388C56D89593
0009
0010 #include <boost/exception/detail/requires_cxx11.hpp>
0011 #include <boost/exception/exception.hpp>
0012 #include <boost/exception/info.hpp>
0013 #include <boost/exception/diagnostic_information.hpp>
0014 #ifndef BOOST_NO_EXCEPTIONS
0015 # include <boost/exception/detail/clone_current_exception.hpp>
0016 #endif
0017 #include <boost/exception/detail/type_info.hpp>
0018 #ifndef BOOST_NO_RTTI
0019 #include <boost/core/demangle.hpp>
0020 #endif
0021 #include <boost/shared_ptr.hpp>
0022 #include <boost/make_shared.hpp>
0023 #include <stdexcept>
0024 #include <new>
0025 #include <ios>
0026 #include <stdlib.h>
0027
0028 #ifndef BOOST_EXCEPTION_ENABLE_WARNINGS
0029 #if defined(__GNUC__) && __GNUC__*100+__GNUC_MINOR__>301
0030 #pragma GCC system_header
0031 #endif
0032 #ifdef __clang__
0033 #pragma clang system_header
0034 #endif
0035 #ifdef _MSC_VER
0036 #pragma warning(push,1)
0037 #endif
0038 #endif
0039
0040 namespace
0041 boost
0042 {
0043 namespace
0044 exception_detail
0045 {
0046 #ifndef BOOST_NO_CXX11_HDR_EXCEPTION
0047 struct
0048 std_exception_ptr_wrapper:
0049 std::exception
0050 {
0051 std::exception_ptr p;
0052 explicit std_exception_ptr_wrapper( std::exception_ptr const & ptr ) BOOST_NOEXCEPT:
0053 p(ptr)
0054 {
0055 }
0056 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0057 explicit std_exception_ptr_wrapper( std::exception_ptr && ptr ) BOOST_NOEXCEPT:
0058 p(static_cast<std::exception_ptr &&>(ptr))
0059 {
0060 }
0061 #endif
0062 };
0063 shared_ptr<exception_detail::clone_base const>
0064 inline
0065 wrap_exception_ptr( std::exception_ptr const & e )
0066 {
0067 exception_detail::clone_base const & base = boost::enable_current_exception(std_exception_ptr_wrapper(e));
0068 return shared_ptr<exception_detail::clone_base const>(base.clone());
0069 }
0070 #endif
0071 }
0072
0073 class exception_ptr;
0074 namespace exception_detail { void rethrow_exception_( exception_ptr const & ); }
0075
0076 class
0077 exception_ptr
0078 {
0079 typedef boost::shared_ptr<exception_detail::clone_base const> impl;
0080 impl ptr_;
0081 friend void exception_detail::rethrow_exception_( exception_ptr const & );
0082 typedef exception_detail::clone_base const * (impl::*unspecified_bool_type)() const;
0083 public:
0084 exception_ptr()
0085 {
0086 }
0087 #ifndef BOOST_NO_CXX11_HDR_EXCEPTION
0088 exception_ptr( std::exception_ptr const & e ):
0089 ptr_(exception_detail::wrap_exception_ptr(e))
0090 {
0091 }
0092 #endif
0093 explicit
0094 exception_ptr( impl const & ptr ):
0095 ptr_(ptr)
0096 {
0097 }
0098 bool
0099 operator==( exception_ptr const & other ) const
0100 {
0101 return ptr_==other.ptr_;
0102 }
0103 bool
0104 operator!=( exception_ptr const & other ) const
0105 {
0106 return ptr_!=other.ptr_;
0107 }
0108 operator unspecified_bool_type() const
0109 {
0110 return ptr_?&impl::get:0;
0111 }
0112 };
0113
0114 namespace
0115 exception_detail
0116 {
0117 template <class E>
0118 inline
0119 exception_ptr
0120 copy_exception_impl( E const & e )
0121 {
0122 return exception_ptr(boost::make_shared<E>(e));
0123 }
0124 }
0125
0126 template <class E>
0127 inline
0128 exception_ptr
0129 copy_exception( E const & e )
0130 {
0131 return exception_detail::copy_exception_impl(boost::enable_current_exception(e));
0132 }
0133
0134 template <class T>
0135 inline
0136 exception_ptr
0137 make_exception_ptr( T const & e )
0138 {
0139 return boost::copy_exception(e);
0140 }
0141
0142 #ifndef BOOST_NO_RTTI
0143 typedef error_info<struct tag_original_exception_type,std::type_info const *> original_exception_type;
0144
0145 inline
0146 std::string
0147 to_string( original_exception_type const & x )
0148 {
0149 return core::demangle(x.value()->name());
0150 }
0151 #endif
0152
0153 #ifndef BOOST_NO_EXCEPTIONS
0154 namespace
0155 exception_detail
0156 {
0157 struct
0158 bad_alloc_:
0159 boost::exception,
0160 std::bad_alloc
0161 {
0162 ~bad_alloc_() BOOST_NOEXCEPT_OR_NOTHROW { }
0163 };
0164
0165 struct
0166 bad_exception_:
0167 boost::exception,
0168 std::bad_exception
0169 {
0170 ~bad_exception_() BOOST_NOEXCEPT_OR_NOTHROW { }
0171 };
0172
0173 template <class Exception>
0174 exception_ptr
0175 get_static_exception_object()
0176 {
0177 Exception ba;
0178 exception_detail::clone_impl<Exception> c(ba);
0179 #ifndef BOOST_EXCEPTION_DISABLE
0180 c <<
0181 throw_function(BOOST_CURRENT_FUNCTION) <<
0182 throw_file(__FILE__) <<
0183 throw_line(__LINE__);
0184 #endif
0185 static exception_ptr ep(shared_ptr<exception_detail::clone_base const>(new exception_detail::clone_impl<Exception>(c)));
0186 return ep;
0187 }
0188
0189 template <class Exception>
0190 struct
0191 exception_ptr_static_exception_object
0192 {
0193 static exception_ptr const e;
0194 };
0195
0196 template <class Exception>
0197 exception_ptr const
0198 exception_ptr_static_exception_object<Exception>::
0199 e = get_static_exception_object<Exception>();
0200 }
0201
0202 #if defined(__GNUC__)
0203 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
0204 # pragma GCC visibility push (default)
0205 # endif
0206 #endif
0207 class
0208 unknown_exception:
0209 public boost::exception,
0210 public std::exception
0211 {
0212 public:
0213
0214 unknown_exception()
0215 {
0216 }
0217
0218 explicit
0219 unknown_exception( std::exception const & e )
0220 {
0221 add_original_type(e);
0222 }
0223
0224 explicit
0225 unknown_exception( boost::exception const & e ):
0226 boost::exception(e)
0227 {
0228 add_original_type(e);
0229 }
0230
0231 ~unknown_exception() BOOST_NOEXCEPT_OR_NOTHROW
0232 {
0233 }
0234
0235 private:
0236
0237 template <class E>
0238 void
0239 add_original_type( E const & e )
0240 {
0241 #ifndef BOOST_NO_RTTI
0242 (*this) << original_exception_type(&typeid(e));
0243 #endif
0244 }
0245 };
0246 #if defined(__GNUC__)
0247 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
0248 # pragma GCC visibility pop
0249 # endif
0250 #endif
0251
0252 namespace
0253 exception_detail
0254 {
0255 template <class T>
0256 class
0257 current_exception_std_exception_wrapper:
0258 public T,
0259 public boost::exception
0260 {
0261 public:
0262
0263 explicit
0264 current_exception_std_exception_wrapper( T const & e1 ):
0265 T(e1)
0266 {
0267 add_original_type(e1);
0268 }
0269
0270 current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ):
0271 T(e1),
0272 boost::exception(e2)
0273 {
0274 add_original_type(e1);
0275 }
0276
0277 ~current_exception_std_exception_wrapper() BOOST_NOEXCEPT_OR_NOTHROW
0278 {
0279 }
0280
0281 private:
0282
0283 template <class E>
0284 void
0285 add_original_type( E const & e )
0286 {
0287 #ifndef BOOST_NO_RTTI
0288 (*this) << original_exception_type(&typeid(e));
0289 #endif
0290 }
0291 };
0292
0293 #ifdef BOOST_NO_RTTI
0294 template <class T>
0295 boost::exception const *
0296 get_boost_exception( T const * )
0297 {
0298 try
0299 {
0300 throw;
0301 }
0302 catch(
0303 boost::exception & x )
0304 {
0305 return &x;
0306 }
0307 catch(...)
0308 {
0309 return 0;
0310 }
0311 }
0312 #else
0313 template <class T>
0314 boost::exception const *
0315 get_boost_exception( T const * x )
0316 {
0317 return dynamic_cast<boost::exception const *>(x);
0318 }
0319 #endif
0320
0321 template <class T>
0322 inline
0323 exception_ptr
0324 current_exception_std_exception( T const & e1 )
0325 {
0326 if( boost::exception const * e2 = get_boost_exception(&e1) )
0327 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1,*e2));
0328 else
0329 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1));
0330 }
0331
0332 inline
0333 exception_ptr
0334 current_exception_unknown_exception()
0335 {
0336 return boost::copy_exception(unknown_exception());
0337 }
0338
0339 inline
0340 exception_ptr
0341 current_exception_unknown_boost_exception( boost::exception const & e )
0342 {
0343 return boost::copy_exception(unknown_exception(e));
0344 }
0345
0346 inline
0347 exception_ptr
0348 current_exception_unknown_std_exception( std::exception const & e )
0349 {
0350 if( boost::exception const * be = get_boost_exception(&e) )
0351 return current_exception_unknown_boost_exception(*be);
0352 else
0353 return boost::copy_exception(unknown_exception(e));
0354 }
0355
0356 inline
0357 exception_ptr
0358 current_exception_impl()
0359 {
0360 exception_detail::clone_base const * e=0;
0361 switch(
0362 exception_detail::clone_current_exception(e) )
0363 {
0364 case exception_detail::clone_current_exception_result::
0365 success:
0366 {
0367 BOOST_ASSERT(e!=0);
0368 return exception_ptr(shared_ptr<exception_detail::clone_base const>(e));
0369 }
0370 case exception_detail::clone_current_exception_result::
0371 bad_alloc:
0372 {
0373 BOOST_ASSERT(!e);
0374 return exception_detail::exception_ptr_static_exception_object<bad_alloc_>::e;
0375 }
0376 case exception_detail::clone_current_exception_result::
0377 bad_exception:
0378 {
0379 BOOST_ASSERT(!e);
0380 return exception_detail::exception_ptr_static_exception_object<bad_exception_>::e;
0381 }
0382 default:
0383 BOOST_ASSERT(0);
0384 case exception_detail::clone_current_exception_result::
0385 not_supported:
0386 {
0387 BOOST_ASSERT(!e);
0388 try
0389 {
0390 throw;
0391 }
0392 catch(
0393 exception_detail::clone_base & e )
0394 {
0395 return exception_ptr(shared_ptr<exception_detail::clone_base const>(e.clone()));
0396 }
0397
0398 #ifdef BOOST_NO_CXX11_HDR_EXCEPTION
0399
0400 catch(
0401 std::domain_error & e )
0402 {
0403 return exception_detail::current_exception_std_exception(e);
0404 }
0405 catch(
0406 std::invalid_argument & e )
0407 {
0408 return exception_detail::current_exception_std_exception(e);
0409 }
0410 catch(
0411 std::length_error & e )
0412 {
0413 return exception_detail::current_exception_std_exception(e);
0414 }
0415 catch(
0416 std::out_of_range & e )
0417 {
0418 return exception_detail::current_exception_std_exception(e);
0419 }
0420 catch(
0421 std::logic_error & e )
0422 {
0423 return exception_detail::current_exception_std_exception(e);
0424 }
0425 catch(
0426 std::range_error & e )
0427 {
0428 return exception_detail::current_exception_std_exception(e);
0429 }
0430 catch(
0431 std::overflow_error & e )
0432 {
0433 return exception_detail::current_exception_std_exception(e);
0434 }
0435 catch(
0436 std::underflow_error & e )
0437 {
0438 return exception_detail::current_exception_std_exception(e);
0439 }
0440 catch(
0441 std::ios_base::failure & e )
0442 {
0443 return exception_detail::current_exception_std_exception(e);
0444 }
0445 catch(
0446 std::runtime_error & e )
0447 {
0448 return exception_detail::current_exception_std_exception(e);
0449 }
0450 catch(
0451 std::bad_alloc & e )
0452 {
0453 return exception_detail::current_exception_std_exception(e);
0454 }
0455 #ifndef BOOST_NO_TYPEID
0456 catch(
0457 std::bad_cast & e )
0458 {
0459 return exception_detail::current_exception_std_exception(e);
0460 }
0461 catch(
0462 std::bad_typeid & e )
0463 {
0464 return exception_detail::current_exception_std_exception(e);
0465 }
0466 #endif
0467 catch(
0468 std::bad_exception & e )
0469 {
0470 return exception_detail::current_exception_std_exception(e);
0471 }
0472 catch(
0473 std::exception & e )
0474 {
0475 return exception_detail::current_exception_unknown_std_exception(e);
0476 }
0477 catch(
0478 boost::exception & e )
0479 {
0480 return exception_detail::current_exception_unknown_boost_exception(e);
0481 }
0482
0483 #endif
0484
0485 catch(
0486 ... )
0487 {
0488 #ifndef BOOST_NO_CXX11_HDR_EXCEPTION
0489 try
0490 {
0491 return exception_ptr(std::current_exception());
0492 }
0493 catch(
0494 ...)
0495 {
0496 return exception_detail::current_exception_unknown_exception();
0497 }
0498 #else
0499 return exception_detail::current_exception_unknown_exception();
0500 #endif
0501 }
0502 }
0503 }
0504 }
0505 }
0506
0507 inline
0508 exception_ptr
0509 current_exception()
0510 {
0511 exception_ptr ret;
0512 try
0513 {
0514 ret=exception_detail::current_exception_impl();
0515 }
0516 catch(
0517 std::bad_alloc & )
0518 {
0519 ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_alloc_>::e;
0520 }
0521 catch(
0522 ... )
0523 {
0524 ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_exception_>::e;
0525 }
0526 BOOST_ASSERT(ret);
0527 return ret;
0528 }
0529 #endif
0530
0531 namespace
0532 exception_detail
0533 {
0534 inline
0535 void
0536 rethrow_exception_( exception_ptr const & p )
0537 {
0538 BOOST_ASSERT(p);
0539 #if defined( BOOST_NO_CXX11_HDR_EXCEPTION ) || defined( BOOST_NO_EXCEPTIONS )
0540 p.ptr_->rethrow();
0541 #else
0542 try
0543 {
0544 p.ptr_->rethrow();
0545 }
0546 catch(
0547 std_exception_ptr_wrapper const & wrp)
0548 {
0549
0550 std::rethrow_exception(wrp.p);
0551 }
0552 #endif
0553 }
0554 }
0555
0556 BOOST_NORETURN
0557 inline
0558 void
0559 rethrow_exception( exception_ptr const & p )
0560 {
0561 exception_detail::rethrow_exception_(p);
0562 BOOST_ASSERT(0);
0563 #if defined(UNDER_CE)
0564
0565 exit(-1);
0566 #else
0567 abort();
0568 #endif
0569 }
0570
0571 inline
0572 std::string
0573 diagnostic_information( exception_ptr const & p, bool verbose=true )
0574 {
0575 if( p )
0576 #ifdef BOOST_NO_EXCEPTIONS
0577 return "<unavailable> due to BOOST_NO_EXCEPTIONS";
0578 #else
0579 try
0580 {
0581 rethrow_exception(p);
0582 }
0583 catch(
0584 ... )
0585 {
0586 return current_exception_diagnostic_information(verbose);
0587 }
0588 #endif
0589 return "<empty>";
0590 }
0591
0592 inline
0593 std::string
0594 to_string( exception_ptr const & p )
0595 {
0596 std::string s='\n'+diagnostic_information(p);
0597 std::string padding(" ");
0598 std::string r;
0599 bool f=false;
0600 for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i )
0601 {
0602 if( f )
0603 r+=padding;
0604 char c=*i;
0605 r+=c;
0606 f=(c=='\n');
0607 }
0608 return r;
0609 }
0610 }
0611
0612 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
0613 #pragma warning(pop)
0614 #endif
0615 #endif