Optimization for error_info<throw_function>, error_info<throw_file>, error_info<throw_line>. Refactored exception_ptr to use shared_ptr.

[SVN r48521]
This commit is contained in:
Emil Dotchevski
2008-09-01 21:06:09 +00:00
parent 9a35c999a2
commit b84fb75a60
16 changed files with 418 additions and 455 deletions

View File

@ -6,7 +6,6 @@
#ifndef UUID_CE6983AC753411DDA764247956D89593
#define UUID_CE6983AC753411DDA764247956D89593
#include <boost/detail/workaround.hpp>
#include <string>
namespace
@ -25,10 +24,8 @@ boost
protected:
#if BOOST_WORKAROUND( __GNUC__, BOOST_TESTED_AT(4) )
virtual //Disable bogus GCC warning.
#endif
~error_info_base()
virtual
~error_info_base() throw()
{
}
};

View File

@ -8,7 +8,6 @@
#include <boost/exception/detail/type_info.hpp>
#include <iomanip>
#include <typeinfo>
#include <ios>
#include <string>
#include <sstream>

View File

@ -44,13 +44,6 @@ boost
return a.type_==b.type_;
}
friend
bool
operator!=( type_info_ const & a, type_info_ const & b )
{
return !(a==b);
}
friend
bool
operator<( type_info_ const & a, type_info_ const & b )
@ -88,13 +81,6 @@ boost
return (*a.type_)==(*b.type_);
}
friend
bool
operator!=( type_info_ const & a, type_info_ const & b )
{
return !(a==b);
}
friend
bool
operator<( type_info_ const & a, type_info_ const & b )
@ -109,6 +95,13 @@ boost
}
};
#endif
inline
bool
operator!=( type_info_ const & a, type_info_ const & b )
{
return !(a==b);
}
}
}

View File

@ -6,9 +6,9 @@
#ifndef UUID_0552D49838DD11DD90146B8956D89593
#define UUID_0552D49838DD11DD90146B8956D89593
#include <boost/exception/exception.hpp>
#include <boost/exception/detail/type_info.hpp>
#include <boost/exception/get_error_info.hpp>
#include <exception>
#include <sstream>
#include <string>
namespace
@ -17,13 +17,27 @@ boost
namespace
exception_detail
{
char const *
get_diagnostic_information( exception const & x )
{
if( error_info_container * c=x.data_.get() )
try
{
return c->diagnostic_information();
}
catch(...)
{
}
return 0;
}
template <class T>
std::string
std_exception_diagnostic_information( std::exception const * x, T const & )
{
if( char const * s=x->what() )
if( *s )
return std::string("std::exception::what(): ")+s;
return std::string("\nstd::exception::what(): ")+s;
return std::string();
}
@ -35,58 +49,32 @@ boost
if( std::exception const * x=dynamic_cast<std::exception const *>(&e) )
return std_exception_diagnostic_information(x,e);
else
#endif
return std::string();
}
template <class T>
std::string
boost_exception_diagnostic_information( boost::exception const * x, T const & )
{
if( char const * s=x->diagnostic_information() )
if( *s )
return std::string("boost::exception::diagnostic_information():\n")+s;
return std::string();
}
template <class T>
std::string
boost_exception_diagnostic_information( void const *, T const & e )
{
#ifndef BOOST_NO_RTTI
if( exception const * x=dynamic_cast<exception const *>(&e) )
return boost_exception_diagnostic_information(x,e);
else
#endif
return std::string();
}
}
template <class T>
inline
std::string
diagnostic_information( T const & x )
diagnostic_information( exception const & x )
{
std::string di=
#if defined(BOOST_NO_RTTI) || defined(BOOST_NO_TYPEID)
std::string("Static exception type: ")+BOOST_EXCEPTION_STATIC_TYPEID(T)
#else
std::string("Dynamic exception type: ")+BOOST_EXCEPTION_DYNAMIC_TYPEID(x)
std::ostringstream tmp;
tmp <<
"boost::exception diagnostic information:"
#if !defined(BOOST_NO_RTTI) && !defined(BOOST_NO_TYPEID)
"\nDynamic exception type: " << BOOST_EXCEPTION_DYNAMIC_TYPEID(x).name()
#endif
.name();
std::string di1=exception_detail::std_exception_diagnostic_information(&x,x);
if( !di1.empty() )
{
di+='\n';
di+=di1;
}
std::string di2=exception_detail::boost_exception_diagnostic_information(&x,x);
if( !di2.empty() )
{
di+='\n';
di+=di2;
}
return di;
;
if( boost::shared_ptr<char const * const> f=get_error_info<throw_function>(x) )
tmp << "\nThrow function: " << *f;
if( boost::shared_ptr<char const * const> f=get_error_info<throw_file>(x) )
tmp << "\nThrow file name: " << *f;
if( boost::shared_ptr<int const> l=get_error_info<throw_line>(x) )
tmp << "\nThrow file line: " << *l;
if( char const * s=exception_detail::get_diagnostic_information(x) )
if( *s )
tmp << "\n" << s;
return tmp.str();
}
}

