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
committed by Peter Dimov
parent 67d235059a
commit 019fbaa77e
2 changed files with 116 additions and 84 deletions

View File

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

View File

@ -38,6 +38,13 @@
#if !defined( BOOST_NO_EXCEPTIONS ) && !defined( BOOST_EXCEPTION_DISABLE ) #if !defined( BOOST_NO_EXCEPTIONS ) && !defined( BOOST_EXCEPTION_DISABLE )
# include <boost/exception/exception.hpp> # include <boost/exception/exception.hpp>
# include <boost/current_function.hpp>
# define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(::boost::enable_error_info(x) <<\
::boost::throw_function(BOOST_CURRENT_FUNCTION) <<\
::boost::throw_file(__FILE__) <<\
::boost::throw_line((int)__LINE__))
#else
# define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x)
#endif #endif
namespace boost namespace boost