support for exception_ptr and nesting of exception_ptr objects in boost::diagnostic_information

[SVN r53066]
This commit is contained in:
Emil Dotchevski
2009-05-17 06:12:29 +00:00
parent 4138359063
commit de1a3daa85
47 changed files with 7227 additions and 6549 deletions

View File

@ -0,0 +1,26 @@
//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_DC4208C6417811DEBF11E1EC55D89593
#define UUID_DC4208C6417811DEBF11E1EC55D89593
namespace
boost
{
namespace
exception_detail
{
class
exception_ptr_base
{
public:
virtual void _rethrow() const=0;
virtual bool _empty() const=0;
};
}
}
#endif

View File

@ -8,6 +8,7 @@
#include <boost/config.hpp>
#include <boost/exception/get_error_info.hpp>
#include <boost/exception/detail/exception_ptr_base.hpp>
#include <boost/utility/enable_if.hpp>
#include <exception>
#include <sstream>
@ -41,16 +42,6 @@ boost
enum e { value = !enable_boost_exception_overload<T>::value && sizeof(check((T*)0))==sizeof(yes) };
};
#ifndef BOOST_NO_RTTI
template <class T>
inline
std::string
dynamic_exception_type( T const & x )
{
return std::string("Dynamic exception type: ") + BOOST_EXCEPTION_DYNAMIC_TYPEID(x).name();
}
#endif
inline
char const *
get_diagnostic_information( exception const & x )
@ -72,43 +63,41 @@ boost
inline
std::string
boost_diagnostic_information( exception const & x )
diagnostic_information_impl( boost::exception const * be, std::exception const * se )
{
BOOST_ASSERT(be||se);
#ifndef BOOST_NO_RTTI
if( !se )
se = dynamic_cast<std::exception const *>(be);
if( !be )
be = dynamic_cast<boost::exception const *>(se);
#endif
std::ostringstream tmp;
if( char const * const * f=get_error_info<throw_file>(x) )
if( be )
{
tmp << *f;
if( int const * l=get_error_info<throw_line>(x) )
tmp << '(' << *l << "): ";
if( char const * const * f=get_error_info<throw_file>(*be) )
{
tmp << *f;
if( int const * l=get_error_info<throw_line>(*be) )
tmp << '(' << *l << "): ";
}
tmp << "Throw in function ";
if( char const * const * fn=get_error_info<throw_function>(*be) )
tmp << *fn;
else
tmp << "(unknown)";
tmp << '\n';
}
tmp << "Throw in function ";
if( char const * const * fn=get_error_info<throw_function>(x) )
tmp << *fn;
else
tmp << "(unknown)";
tmp << std::endl;
#ifndef BOOST_NO_RTTI
tmp << dynamic_exception_type(x) << std::endl;
if( std::exception const * e=dynamic_cast<std::exception const *>(&x) )
tmp << "std::exception::what: " << e->what() << std::endl;
tmp << std::string("Dynamic exception type: ") <<
(be?BOOST_EXCEPTION_DYNAMIC_TYPEID(*be):BOOST_EXCEPTION_DYNAMIC_TYPEID(*se)).name() << '\n';
#endif
if( char const * s=exception_detail::get_diagnostic_information(x) )
if( *s )
tmp << s;
return tmp.str();
}
inline
std::string
std_diagnostic_information( std::exception const & x )
{
std::ostringstream tmp;
#ifndef BOOST_NO_RTTI
if( exception const * e=dynamic_cast<exception const *>(&x) )
return boost_diagnostic_information(*e);
tmp << dynamic_exception_type(x) << std::endl;
#endif
tmp << "std::exception::what: " << x.what() << std::endl;
if( se )
tmp << "std::exception::what: " << se->what() << '\n';
if( be )
if( char const * s=exception_detail::get_diagnostic_information(*be) )
if( *s )
tmp << s;
return tmp.str();
}
}
@ -118,7 +107,7 @@ boost
typename enable_if<exception_detail::enable_boost_exception_overload<T>,std::string>::type
diagnostic_information( T const & e )
{
return exception_detail::boost_diagnostic_information(e);
return exception_detail::diagnostic_information_impl(&e,0);
}
template <class T>
@ -126,7 +115,7 @@ boost
typename enable_if<exception_detail::enable_std_exception_overload<T>,std::string>::type
diagnostic_information( T const & e )
{
return exception_detail::std_diagnostic_information(e);
return exception_detail::diagnostic_information_impl(0,&e);
}
}
@ -139,14 +128,31 @@ boost
std::string
current_exception_diagnostic_information()
{
if( boost::exception const * e=current_exception_cast<boost::exception const>() )
return diagnostic_information(*e);
else if( std::exception const * e=current_exception_cast<std::exception const>() )
return diagnostic_information(*e);
boost::exception const * be=current_exception_cast<boost::exception const>();
std::exception const * se=current_exception_cast<std::exception const>();
if( be || se )
return exception_detail::diagnostic_information_impl(be,se);
else
return "No diagnostic information available.";
}
}
inline
std::string
diagnostic_information( exception_detail::exception_ptr_base const & p )
{
if( !p._empty() )
try
{
p._rethrow();
}
catch(
... )
{
return current_exception_diagnostic_information();
}
return "<empty>";
}
}
#endif
#endif

View File

@ -106,7 +106,7 @@ boost
for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i )
{
shared_ptr<error_info_base const> const & x = i->second;
tmp << '[' << x->tag_typeid_name() << "] = " << x->value_as_string() << std::endl;
tmp << '[' << x->tag_typeid_name() << "] = " << x->value_as_string() << '\n';
}
tmp.str().swap(diagnostic_info_str_);
}