forked from boostorg/throw_exception
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:
committed by
Peter Dimov
parent
67d235059a
commit
019fbaa77e
@ -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
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user