1 //Copyright (c) 2006-2010 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_0552D49838DD11DD90146B8956D89593
7 #define UUID_0552D49838DD11DD90146B8956D89593
9 #include <boost/config.hpp>
10 #include <boost/exception/get_error_info.hpp>
11 #include <boost/exception/info.hpp>
12 #include <boost/utility/enable_if.hpp>
14 #include <boost/core/demangle.hpp>
19 #ifndef BOOST_NO_EXCEPTIONS
20 #include <boost/exception/current_exception_cast.hpp>
23 #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
24 #pragma GCC system_header
26 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
27 #pragma warning(push,1)
30 #ifndef BOOST_NO_EXCEPTIONS
37 std::string diagnostic_information_impl( boost::exception const *, std::exception const *, bool, bool );
42 current_exception_diagnostic_information( bool verbose=true)
44 boost::exception const * be=current_exception_cast<boost::exception const>();
45 std::exception const * se=current_exception_cast<std::exception const>();
47 return exception_detail::diagnostic_information_impl(be,se,true,verbose);
48 #if defined(__GLIBCXX__) && __cplusplus >= 201103L && !defined(BOOST_NO_RTTI)
49 else if (auto* p=std::current_exception().__cxa_exception_type())
50 return "Dynamic exception type: "+boost::core::demangle(p->name());
53 return "No diagnostic information available.";
66 get_boost_exception( exception const * e )
73 get_boost_exception( ... )
79 std::exception const *
80 get_std_exception( std::exception const * e )
86 std::exception const *
87 get_std_exception( ... )
94 get_diagnostic_information( exception const & x, char const * header )
96 #ifndef BOOST_NO_EXCEPTIONS
100 error_info_container * c=x.data_.get();
102 x.data_.adopt(c=new exception_detail::error_info_container_impl);
103 char const * di=c->diagnostic_information(header);
106 #ifndef BOOST_NO_EXCEPTIONS
117 diagnostic_information_impl( boost::exception const * be, std::exception const * se, bool with_what, bool verbose )
120 return "Unknown exception.";
121 #ifndef BOOST_NO_RTTI
123 be=dynamic_cast<boost::exception const *>(se);
125 se=dynamic_cast<std::exception const *>(be);
128 if( with_what && se )
131 if( be && exception_detail::get_diagnostic_information(*be,0)==wh )
134 std::ostringstream tmp;
137 char const * const * f=get_error_info<throw_file>(*be);
138 int const * l=get_error_info<throw_line>(*be);
139 char const * const * fn=get_error_info<throw_function>(*be);
140 if( !f && !l && !fn )
141 tmp << "Throw location unknown (consider using BOOST_THROW_EXCEPTION)\n";
147 if( int const * l=get_error_info<throw_line>(*be) )
148 tmp << '(' << *l << "): ";
150 tmp << "Throw in function ";
151 if( char const * const * fn=get_error_info<throw_function>(*be) )
158 #ifndef BOOST_NO_RTTI
160 tmp << std::string("Dynamic exception type: ") <<
161 core::demangle((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()) << '\n';
163 if( with_what && se && verbose )
164 tmp << "std::exception::what: " << (wh ? wh : "(null)") << '\n';
166 if( char const * s=exception_detail::get_diagnostic_information(*be,tmp.str().c_str()) )
168 return std::string(s);
175 diagnostic_information( T const & e, bool verbose=true )
177 return exception_detail::diagnostic_information_impl(exception_detail::get_boost_exception(&e),exception_detail::get_std_exception(&e),true,verbose);
182 diagnostic_information_what( exception const & e, bool verbose=true ) BOOST_NOEXCEPT_OR_NOTHROW
185 #ifndef BOOST_NO_EXCEPTIONS
189 (void) exception_detail::diagnostic_information_impl(&e,0,false,verbose);
190 if( char const * di=exception_detail::get_diagnostic_information(e,0) )
193 return "Failed to produce boost::diagnostic_information_what()";
194 #ifndef BOOST_NO_EXCEPTIONS
205 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)