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
9 #include <boost/config.hpp>
10 #ifdef BOOST_NO_EXCEPTIONS
11 #error This header requires exception handling to be enabled.
13 #include <boost/exception/exception.hpp>
14 #include <boost/exception/info.hpp>
15 #include <boost/exception/diagnostic_information.hpp>
16 #include <boost/exception/detail/clone_current_exception.hpp>
17 #include <boost/exception/detail/type_info.hpp>
19 #include <boost/core/demangle.hpp>
21 #include <boost/shared_ptr.hpp>
27 #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
28 #pragma GCC system_header
30 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
31 #pragma warning(push,1)
38 BOOST_NORETURN void rethrow_exception( exception_ptr const & );
39 exception_ptr current_exception();
44 typedef boost::shared_ptr<exception_detail::clone_base const> impl;
46 friend void rethrow_exception( exception_ptr const & );
47 typedef exception_detail::clone_base const * (impl::*unspecified_bool_type)() const;
53 exception_ptr( impl const & ptr ):
58 operator==( exception_ptr const & other ) const
60 return ptr_==other.ptr_;
63 operator!=( exception_ptr const & other ) const
65 return ptr_!=other.ptr_;
67 operator unspecified_bool_type() const
69 return ptr_?&impl::get:0;
76 copy_exception( T const & e )
80 throw enable_current_exception(e);
85 return current_exception();
90 typedef error_info<struct tag_original_exception_type,std::type_info const *> original_exception_type;
94 to_string( original_exception_type const & x )
96 return core::demangle(x.value()->name());
108 ~bad_alloc_() throw() { }
116 ~bad_exception_() throw() { }
119 template <class Exception>
121 get_static_exception_object()
124 exception_detail::clone_impl<Exception> c(ba);
125 #ifndef BOOST_EXCEPTION_DISABLE
127 throw_function(BOOST_CURRENT_FUNCTION) <<
128 throw_file(__FILE__) <<
129 throw_line(__LINE__);
131 static exception_ptr ep(shared_ptr<exception_detail::clone_base const>(new exception_detail::clone_impl<Exception>(c)));
135 template <class Exception>
137 exception_ptr_static_exception_object
139 static exception_ptr const e;
142 template <class Exception>
144 exception_ptr_static_exception_object<Exception>::
145 e = get_static_exception_object<Exception>();
148 #if defined(__GNUC__)
149 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
150 # pragma GCC visibility push (default)
155 public boost::exception,
156 public std::exception
165 unknown_exception( std::exception const & e )
167 add_original_type(e);
171 unknown_exception( boost::exception const & e ):
174 add_original_type(e);
177 ~unknown_exception() throw()
185 add_original_type( E const & e )
187 #ifndef BOOST_NO_RTTI
188 (*this) << original_exception_type(&typeid(e));
192 #if defined(__GNUC__)
193 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
194 # pragma GCC visibility pop
203 current_exception_std_exception_wrapper:
205 public boost::exception
210 current_exception_std_exception_wrapper( T const & e1 ):
213 add_original_type(e1);
216 current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ):
220 add_original_type(e1);
223 ~current_exception_std_exception_wrapper() throw()
231 add_original_type( E const & e )
233 #ifndef BOOST_NO_RTTI
234 (*this) << original_exception_type(&typeid(e));
241 boost::exception const *
242 get_boost_exception( T const * )
249 boost::exception & x )
260 boost::exception const *
261 get_boost_exception( T const * x )
263 return dynamic_cast<boost::exception const *>(x);
270 current_exception_std_exception( T const & e1 )
272 if( boost::exception const * e2 = get_boost_exception(&e1) )
273 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1,*e2));
275 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1));
280 current_exception_unknown_exception()
282 return boost::copy_exception(unknown_exception());
287 current_exception_unknown_boost_exception( boost::exception const & e )
289 return boost::copy_exception(unknown_exception(e));
294 current_exception_unknown_std_exception( std::exception const & e )
296 if( boost::exception const * be = get_boost_exception(&e) )
297 return current_exception_unknown_boost_exception(*be);
299 return boost::copy_exception(unknown_exception(e));
304 current_exception_impl()
306 exception_detail::clone_base const * e=0;
308 exception_detail::clone_current_exception(e) )
310 case exception_detail::clone_current_exception_result::
314 return exception_ptr(shared_ptr<exception_detail::clone_base const>(e));
316 case exception_detail::clone_current_exception_result::
320 return exception_detail::exception_ptr_static_exception_object<bad_alloc_>::e;
322 case exception_detail::clone_current_exception_result::
326 return exception_detail::exception_ptr_static_exception_object<bad_exception_>::e;
330 case exception_detail::clone_current_exception_result::
339 exception_detail::clone_base & e )
341 return exception_ptr(shared_ptr<exception_detail::clone_base const>(e.clone()));
344 std::domain_error & e )
346 return exception_detail::current_exception_std_exception(e);
349 std::invalid_argument & e )
351 return exception_detail::current_exception_std_exception(e);
354 std::length_error & e )
356 return exception_detail::current_exception_std_exception(e);
359 std::out_of_range & e )
361 return exception_detail::current_exception_std_exception(e);
364 std::logic_error & e )
366 return exception_detail::current_exception_std_exception(e);
369 std::range_error & e )
371 return exception_detail::current_exception_std_exception(e);
374 std::overflow_error & e )
376 return exception_detail::current_exception_std_exception(e);
379 std::underflow_error & e )
381 return exception_detail::current_exception_std_exception(e);
384 std::ios_base::failure & e )
386 return exception_detail::current_exception_std_exception(e);
389 std::runtime_error & e )
391 return exception_detail::current_exception_std_exception(e);
396 return exception_detail::current_exception_std_exception(e);
398 #ifndef BOOST_NO_TYPEID
402 return exception_detail::current_exception_std_exception(e);
405 std::bad_typeid & e )
407 return exception_detail::current_exception_std_exception(e);
411 std::bad_exception & e )
413 return exception_detail::current_exception_std_exception(e);
418 return exception_detail::current_exception_unknown_std_exception(e);
421 boost::exception & e )
423 return exception_detail::current_exception_unknown_boost_exception(e);
428 return exception_detail::current_exception_unknown_exception();
442 ret=exception_detail::current_exception_impl();
447 ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_alloc_>::e;
452 ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_exception_>::e;
461 rethrow_exception( exception_ptr const & p )
466 #if defined(UNDER_CE)
467 // some CE platforms don't define ::abort()
476 diagnostic_information( exception_ptr const & p, bool verbose=true )
481 rethrow_exception(p);
486 return current_exception_diagnostic_information(verbose);
493 to_string( exception_ptr const & p )
495 std::string s='\n'+diagnostic_information(p);
496 std::string padding(" ");
499 for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i )
511 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)