File indexing completed on 2025-01-30 09:35:33
0001
0002
0003
0004
0005
0006 #ifndef BOOST_EXCEPTION_0552D49838DD11DD90146B8956D89593
0007 #define BOOST_EXCEPTION_0552D49838DD11DD90146B8956D89593
0008
0009 #include <boost/config.hpp>
0010 #include <boost/exception/get_error_info.hpp>
0011 #include <boost/exception/info.hpp>
0012 #include <boost/core/enable_if.hpp>
0013 #ifndef BOOST_NO_RTTI
0014 #include <boost/core/demangle.hpp>
0015 #endif
0016 #include <exception>
0017 #include <sstream>
0018 #include <string>
0019 #ifndef BOOST_NO_EXCEPTIONS
0020 #include <boost/exception/current_exception_cast.hpp>
0021 #endif
0022
0023 #ifndef BOOST_EXCEPTION_ENABLE_WARNINGS
0024 #if __GNUC__*100+__GNUC_MINOR__>301
0025 #pragma GCC system_header
0026 #endif
0027 #ifdef __clang__
0028 #pragma clang system_header
0029 #endif
0030 #ifdef _MSC_VER
0031 #pragma warning(push,1)
0032 #endif
0033 #endif
0034
0035 #ifndef BOOST_NO_EXCEPTIONS
0036 namespace
0037 boost
0038 {
0039 namespace
0040 exception_detail
0041 {
0042 std::string diagnostic_information_impl( boost::exception const *, std::exception const *, bool, bool );
0043 }
0044
0045 inline
0046 std::string
0047 current_exception_diagnostic_information( bool verbose=true)
0048 {
0049 boost::exception const * be=current_exception_cast<boost::exception const>();
0050 std::exception const * se=current_exception_cast<std::exception const>();
0051 if( be || se )
0052 return exception_detail::diagnostic_information_impl(be,se,true,verbose);
0053 #if defined(__GLIBCXX__) && __cplusplus >= 201103L && !defined(BOOST_NO_RTTI)
0054 else if (auto* p=std::current_exception().__cxa_exception_type())
0055 return "Dynamic exception type: "+boost::core::demangle(p->name());
0056 #endif
0057 else
0058 return "No diagnostic information available.";
0059 }
0060 }
0061 #endif
0062
0063 namespace
0064 boost
0065 {
0066 namespace
0067 exception_detail
0068 {
0069 inline
0070 exception const *
0071 get_boost_exception( exception const * e )
0072 {
0073 return e;
0074 }
0075
0076 inline
0077 exception const *
0078 get_boost_exception( ... )
0079 {
0080 return 0;
0081 }
0082
0083 inline
0084 std::exception const *
0085 get_std_exception( std::exception const * e )
0086 {
0087 return e;
0088 }
0089
0090 inline
0091 std::exception const *
0092 get_std_exception( ... )
0093 {
0094 return 0;
0095 }
0096
0097 inline
0098 char const *
0099 get_diagnostic_information( exception const & x, char const * header )
0100 {
0101 #ifndef BOOST_NO_EXCEPTIONS
0102 try
0103 {
0104 #endif
0105 error_info_container * c=x.data_.get();
0106 if( !c )
0107 x.data_.adopt(c=new exception_detail::error_info_container_impl);
0108 char const * di=c->diagnostic_information(header);
0109 BOOST_ASSERT(di!=0);
0110 return di;
0111 #ifndef BOOST_NO_EXCEPTIONS
0112 }
0113 catch(...)
0114 {
0115 return 0;
0116 }
0117 #endif
0118 }
0119
0120 inline
0121 std::string
0122 diagnostic_information_impl( boost::exception const * be, std::exception const * se, bool with_what, bool verbose )
0123 {
0124 if( !be && !se )
0125 return "Unknown exception.";
0126 #ifndef BOOST_NO_RTTI
0127 if( !be )
0128 be=dynamic_cast<boost::exception const *>(se);
0129 if( !se )
0130 se=dynamic_cast<std::exception const *>(be);
0131 #endif
0132 char const * wh=0;
0133 if( with_what && se )
0134 {
0135 wh=se->what();
0136 if( be && exception_detail::get_diagnostic_information(*be,0)==wh )
0137 return wh;
0138 }
0139 std::ostringstream tmp;
0140 if( be && verbose )
0141 {
0142 char const * const * f=get_error_info<throw_file>(*be);
0143 int const * l=get_error_info<throw_line>(*be);
0144 char const * const * fn=get_error_info<throw_function>(*be);
0145 if( !f && !l && !fn )
0146 tmp << "Throw location unknown (consider using BOOST_THROW_EXCEPTION)\n";
0147 else
0148 {
0149 if( f )
0150 {
0151 tmp << *f;
0152 if( l )
0153 tmp << '(' << *l << "): ";
0154 }
0155 tmp << "Throw in function ";
0156 if( fn )
0157 tmp << *fn;
0158 else
0159 tmp << "(unknown)";
0160 tmp << '\n';
0161 }
0162 }
0163 #ifndef BOOST_NO_RTTI
0164 if ( verbose )
0165 tmp << std::string("Dynamic exception type: ") <<
0166 core::demangle((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()) << '\n';
0167 #endif
0168 if( with_what && se && verbose )
0169 tmp << "std::exception::what: " << (wh ? wh : "(null)") << '\n';
0170 if( be )
0171 if( char const * s=exception_detail::get_diagnostic_information(*be,tmp.str().c_str()) )
0172 if( *s )
0173 return std::string(s);
0174 return tmp.str();
0175 }
0176 }
0177
0178 template <class T>
0179 std::string
0180 diagnostic_information( T const & e, bool verbose=true )
0181 {
0182 return exception_detail::diagnostic_information_impl(exception_detail::get_boost_exception(&e),exception_detail::get_std_exception(&e),true,verbose);
0183 }
0184
0185 inline
0186 char const *
0187 diagnostic_information_what( exception const & e, bool verbose=true ) BOOST_NOEXCEPT_OR_NOTHROW
0188 {
0189 char const * w=0;
0190 #ifndef BOOST_NO_EXCEPTIONS
0191 try
0192 {
0193 #endif
0194 (void) exception_detail::diagnostic_information_impl(&e,0,false,verbose);
0195 if( char const * di=exception_detail::get_diagnostic_information(e,0) )
0196 return di;
0197 else
0198 return "Failed to produce boost::diagnostic_information_what()";
0199 #ifndef BOOST_NO_EXCEPTIONS
0200 }
0201 catch(
0202 ... )
0203 {
0204 }
0205 #endif
0206 return w;
0207 }
0208 }
0209
0210 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
0211 #pragma warning(pop)
0212 #endif
0213 #endif