annotate DEPENDENCIES/generic/include/boost/exception/detail/exception_ptr.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
Chris@16 2
Chris@16 3 //Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 #ifndef UUID_618474C2DE1511DEB74A388C56D89593
Chris@16 7 #define UUID_618474C2DE1511DEB74A388C56D89593
Chris@16 8 #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
Chris@16 9 #pragma GCC system_header
Chris@16 10 #endif
Chris@16 11 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
Chris@16 12 #pragma warning(push,1)
Chris@16 13 #endif
Chris@16 14
Chris@16 15 #include <boost/config.hpp>
Chris@16 16 #ifdef BOOST_NO_EXCEPTIONS
Chris@16 17 #error This header requires exception handling to be enabled.
Chris@16 18 #endif
Chris@16 19 #include <boost/exception/exception.hpp>
Chris@16 20 #include <boost/exception/info.hpp>
Chris@16 21 #include <boost/exception/diagnostic_information.hpp>
Chris@16 22 #include <boost/exception/detail/type_info.hpp>
Chris@16 23 #include <boost/exception/detail/clone_current_exception.hpp>
Chris@101 24 #ifndef BOOST_NO_RTTI
Chris@101 25 #include <boost/core/demangle.hpp>
Chris@101 26 #endif
Chris@16 27 #include <boost/shared_ptr.hpp>
Chris@16 28 #include <stdexcept>
Chris@16 29 #include <new>
Chris@16 30 #include <ios>
Chris@16 31 #include <stdlib.h>
Chris@16 32
Chris@16 33 namespace
Chris@16 34 boost
Chris@16 35 {
Chris@16 36 class exception_ptr;
Chris@101 37 BOOST_NORETURN void rethrow_exception( exception_ptr const & );
Chris@16 38 exception_ptr current_exception();
Chris@16 39
Chris@16 40 class
Chris@16 41 exception_ptr
Chris@16 42 {
Chris@16 43 typedef boost::shared_ptr<exception_detail::clone_base const> impl;
Chris@16 44 impl ptr_;
Chris@16 45 friend void rethrow_exception( exception_ptr const & );
Chris@16 46 typedef exception_detail::clone_base const * (impl::*unspecified_bool_type)() const;
Chris@16 47 public:
Chris@16 48 exception_ptr()
Chris@16 49 {
Chris@16 50 }
Chris@16 51 explicit
Chris@16 52 exception_ptr( impl const & ptr ):
Chris@16 53 ptr_(ptr)
Chris@16 54 {
Chris@16 55 }
Chris@16 56 bool
Chris@16 57 operator==( exception_ptr const & other ) const
Chris@16 58 {
Chris@16 59 return ptr_==other.ptr_;
Chris@16 60 }
Chris@16 61 bool
Chris@16 62 operator!=( exception_ptr const & other ) const
Chris@16 63 {
Chris@16 64 return ptr_!=other.ptr_;
Chris@16 65 }
Chris@16 66 operator unspecified_bool_type() const
Chris@16 67 {
Chris@16 68 return ptr_?&impl::get:0;
Chris@16 69 }
Chris@16 70 };
Chris@16 71
Chris@16 72 template <class T>
Chris@16 73 inline
Chris@16 74 exception_ptr
Chris@16 75 copy_exception( T const & e )
Chris@16 76 {
Chris@16 77 try
Chris@16 78 {
Chris@16 79 throw enable_current_exception(e);
Chris@16 80 }
Chris@16 81 catch(
Chris@16 82 ... )
Chris@16 83 {
Chris@16 84 return current_exception();
Chris@16 85 }
Chris@16 86 }
Chris@16 87
Chris@16 88 #ifndef BOOST_NO_RTTI
Chris@16 89 typedef error_info<struct tag_original_exception_type,std::type_info const *> original_exception_type;
Chris@16 90
Chris@16 91 inline
Chris@16 92 std::string
Chris@16 93 to_string( original_exception_type const & x )
Chris@16 94 {
Chris@101 95 return core::demangle(x.value()->name());
Chris@16 96 }
Chris@16 97 #endif
Chris@16 98
Chris@16 99 namespace
Chris@16 100 exception_detail
Chris@16 101 {
Chris@16 102 struct
Chris@16 103 bad_alloc_:
Chris@16 104 boost::exception,
Chris@16 105 std::bad_alloc
Chris@16 106 {
Chris@16 107 ~bad_alloc_() throw() { }
Chris@16 108 };
Chris@16 109
Chris@16 110 struct
Chris@16 111 bad_exception_:
Chris@16 112 boost::exception,
Chris@16 113 std::bad_exception
Chris@16 114 {
Chris@16 115 ~bad_exception_() throw() { }
Chris@16 116 };
Chris@16 117
Chris@16 118 template <class Exception>
Chris@16 119 exception_ptr
Chris@16 120 get_static_exception_object()
Chris@16 121 {
Chris@16 122 Exception ba;
Chris@16 123 exception_detail::clone_impl<Exception> c(ba);
Chris@16 124 #ifndef BOOST_EXCEPTION_DISABLE
Chris@16 125 c <<
Chris@16 126 throw_function(BOOST_CURRENT_FUNCTION) <<
Chris@16 127 throw_file(__FILE__) <<
Chris@16 128 throw_line(__LINE__);
Chris@16 129 #endif
Chris@16 130 static exception_ptr ep(shared_ptr<exception_detail::clone_base const>(new exception_detail::clone_impl<Exception>(c)));
Chris@16 131 return ep;
Chris@16 132 }
Chris@16 133
Chris@16 134 template <class Exception>
Chris@16 135 struct
Chris@16 136 exception_ptr_static_exception_object
Chris@16 137 {
Chris@16 138 static exception_ptr const e;
Chris@16 139 };
Chris@16 140
Chris@16 141 template <class Exception>
Chris@16 142 exception_ptr const
Chris@16 143 exception_ptr_static_exception_object<Exception>::
Chris@16 144 e = get_static_exception_object<Exception>();
Chris@16 145 }
Chris@16 146
Chris@16 147 #if defined(__GNUC__)
Chris@16 148 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
Chris@16 149 # pragma GCC visibility push (default)
Chris@16 150 # endif
Chris@16 151 #endif
Chris@16 152 class
Chris@16 153 unknown_exception:
Chris@16 154 public boost::exception,
Chris@16 155 public std::exception
Chris@16 156 {
Chris@16 157 public:
Chris@16 158
Chris@16 159 unknown_exception()
Chris@16 160 {
Chris@16 161 }
Chris@16 162
Chris@16 163 explicit
Chris@16 164 unknown_exception( std::exception const & e )
Chris@16 165 {
Chris@16 166 add_original_type(e);
Chris@16 167 }
Chris@16 168
Chris@16 169 explicit
Chris@16 170 unknown_exception( boost::exception const & e ):
Chris@16 171 boost::exception(e)
Chris@16 172 {
Chris@16 173 add_original_type(e);
Chris@16 174 }
Chris@16 175
Chris@16 176 ~unknown_exception() throw()
Chris@16 177 {
Chris@16 178 }
Chris@16 179
Chris@16 180 private:
Chris@16 181
Chris@16 182 template <class E>
Chris@16 183 void
Chris@16 184 add_original_type( E const & e )
Chris@16 185 {
Chris@16 186 #ifndef BOOST_NO_RTTI
Chris@16 187 (*this) << original_exception_type(&typeid(e));
Chris@16 188 #endif
Chris@16 189 }
Chris@16 190 };
Chris@16 191 #if defined(__GNUC__)
Chris@16 192 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
Chris@16 193 # pragma GCC visibility pop
Chris@16 194 # endif
Chris@16 195 #endif
Chris@16 196
Chris@16 197 namespace
Chris@16 198 exception_detail
Chris@16 199 {
Chris@16 200 template <class T>
Chris@16 201 class
Chris@16 202 current_exception_std_exception_wrapper:
Chris@16 203 public T,
Chris@16 204 public boost::exception
Chris@16 205 {
Chris@16 206 public:
Chris@16 207
Chris@16 208 explicit
Chris@16 209 current_exception_std_exception_wrapper( T const & e1 ):
Chris@16 210 T(e1)
Chris@16 211 {
Chris@16 212 add_original_type(e1);
Chris@16 213 }
Chris@16 214
Chris@16 215 current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ):
Chris@16 216 T(e1),
Chris@16 217 boost::exception(e2)
Chris@16 218 {
Chris@16 219 add_original_type(e1);
Chris@16 220 }
Chris@16 221
Chris@16 222 ~current_exception_std_exception_wrapper() throw()
Chris@16 223 {
Chris@16 224 }
Chris@16 225
Chris@16 226 private:
Chris@16 227
Chris@16 228 template <class E>
Chris@16 229 void
Chris@16 230 add_original_type( E const & e )
Chris@16 231 {
Chris@16 232 #ifndef BOOST_NO_RTTI
Chris@16 233 (*this) << original_exception_type(&typeid(e));
Chris@16 234 #endif
Chris@16 235 }
Chris@16 236 };
Chris@16 237
Chris@16 238 #ifdef BOOST_NO_RTTI
Chris@16 239 template <class T>
Chris@16 240 boost::exception const *
Chris@16 241 get_boost_exception( T const * )
Chris@16 242 {
Chris@16 243 try
Chris@16 244 {
Chris@16 245 throw;
Chris@16 246 }
Chris@16 247 catch(
Chris@16 248 boost::exception & x )
Chris@16 249 {
Chris@16 250 return &x;
Chris@16 251 }
Chris@16 252 catch(...)
Chris@16 253 {
Chris@16 254 return 0;
Chris@16 255 }
Chris@16 256 }
Chris@16 257 #else
Chris@16 258 template <class T>
Chris@16 259 boost::exception const *
Chris@16 260 get_boost_exception( T const * x )
Chris@16 261 {
Chris@16 262 return dynamic_cast<boost::exception const *>(x);
Chris@16 263 }
Chris@16 264 #endif
Chris@16 265
Chris@16 266 template <class T>
Chris@16 267 inline
Chris@16 268 exception_ptr
Chris@16 269 current_exception_std_exception( T const & e1 )
Chris@16 270 {
Chris@16 271 if( boost::exception const * e2 = get_boost_exception(&e1) )
Chris@16 272 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1,*e2));
Chris@16 273 else
Chris@16 274 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1));
Chris@16 275 }
Chris@16 276
Chris@16 277 inline
Chris@16 278 exception_ptr
Chris@16 279 current_exception_unknown_exception()
Chris@16 280 {
Chris@16 281 return boost::copy_exception(unknown_exception());
Chris@16 282 }
Chris@16 283
Chris@16 284 inline
Chris@16 285 exception_ptr
Chris@16 286 current_exception_unknown_boost_exception( boost::exception const & e )
Chris@16 287 {
Chris@16 288 return boost::copy_exception(unknown_exception(e));
Chris@16 289 }
Chris@16 290
Chris@16 291 inline
Chris@16 292 exception_ptr
Chris@16 293 current_exception_unknown_std_exception( std::exception const & e )
Chris@16 294 {
Chris@16 295 if( boost::exception const * be = get_boost_exception(&e) )
Chris@16 296 return current_exception_unknown_boost_exception(*be);
Chris@16 297 else
Chris@16 298 return boost::copy_exception(unknown_exception(e));
Chris@16 299 }
Chris@16 300
Chris@16 301 inline
Chris@16 302 exception_ptr
Chris@16 303 current_exception_impl()
Chris@16 304 {
Chris@16 305 exception_detail::clone_base const * e=0;
Chris@16 306 switch(
Chris@16 307 exception_detail::clone_current_exception(e) )
Chris@16 308 {
Chris@16 309 case exception_detail::clone_current_exception_result::
Chris@16 310 success:
Chris@16 311 {
Chris@16 312 BOOST_ASSERT(e!=0);
Chris@16 313 return exception_ptr(shared_ptr<exception_detail::clone_base const>(e));
Chris@16 314 }
Chris@16 315 case exception_detail::clone_current_exception_result::
Chris@16 316 bad_alloc:
Chris@16 317 {
Chris@16 318 BOOST_ASSERT(!e);
Chris@16 319 return exception_detail::exception_ptr_static_exception_object<bad_alloc_>::e;
Chris@16 320 }
Chris@16 321 case exception_detail::clone_current_exception_result::
Chris@16 322 bad_exception:
Chris@16 323 {
Chris@16 324 BOOST_ASSERT(!e);
Chris@16 325 return exception_detail::exception_ptr_static_exception_object<bad_exception_>::e;
Chris@16 326 }
Chris@16 327 default:
Chris@16 328 BOOST_ASSERT(0);
Chris@16 329 case exception_detail::clone_current_exception_result::
Chris@16 330 not_supported:
Chris@16 331 {
Chris@16 332 BOOST_ASSERT(!e);
Chris@16 333 try
Chris@16 334 {
Chris@16 335 throw;
Chris@16 336 }
Chris@16 337 catch(
Chris@16 338 exception_detail::clone_base & e )
Chris@16 339 {
Chris@16 340 return exception_ptr(shared_ptr<exception_detail::clone_base const>(e.clone()));
Chris@16 341 }
Chris@16 342 catch(
Chris@16 343 std::domain_error & e )
Chris@16 344 {
Chris@16 345 return exception_detail::current_exception_std_exception(e);
Chris@16 346 }
Chris@16 347 catch(
Chris@16 348 std::invalid_argument & e )
Chris@16 349 {
Chris@16 350 return exception_detail::current_exception_std_exception(e);
Chris@16 351 }
Chris@16 352 catch(
Chris@16 353 std::length_error & e )
Chris@16 354 {
Chris@16 355 return exception_detail::current_exception_std_exception(e);
Chris@16 356 }
Chris@16 357 catch(
Chris@16 358 std::out_of_range & e )
Chris@16 359 {
Chris@16 360 return exception_detail::current_exception_std_exception(e);
Chris@16 361 }
Chris@16 362 catch(
Chris@16 363 std::logic_error & e )
Chris@16 364 {
Chris@16 365 return exception_detail::current_exception_std_exception(e);
Chris@16 366 }
Chris@16 367 catch(
Chris@16 368 std::range_error & e )
Chris@16 369 {
Chris@16 370 return exception_detail::current_exception_std_exception(e);
Chris@16 371 }
Chris@16 372 catch(
Chris@16 373 std::overflow_error & e )
Chris@16 374 {
Chris@16 375 return exception_detail::current_exception_std_exception(e);
Chris@16 376 }
Chris@16 377 catch(
Chris@16 378 std::underflow_error & e )
Chris@16 379 {
Chris@16 380 return exception_detail::current_exception_std_exception(e);
Chris@16 381 }
Chris@16 382 catch(
Chris@16 383 std::ios_base::failure & e )
Chris@16 384 {
Chris@16 385 return exception_detail::current_exception_std_exception(e);
Chris@16 386 }
Chris@16 387 catch(
Chris@16 388 std::runtime_error & e )
Chris@16 389 {
Chris@16 390 return exception_detail::current_exception_std_exception(e);
Chris@16 391 }
Chris@16 392 catch(
Chris@16 393 std::bad_alloc & e )
Chris@16 394 {
Chris@16 395 return exception_detail::current_exception_std_exception(e);
Chris@16 396 }
Chris@16 397 #ifndef BOOST_NO_TYPEID
Chris@16 398 catch(
Chris@16 399 std::bad_cast & e )
Chris@16 400 {
Chris@16 401 return exception_detail::current_exception_std_exception(e);
Chris@16 402 }
Chris@16 403 catch(
Chris@16 404 std::bad_typeid & e )
Chris@16 405 {
Chris@16 406 return exception_detail::current_exception_std_exception(e);
Chris@16 407 }
Chris@16 408 #endif
Chris@16 409 catch(
Chris@16 410 std::bad_exception & e )
Chris@16 411 {
Chris@16 412 return exception_detail::current_exception_std_exception(e);
Chris@16 413 }
Chris@16 414 catch(
Chris@16 415 std::exception & e )
Chris@16 416 {
Chris@16 417 return exception_detail::current_exception_unknown_std_exception(e);
Chris@16 418 }
Chris@16 419 catch(
Chris@16 420 boost::exception & e )
Chris@16 421 {
Chris@16 422 return exception_detail::current_exception_unknown_boost_exception(e);
Chris@16 423 }
Chris@16 424 catch(
Chris@16 425 ... )
Chris@16 426 {
Chris@16 427 return exception_detail::current_exception_unknown_exception();
Chris@16 428 }
Chris@16 429 }
Chris@16 430 }
Chris@16 431 }
Chris@16 432 }
Chris@16 433
Chris@16 434 inline
Chris@16 435 exception_ptr
Chris@16 436 current_exception()
Chris@16 437 {
Chris@16 438 exception_ptr ret;
Chris@16 439 try
Chris@16 440 {
Chris@16 441 ret=exception_detail::current_exception_impl();
Chris@16 442 }
Chris@16 443 catch(
Chris@16 444 std::bad_alloc & )
Chris@16 445 {
Chris@16 446 ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_alloc_>::e;
Chris@16 447 }
Chris@16 448 catch(
Chris@16 449 ... )
Chris@16 450 {
Chris@16 451 ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_exception_>::e;
Chris@16 452 }
Chris@16 453 BOOST_ASSERT(ret);
Chris@16 454 return ret;
Chris@16 455 }
Chris@16 456
Chris@101 457 BOOST_NORETURN
Chris@16 458 inline
Chris@16 459 void
Chris@16 460 rethrow_exception( exception_ptr const & p )
Chris@16 461 {
Chris@16 462 BOOST_ASSERT(p);
Chris@16 463 p.ptr_->rethrow();
Chris@16 464 BOOST_ASSERT(0);
Chris@16 465 #if defined(UNDER_CE)
Chris@16 466 // some CE platforms don't define ::abort()
Chris@16 467 exit(-1);
Chris@16 468 #else
Chris@16 469 abort();
Chris@16 470 #endif
Chris@16 471 }
Chris@16 472
Chris@16 473 inline
Chris@16 474 std::string
Chris@16 475 diagnostic_information( exception_ptr const & p, bool verbose=true )
Chris@16 476 {
Chris@16 477 if( p )
Chris@16 478 try
Chris@16 479 {
Chris@16 480 rethrow_exception(p);
Chris@16 481 }
Chris@16 482 catch(
Chris@16 483 ... )
Chris@16 484 {
Chris@16 485 return current_exception_diagnostic_information(verbose);
Chris@16 486 }
Chris@16 487 return "<empty>";
Chris@16 488 }
Chris@16 489
Chris@16 490 inline
Chris@16 491 std::string
Chris@16 492 to_string( exception_ptr const & p )
Chris@16 493 {
Chris@16 494 std::string s='\n'+diagnostic_information(p);
Chris@16 495 std::string padding(" ");
Chris@16 496 std::string r;
Chris@16 497 bool f=false;
Chris@16 498 for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i )
Chris@16 499 {
Chris@16 500 if( f )
Chris@16 501 r+=padding;
Chris@16 502 char c=*i;
Chris@16 503 r+=c;
Chris@16 504 f=(c=='\n');
Chris@16 505 }
Chris@16 506 return r;
Chris@16 507 }
Chris@16 508 }
Chris@16 509
Chris@16 510 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
Chris@16 511 #pragma warning(pop)
Chris@16 512 #endif
Chris@16 513 #endif