//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. //Distributed under the Boost Software License, Version 1.0. (See accompanying //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef UUID_618474C2DE1511DEB74A388C56D89593 #define UUID_618474C2DE1511DEB74A388C56D89593 #if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma warning(push,1) #endif #include #ifdef BOOST_NO_EXCEPTIONS #error This header requires exception handling to be enabled. #endif #include #include #include #include #include #include #include #include namespace boost { #ifndef BOOST_NO_RTTI typedef error_info original_exception_type; inline std::string to_string( original_exception_type const & x ) { return x.value()->name(); } #endif class exception_ptr; exception_ptr current_exception(); void rethrow_exception( exception_ptr const & ); class exception_ptr { typedef bool exception_ptr::*unspecified_bool_type; friend exception_ptr current_exception(); friend void rethrow_exception( exception_ptr const & ); shared_ptr c_; bool bad_alloc_; struct bad_alloc_tag { }; explicit exception_ptr( bad_alloc_tag ): bad_alloc_(true) { } explicit exception_ptr( shared_ptr const & c ): c_(c), bad_alloc_(false) { BOOST_ASSERT(c); } void rethrow() const { BOOST_ASSERT(*this); if( bad_alloc_ ) throw enable_current_exception(std::bad_alloc()); else c_->rethrow(); } bool empty() const { return !bad_alloc_ && !c_; } public: exception_ptr(): bad_alloc_(false) { } ~exception_ptr() throw() { } operator unspecified_bool_type() const { return empty() ? 0 : &exception_ptr::bad_alloc_; } friend bool operator==( exception_ptr const & a, exception_ptr const & b ) { return a.c_==b.c_ && a.bad_alloc_==b.bad_alloc_; } friend bool operator!=( exception_ptr const & a, exception_ptr const & b ) { return !(a==b); } }; class unknown_exception: public exception, public std::exception, public exception_detail::clone_base { public: unknown_exception() { } explicit unknown_exception( std::exception const & e ) { add_original_type(e); } explicit unknown_exception( boost::exception const & e ): boost::exception(e) { add_original_type(e); } ~unknown_exception() throw() { } private: exception_detail::clone_base const * clone() const { return new unknown_exception(*this); } void rethrow() const { throw*this; } template void add_original_type( E const & e ) { #ifndef BOOST_NO_RTTI (*this) << original_exception_type(&typeid(e)); #endif } }; namespace exception_detail { template class current_exception_std_exception_wrapper: public T, public boost::exception, public clone_base { public: explicit current_exception_std_exception_wrapper( T const & e1 ): T(e1) { add_original_type(e1); } current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ): T(e1), boost::exception(e2) { add_original_type(e1); } ~current_exception_std_exception_wrapper() throw() { } private: clone_base const * clone() const { return new current_exception_std_exception_wrapper(*this); } void rethrow() const { throw *this; } template void add_original_type( E const & e ) { #ifndef BOOST_NO_RTTI (*this) << original_exception_type(&typeid(e)); #endif } }; #ifdef BOOST_NO_RTTI template exception const * get_boost_exception( T const * ) { try { throw; } catch( exception & x ) { return &x; } catch(...) { return 0; } } #else template exception const * get_boost_exception( T const * x ) { return dynamic_cast(x); } #endif template inline shared_ptr current_exception_std_exception( T const & e1 ) { if( boost::exception const * e2 = get_boost_exception(&e1) ) return shared_ptr const>(new current_exception_std_exception_wrapper(e1,*e2)); else return shared_ptr const>(new current_exception_std_exception_wrapper(e1)); } inline shared_ptr current_exception_unknown_exception() { return shared_ptr(new unknown_exception()); } inline shared_ptr current_exception_unknown_boost_exception( boost::exception const & e ) { return shared_ptr(new unknown_exception(e)); } inline shared_ptr current_exception_unknown_std_exception( std::exception const & e ) { if( boost::exception const * be = get_boost_exception(&e) ) return current_exception_unknown_boost_exception(*be); else return shared_ptr(new unknown_exception(e)); } inline shared_ptr current_exception_impl() { try { throw; } catch( exception_detail::clone_base & e ) { return shared_ptr(e.clone()); } catch( std::domain_error & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::invalid_argument & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::length_error & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::out_of_range & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::logic_error & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::range_error & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::overflow_error & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::underflow_error & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::ios_base::failure & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::runtime_error & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::bad_alloc & e ) { return exception_detail::current_exception_std_exception(e); } #ifndef BOOST_NO_TYPEID catch( std::bad_cast & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::bad_typeid & e ) { return exception_detail::current_exception_std_exception(e); } #endif catch( std::bad_exception & e ) { return exception_detail::current_exception_std_exception(e); } catch( std::exception & e ) { return exception_detail::current_exception_unknown_std_exception(e); } catch( boost::exception & e ) { return exception_detail::current_exception_unknown_boost_exception(e); } catch( ... ) { return exception_detail::current_exception_unknown_exception(); } } } inline exception_ptr current_exception() { try { return exception_ptr(exception_detail::current_exception_impl()); } catch( std::bad_alloc & ) { } catch( ... ) { try { return exception_ptr(exception_detail::current_exception_std_exception(std::bad_exception())); } catch( std::bad_alloc & ) { } catch( ... ) { BOOST_ASSERT(0); } } return exception_ptr(exception_ptr::bad_alloc_tag()); } template inline exception_ptr copy_exception( T const & e ) { try { throw enable_current_exception(e); } catch( ... ) { return current_exception(); } } inline void rethrow_exception( exception_ptr const & p ) { p.rethrow(); } inline std::string diagnostic_information( exception_ptr const & p ) { if( p ) try { rethrow_exception(p); } catch( ... ) { return current_exception_diagnostic_information(); } return ""; } inline std::string to_string( exception_ptr const & p ) { std::string s='\n'+diagnostic_information(p); std::string padding(" "); std::string r; bool f=false; for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i ) { if( f ) r+=padding; char c=*i; r+=c; f=(c=='\n'); } return r; } } #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma warning(pop) #endif #endif