View File

@ -9,9 +9,6 @@
namespace
boost
{
////////////////////////////////////////////////////////////////////////
namespace
exception_detail
{
@ -66,65 +63,77 @@ boost
add_ref()
{
if( px_ )
intrusive_ptr_add_ref(px_);
px_->add_ref();
}
void
release()
{
if( px_ )
intrusive_ptr_release(px_);
px_->release();
}
};
}
////////////////////////////////////////////////////////////////////////
namespace
exception_detail
template <class Tag,class T>
class error_info;
typedef error_info<struct tag_throw_function,char const *> throw_function;
typedef error_info<struct tag_throw_file,char const *> throw_file;
typedef error_info<struct tag_throw_line,int> throw_line;
template <>
class
error_info<tag_throw_function,char const *>
{
class
counted_base
public:
typedef char const * value_type;
value_type v_;
explicit
error_info( value_type v ):
v_(v)
{
friend
void
intrusive_ptr_add_ref( counted_base const * c )
{
c->add_ref();
}
}
};
friend
void
intrusive_ptr_release( counted_base const * c )
{
c->release();
}
template <>
class
error_info<tag_throw_file,char const *>
{
public:
typedef char const * value_type;
value_type v_;
explicit
error_info( value_type v ):
v_(v)
{
}
};
virtual void add_ref() const=0;
virtual void release() const=0;
template <>
class
error_info<tag_throw_line,int>
{
public:
typedef int value_type;
value_type v_;
explicit
error_info( value_type v ):
v_(v)
{
}
};
protected:
virtual
~counted_base() throw()
{
}
};
}
////////////////////////////////////////////////////////////////////////
template <class E,class Tag,class T>
E const & operator<<( E const &, error_info<Tag,T> const & );
class exception;
template <class>
class shared_ptr;
template <class Tag,class T>
class error_info;
template <class E,class Tag,class T>
E const & operator<<( E const &, error_info<Tag,T> const & );
namespace
exception_detail
{
@ -132,62 +141,83 @@ boost
struct type_info_;
struct
error_info_container:
public exception_detail::counted_base
error_info_container
{
virtual char const * diagnostic_information() const = 0;
virtual shared_ptr<error_info_base const> get( type_info_ const & ) const = 0;
virtual void set( shared_ptr<error_info_base const> const &, type_info_ const & ) = 0;
virtual void add_ref() const = 0;
virtual void release() const = 0;
protected:
virtual
~error_info_container() throw()
{
}
};
template <class ErrorInfo>
shared_ptr<typename ErrorInfo::value_type const> get_info( exception const & );
template <class>
struct get_info;
char const * get_diagnostic_information( exception const & );
}
class
exception
{
public:
virtual
char const *
diagnostic_information() const throw()
{
return _diagnostic_information();
}
protected:
exception()
exception():
throw_function_(0),
throw_file_(0),
throw_line_(-1)
{
}
virtual ~exception() throw()=0;
char const *
_diagnostic_information() const throw()
{
if( exception_detail::error_info_container * c=data_.get() )
try
{
if( char const * w = c->diagnostic_information() )
return w;
}
catch(...)
{
}
return "";
}
virtual ~exception() throw() = 0;
private:
template <class E,class Tag,class T>
friend E const & operator<<( E const &, error_info<Tag,T> const & );
template <class E>
friend
E const &
operator<<( E const & x, throw_function y )
{
x.throw_function_=y.v_;
return x;
}
template <class ErrorInfo>
friend shared_ptr<typename ErrorInfo::value_type const> exception_detail::get_info( exception const & );
template <class E>
friend
E const &
operator<<( E const & x, throw_file y )
{
x.throw_file_=y.v_;
return x;
}
template <class E>
friend
E const &
operator<<( E const & x, throw_line y )
{
x.throw_line_=y.v_;
return x;
}
friend char const * exception_detail::get_diagnostic_information( exception const & );
template <class E,class Tag,class T>
friend E const & operator<<( E const &, error_info<Tag,T> const & );
template <class>
friend struct exception_detail::get_info;
mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;
mutable char const * throw_function_;
mutable char const * throw_file_;
mutable int throw_line_;
};
inline
@ -270,14 +300,12 @@ boost
virtual clone_base const * clone() const = 0;
virtual void rethrow() const = 0;
virtual ~clone_base() throw() = 0;
};
inline
clone_base::
~clone_base() throw()
{
}
virtual
~clone_base() throw()
{
}
};
inline
void
@ -322,7 +350,7 @@ boost
void
rethrow() const
{
throw *this;
throw*this;
}
};
}
@ -334,9 +362,6 @@ boost
{
return exception_detail::clone_impl<T>(x);
}
////////////////////////////////////////////////////////////////////////
}
#endif

View File

