Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #ifndef UUID_0552D49838DD11DD90146B8956D89593
00007 #define UUID_0552D49838DD11DD90146B8956D89593
00008
00009 #include <boost/config.hpp>
00010 #include <boost/exception/get_error_info.hpp>
00011 #include <boost/utility/enable_if.hpp>
00012 #include <exception>
00013 #include <sstream>
00014 #include <string>
00015
00016 namespace
00017 boost
00018 {
00019 namespace
00020 exception_detail
00021 {
00022 template <class T>
00023 struct
00024 enable_boost_exception_overload
00025 {
00026 struct yes { char q[100]; };
00027 typedef char no;
00028 static yes check(exception const *);
00029 static no check(...);
00030 enum e { value=sizeof(check((T*)0))==sizeof(yes) };
00031 };
00032
00033 template <class T>
00034 struct
00035 enable_std_exception_overload
00036 {
00037 struct yes { char q[100]; };
00038 typedef char no;
00039 static yes check(std::exception const *);
00040 static no check(...);
00041 enum e { value = !enable_boost_exception_overload<T>::value && sizeof(check((T*)0))==sizeof(yes) };
00042 };
00043
00044 #ifndef BOOST_NO_RTTI
00045 template <class T>
00046 inline
00047 std::string
00048 dynamic_exception_type( T const & x )
00049 {
00050 return std::string("Dynamic exception type: ") + BOOST_EXCEPTION_DYNAMIC_TYPEID(x).name();
00051 }
00052 #endif
00053
00054 inline
00055 char const *
00056 get_diagnostic_information( exception const & x )
00057 {
00058 if( error_info_container * c=x.data_.get() )
00059 #ifndef BOOST_NO_EXCEPTIONS
00060 try
00061 {
00062 #endif
00063 return c->diagnostic_information();
00064 #ifndef BOOST_NO_EXCEPTIONS
00065 }
00066 catch(...)
00067 {
00068 }
00069 #endif
00070 return 0;
00071 }
00072
00073 inline
00074 std::string
00075 boost_diagnostic_information( exception const & x )
00076 {
00077 std::ostringstream tmp;
00078 if( char const * const * f=get_error_info<throw_file>(x) )
00079 {
00080 tmp << *f;
00081 if( int const * l=get_error_info<throw_line>(x) )
00082 tmp << '(' << *l << "): ";
00083 }
00084 tmp << "Throw in function ";
00085 if( char const * const * fn=get_error_info<throw_function>(x) )
00086 tmp << *fn;
00087 else
00088 tmp << "(unknown)";
00089 tmp << std::endl;
00090 #ifndef BOOST_NO_RTTI
00091 tmp << dynamic_exception_type(x) << std::endl;
00092 if( std::exception const * e=dynamic_cast<std::exception const *>(&x) )
00093 tmp << "std::exception::what: " << e->what() << std::endl;
00094 #endif
00095 if( char const * s=exception_detail::get_diagnostic_information(x) )
00096 if( *s )
00097 tmp << s;
00098 return tmp.str();
00099 }
00100
00101 inline
00102 std::string
00103 std_diagnostic_information( std::exception const & x )
00104 {
00105 std::ostringstream tmp;
00106 #ifndef BOOST_NO_RTTI
00107 if( exception const * e=dynamic_cast<exception const *>(&x) )
00108 return boost_diagnostic_information(*e);
00109 tmp << dynamic_exception_type(x) << std::endl;
00110 #endif
00111 tmp << "std::exception::what: " << x.what() << std::endl;
00112 return tmp.str();
00113 }
00114 }
00115
00116 template <class T>
00117 inline
00118 typename enable_if<exception_detail::enable_boost_exception_overload<T>,std::string>::type
00119 diagnostic_information( T const & e )
00120 {
00121 return exception_detail::boost_diagnostic_information(e);
00122 }
00123
00124 template <class T>
00125 inline
00126 typename enable_if<exception_detail::enable_std_exception_overload<T>,std::string>::type
00127 diagnostic_information( T const & e )
00128 {
00129 return exception_detail::std_diagnostic_information(e);
00130 }
00131 }
00132
00133 #ifndef BOOST_NO_EXCEPTIONS
00134 #include <boost/exception/current_exception_cast.hpp>
00135 namespace
00136 boost
00137 {
00138 inline
00139 std::string
00140 current_exception_diagnostic_information()
00141 {
00142 if( boost::exception const * e=current_exception_cast<boost::exception const>() )
00143 return diagnostic_information(*e);
00144 else if( std::exception const * e=current_exception_cast<std::exception const>() )
00145 return diagnostic_information(*e);
00146 else
00147 return "No diagnostic information available.";
00148 }
00149 }
00150 #endif
00151
00152 #endif