1 //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
3 //Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef UUID_618474C2DE1511DEB74A388C56D89593
7 #define UUID_618474C2DE1511DEB74A388C56D89593
8 #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
9 #pragma GCC system_header
11 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
12 #pragma warning(push,1)
15 #include <boost/config.hpp>
16 #ifdef BOOST_NO_EXCEPTIONS
17 #error This header requires exception handling to be enabled.
19 #include <boost/exception/exception.hpp>
20 #include <boost/exception/info.hpp>
21 #include <boost/exception/diagnostic_information.hpp>
22 #include <boost/exception/detail/type_info.hpp>
23 #include <boost/exception/detail/clone_current_exception.hpp>
25 #include <boost/core/demangle.hpp>
27 #include <boost/shared_ptr.hpp>
37 BOOST_NORETURN void rethrow_exception( exception_ptr const & );
38 exception_ptr current_exception();
43 typedef boost::shared_ptr<exception_detail::clone_base const> impl;
45 friend void rethrow_exception( exception_ptr const & );
46 typedef exception_detail::clone_base const * (impl::*unspecified_bool_type)() const;
52 exception_ptr( impl const & ptr ):
57 operator==( exception_ptr const & other ) const
59 return ptr_==other.ptr_;
62 operator!=( exception_ptr const & other ) const
64 return ptr_!=other.ptr_;
66 operator unspecified_bool_type() const
68 return ptr_?&impl::get:0;
75 copy_exception( T const & e )
79 throw enable_current_exception(e);
84 return current_exception();
89 typedef error_info<struct tag_original_exception_type,std::type_info const *> original_exception_type;
93 to_string( original_exception_type const & x )
95 return core::demangle(x.value()->name());
107 ~bad_alloc_() throw() { }
115 ~bad_exception_() throw() { }
118 template <class Exception>
120 get_static_exception_object()
123 exception_detail::clone_impl<Exception> c(ba);
124 #ifndef BOOST_EXCEPTION_DISABLE
126 throw_function(BOOST_CURRENT_FUNCTION) <<
127 throw_file(__FILE__) <<
128 throw_line(__LINE__);
130 static exception_ptr ep(shared_ptr<exception_detail::clone_base const>(new exception_detail::clone_impl<Exception>(c)));
134 template <class Exception>
136 exception_ptr_static_exception_object
138 static exception_ptr const e;
141 template <class Exception>
143 exception_ptr_static_exception_object<Exception>::
144 e = get_static_exception_object<Exception>();
147 #if defined(__GNUC__)
148 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
149 # pragma GCC visibility push (default)
154 public boost::exception,
155 public std::exception
164 unknown_exception( std::exception const & e )
166 add_original_type(e);
170 unknown_exception( boost::exception const & e ):
173 add_original_type(e);
176 ~unknown_exception() throw()
184 add_original_type( E const & e )
186 #ifndef BOOST_NO_RTTI
187 (*this) << original_exception_type(&typeid(e));
191 #if defined(__GNUC__)
192 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
193 # pragma GCC visibility pop
202 current_exception_std_exception_wrapper:
204 public boost::exception
209 current_exception_std_exception_wrapper( T const & e1 ):
212 add_original_type(e1);
215 current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ):
219 add_original_type(e1);
222 ~current_exception_std_exception_wrapper() throw()
230 add_original_type( E const & e )
232 #ifndef BOOST_NO_RTTI
233 (*this) << original_exception_type(&typeid(e));
240 boost::exception const *
241 get_boost_exception( T const * )
248 boost::exception & x )
259 boost::exception const *
260 get_boost_exception( T const * x )
262 return dynamic_cast<boost::exception const *>(x);
269 current_exception_std_exception( T const & e1 )
271 if( boost::exception const * e2 = get_boost_exception(&e1) )
272 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1,*e2));
274 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1));
279 current_exception_unknown_exception()
281 return boost::copy_exception(unknown_exception());
286 current_exception_unknown_boost_exception( boost::exception const & e )
288 return boost::copy_exception(unknown_exception(e));
293 current_exception_unknown_std_exception( std::exception const & e )
295 if( boost::exception const * be = get_boost_exception(&e) )
296 return current_exception_unknown_boost_exception(*be);
298 return boost::copy_exception(unknown_exception(e));
303 current_exception_impl()
305 exception_detail::clone_base const * e=0;
307 exception_detail::clone_current_exception(e) )
309 case exception_detail::clone_current_exception_result::
313 return exception_ptr(shared_ptr<exception_detail::clone_base const>(e));
315 case exception_detail::clone_current_exception_result::
319 return exception_detail::exception_ptr_static_exception_object<bad_alloc_>::e;
321 case exception_detail::clone_current_exception_result::
325 return exception_detail::exception_ptr_static_exception_object<bad_exception_>::e;
329 case exception_detail::clone_current_exception_result::
338 exception_detail::clone_base & e )
340 return exception_ptr(shared_ptr<exception_detail::clone_base const>(e.clone()));
343 std::domain_error & e )
345 return exception_detail::current_exception_std_exception(e);
348 std::invalid_argument & e )
350 return exception_detail::current_exception_std_exception(e);
353 std::length_error & e )
355 return exception_detail::current_exception_std_exception(e);
358 std::out_of_range & e )
360 return exception_detail::current_exception_std_exception(e);
363 std::logic_error & e )
365 return exception_detail::current_exception_std_exception(e);
368 std::range_error & e )
370 return exception_detail::current_exception_std_exception(e);
373 std::overflow_error & e )
375 return exception_detail::current_exception_std_exception(e);
378 std::underflow_error & e )
380 return exception_detail::current_exception_std_exception(e);
383 std::ios_base::failure & e )
385 return exception_detail::current_exception_std_exception(e);
388 std::runtime_error & e )
390 return exception_detail::current_exception_std_exception(e);
395 return exception_detail::current_exception_std_exception(e);
397 #ifndef BOOST_NO_TYPEID
401 return exception_detail::current_exception_std_exception(e);
404 std::bad_typeid & e )
406 return exception_detail::current_exception_std_exception(e);
410 std::bad_exception & e )
412 return exception_detail::current_exception_std_exception(e);
417 return exception_detail::current_exception_unknown_std_exception(e);
420 boost::exception & e )
422 return exception_detail::current_exception_unknown_boost_exception(e);
427 return exception_detail::current_exception_unknown_exception();
441 ret=exception_detail::current_exception_impl();
446 ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_alloc_>::e;
451 ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_exception_>::e;
460 rethrow_exception( exception_ptr const & p )
465 #if defined(UNDER_CE)
466 // some CE platforms don't define ::abort()
475 diagnostic_information( exception_ptr const & p, bool verbose=true )
480 rethrow_exception(p);
485 return current_exception_diagnostic_information(verbose);
492 to_string( exception_ptr const & p )
494 std::string s='\n'+diagnostic_information(p);
495 std::string padding(" ");
498 for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i )
510 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)