@ -10,6 +10,7 @@
#include <boost/exception/detail/error_info_base.hpp>
#include <boost/exception/detail/type_info.hpp>
#include <boost/shared_ptr.hpp>
#include <memory.h>
namespace
boost
@ -17,22 +18,106 @@ boost
namespace
exception_detail
{
template <class ErrorInfo>
inline
shared_ptr<typename ErrorInfo::value_type const>
get_info( exception const & x )
struct
strwrap
{
if( exception_detail::error_info_container * c=x.data_.get() )
if( shared_ptr<exception_detail::error_info_base const> eib = c->get(BOOST_EXCEPTION_STATIC_TYPEID(ErrorInfo)) )
char const * str;
strwrap( char const * s ):
str(init(s))
{
}
~strwrap()
{
delete[] str;
}
private:
strwrap( strwrap const & );
strwrap & operator=( strwrap const & );
static
char const *
init( char const * s )
{
size_t n=1+strlen(s);
char * str = new char[n];
(void) memcpy(str,s,n);
return str;
}
};
template <>
struct
get_info<throw_function>
{
static
shared_ptr<char const * const>
get( exception const & x )
{
if( x.throw_function_ )
{
#ifndef BOOST_NO_RTTI
BOOST_ASSERT( 0!=dynamic_cast<ErrorInfo const *>(eib.get()) );
#endif
ErrorInfo const * w = static_cast<ErrorInfo const *>(eib.get());
return shared_ptr<typename ErrorInfo::value_type const>(eib,&w->value());
shared_ptr<strwrap> s(new strwrap(x.throw_function_));
return shared_ptr<char const *>(s,&s->str);
}
return shared_ptr<typename ErrorInfo::value_type const>();
}
else
return shared_ptr<char const * const>();
}
};
template <>
struct
get_info<throw_file>
{
static
shared_ptr<char const * const>
get( exception const & x )
{
if( x.throw_file_ )
{
shared_ptr<strwrap> s(new strwrap(x.throw_file_));
return shared_ptr<char const *>(s,&s->str);
}
else
return shared_ptr<char const * const>();
}
};
template <>
struct
get_info<throw_line>
{
static
shared_ptr<int const>
get( exception const & x )
{
if( x.throw_line_!=-1 )
return boost::shared_ptr<int>(new int(x.throw_line_));
else
return shared_ptr<int const>();
}
};
template <class ErrorInfo>
struct
get_info
{
static
shared_ptr<typename ErrorInfo::value_type const>
get( exception const & x )
{
if( exception_detail::error_info_container * c=x.data_.get() )
if( shared_ptr<exception_detail::error_info_base const> eib = c->get(BOOST_EXCEPTION_STATIC_TYPEID(ErrorInfo)) )
{
#ifndef BOOST_NO_RTTI
BOOST_ASSERT( 0!=dynamic_cast<ErrorInfo const *>(eib.get()) );
#endif
ErrorInfo const * w = static_cast<ErrorInfo const *>(eib.get());
return shared_ptr<typename ErrorInfo::value_type const>(eib,&w->value());
}
return shared_ptr<typename ErrorInfo::value_type const>();
}
};
}
#ifdef BOOST_NO_RTTI
@ -41,7 +126,7 @@ boost
shared_ptr<typename ErrorInfo::value_type const>
get_error_info( boost::exception const & x )
{
return exception_detail::get_info<ErrorInfo>(x);
return exception_detail::get_info<ErrorInfo>::get(x);
}
#else
template <class ErrorInfo,class E>
@ -50,7 +135,7 @@ boost
get_error_info( E const & some_exception )
{
if( exception const * x = dynamic_cast<exception const *>(&some_exception) )
return exception_detail::get_info<ErrorInfo>(*x);
return exception_detail::get_info<ErrorInfo>::get(*x);
else
return shared_ptr<typename ErrorInfo::value_type const>();
}

View File

@ -7,25 +7,14 @@
#define UUID_8D22C4CA9CC811DCAA9133D256D89593
#include <boost/exception/exception.hpp>
#include <boost/exception/error_info.hpp>
#include <boost/exception/to_string_stub.hpp>
#include <boost/exception/detail/error_info_base.hpp>
#include <boost/exception/detail/type_info.hpp>
#include <boost/shared_ptr.hpp>
#include <map>
#define BOOST_ERROR_INFO\
::boost::throw_function(BOOST_CURRENT_FUNCTION) <<\
::boost::throw_file(__FILE__) <<\
::boost::throw_line((int)__LINE__)
namespace
boost
{
typedef error_info<struct tag_throw_function,char const *> throw_function;
typedef error_info<struct tag_throw_file,char const *> throw_file;
typedef error_info<struct tag_throw_line,int> throw_line;
template <class Tag,class T>
class
error_info:
@ -40,6 +29,10 @@ boost
{
}
~error_info() throw()
{
}
value_type const &
value() const
{
@ -159,7 +152,7 @@ boost
if( !(c=x.data_.get()) )
x.data_.adopt(c=new exception_detail::error_info_container_impl);
c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t));
return x;
return x;
}
}