Boost logo

Boost-Commit :

From: emil_at_[hidden]
Date: 2008-09-01 17:06:11


Author: emildotchevski
Date: 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
New Revision: 48521
URL: http://svn.boost.org/trac/boost/changeset/48521

Log:
Optimization for error_info<throw_function>, error_info<throw_file>, error_info<throw_line>. Refactored exception_ptr to use shared_ptr.
Removed:
   trunk/libs/exception/test/boost_error_info_test.cpp
Text files modified:
   trunk/boost/exception/detail/error_info_base.hpp | 7
   trunk/boost/exception/detail/object_hex_dump.hpp | 1
   trunk/boost/exception/detail/type_info.hpp | 21 +--
   trunk/boost/exception/diagnostic_information.hpp | 80 +++++-------
   trunk/boost/exception/exception.hpp | 183 ++++++++++++++++++-------------
   trunk/boost/exception/get_error_info.hpp | 113 +++++++++++++++++--
   trunk/boost/exception/info.hpp | 17 --
   trunk/boost/exception_ptr.hpp | 231 ++++++++++++---------------------------
   trunk/boost/throw_exception.hpp | 7 +
   trunk/libs/exception/example/example_io.cpp | 12 +-
   trunk/libs/exception/example/logging.cpp | 2
   trunk/libs/exception/test/Jamfile.v2 | 1
   trunk/libs/exception/test/diagnostic_information_test.cpp | 62 +---------
   trunk/libs/exception/test/refcount_ptr_test.cpp | 12 -
   trunk/libs/exception/test/throw_exception_test.cpp | 61 ++++++++++
   15 files changed, 407 insertions(+), 403 deletions(-)

Modified: trunk/boost/exception/detail/error_info_base.hpp
==============================================================================
--- trunk/boost/exception/detail/error_info_base.hpp (original)
+++ trunk/boost/exception/detail/error_info_base.hpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -6,7 +6,6 @@
 #ifndef UUID_CE6983AC753411DDA764247956D89593
 #define UUID_CE6983AC753411DDA764247956D89593
 
-#include <boost/detail/workaround.hpp>
 #include <string>
 
 namespace
@@ -25,10 +24,8 @@
 
             protected:
 
-#if BOOST_WORKAROUND( __GNUC__, BOOST_TESTED_AT(4) )
-virtual //Disable bogus GCC warning.
-#endif
- ~error_info_base()
+ virtual
+ ~error_info_base() throw()
                 {
                 }
             };

Modified: trunk/boost/exception/detail/object_hex_dump.hpp
==============================================================================
--- trunk/boost/exception/detail/object_hex_dump.hpp (original)
+++ trunk/boost/exception/detail/object_hex_dump.hpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -8,7 +8,6 @@
 
 #include <boost/exception/detail/type_info.hpp>
 #include <iomanip>
-#include <typeinfo>
 #include <ios>
 #include <string>
 #include <sstream>

Modified: trunk/boost/exception/detail/type_info.hpp
==============================================================================
--- trunk/boost/exception/detail/type_info.hpp (original)
+++ trunk/boost/exception/detail/type_info.hpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -46,13 +46,6 @@
 
             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 )
                 {
                 return a.type_<b.type_;
@@ -90,13 +83,6 @@
 
             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 )
                 {
                 return 0!=(a.type_->before(*b.type_));
@@ -109,6 +95,13 @@
                 }
             };
 #endif
+
+ inline
+ bool
+ operator!=( type_info_ const & a, type_info_ const & b )
+ {
+ return !(a==b);
+ }
         }
     }
 

Modified: trunk/boost/exception/diagnostic_information.hpp
==============================================================================
--- trunk/boost/exception/diagnostic_information.hpp (original)
+++ trunk/boost/exception/diagnostic_information.hpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -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 @@
     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();
             }
 
@@ -38,55 +52,29 @@
 #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();
         }
     }
 

Modified: trunk/boost/exception/exception.hpp
==============================================================================
--- trunk/boost/exception/exception.hpp (original)
+++ trunk/boost/exception/exception.hpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -9,9 +9,6 @@
 namespace
 boost
     {
-
- ////////////////////////////////////////////////////////////////////////
-
     namespace
     exception_detail
         {
@@ -66,65 +63,77 @@
             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
- {
- class
- counted_base
- {
- friend
- void
- intrusive_ptr_add_ref( counted_base const * c )
- {
- c->add_ref();
- }
+ template <class Tag,class T>
+ class error_info;
 
- friend
- void
- intrusive_ptr_release( counted_base const * c )
- {
- c->release();
- }
+ 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;
 
- virtual void add_ref() const=0;
- virtual void release() const=0;
+ template <>
+ class
+ error_info<tag_throw_function,char const *>
+ {
+ public:
+ typedef char const * value_type;
+ value_type v_;
+ explicit
+ error_info( value_type v ):
+ v_(v)
+ {
+ }
+ };
 
- protected:
+ 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
- ~counted_base() throw()
- {
- }
- };
- }
+ 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;
 
     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 @@
         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:
+ protected:
 
- virtual
- char const *
- diagnostic_information() const throw()
+ exception():
+ throw_function_(0),
+ throw_file_(0),
+ throw_line_(-1)
             {
- return _diagnostic_information();
             }
 
- protected:
+ virtual ~exception() throw() = 0;
 
- exception()
+ private:
+
+ template <class E>
+ friend
+ E const &
+ operator<<( E const & x, throw_function y )
             {
+ x.throw_function_=y.v_;
+ return x;
             }
 
- virtual ~exception() throw()=0;
+ template <class E>
+ friend
+ E const &
+ operator<<( E const & x, throw_file y )
+ {
+ x.throw_file_=y.v_;
+ return x;
+ }
 
- char const *
- _diagnostic_information() const throw()
+ template <class E>
+ friend
+ E const &
+ operator<<( E const & x, throw_line y )
             {
- if( exception_detail::error_info_container * c=data_.get() )
- try
- {
- if( char const * w = c->diagnostic_information() )
- return w;
- }
- catch(...)
- {
- }
- return "";
+ x.throw_line_=y.v_;
+ return x;
             }
 
- private:
+ 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 E,class Tag,class T>
+ friend E const & operator<<( E const &, error_info<Tag,T> const & );
 
- template <class ErrorInfo>
- friend shared_ptr<typename ErrorInfo::value_type const> exception_detail::get_info( exception 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 @@
 
             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 @@
             void
             rethrow() const
                 {
- throw *this;
+ throw*this;
                 }
             };
         }
@@ -334,9 +362,6 @@
         {
         return exception_detail::clone_impl<T>(x);
         }
-
- ////////////////////////////////////////////////////////////////////////
-
     }
 
 #endif

Modified: trunk/boost/exception/get_error_info.hpp
==============================================================================
--- trunk/boost/exception/get_error_info.hpp (original)
+++ trunk/boost/exception/get_error_info.hpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -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 @@
     namespace
     exception_detail
         {
- template <class ErrorInfo>
- inline
- shared_ptr<typename ErrorInfo::value_type const>
- get_info( exception const & x )
+ struct
+ strwrap
+ {
+ 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_ )
+ {
+ shared_ptr<strwrap> s(new strwrap(x.throw_function_));
+ return shared_ptr<char const *>(s,&s->str);
+ }
+ else
+ return shared_ptr<char const * const>();
+ }
+ };
+
+ template <>
+ struct
+ get_info<throw_file>
             {
- 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)) )
+ 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()) );
+ 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>();
- }
+ 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 @@
     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 @@
     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>();
         }

Modified: trunk/boost/exception/info.hpp
==============================================================================
--- trunk/boost/exception/info.hpp (original)
+++ trunk/boost/exception/info.hpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -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 @@
             {
             }
 
+ ~error_info() throw()
+ {
+ }
+
         value_type const &
         value() const
             {
@@ -159,7 +152,7 @@
         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;
         }
     }
 

Modified: trunk/boost/exception_ptr.hpp
==============================================================================
--- trunk/boost/exception_ptr.hpp (original)
+++ trunk/boost/exception_ptr.hpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -8,161 +8,63 @@
 
 #include <boost/exception/exception.hpp>
 #include <boost/exception/detail/type_info.hpp>
-#include <boost/detail/atomic_count.hpp>
-#include <boost/intrusive_ptr.hpp>
+#include <boost/shared_ptr.hpp>
 #include <stdexcept>
 #include <new>
 
 namespace
 boost
     {
- namespace
- exception_detail
- {
- class
- counted_clone:
- public counted_base
- {
- public:
-
- counted_clone():
- count_(0),
- clone_(0)
- {
- }
-
- void
- set( clone_base const * c )
- {
- clone_ = c;
- BOOST_ASSERT(clone_!=0);
- }
-
- void
- rethrow() const
- {
- if( clone_ )
- clone_->rethrow();
- else
- throw enable_current_exception(std::bad_alloc());
- }
-
- private:
-
- counted_clone( counted_clone const & );
- counted_clone & operator=( counted_clone const & );
-
- mutable detail::atomic_count count_;
- clone_base const * clone_;
- void (*clone_deleter_)(clone_base const *);
-
- ~counted_clone() throw()
- {
- if( clone_ )
- delete clone_;
- }
-
- void
- add_ref() const
- {
- ++count_;
- }
-
- void
- release() const
- {
- if( !--count_ )
- delete this;
- }
- };
-
- struct
- bad_alloc_tag
- {
- };
-
- struct
- bad_exception_tag
- {
- };
- }
-
     class exception_ptr;
+ exception_ptr current_exception();
     void rethrow_exception( exception_ptr const & );
 
     class
     exception_ptr
         {
- private:
-
+ typedef bool exception_ptr::*unspecified_bool_type;
+ friend exception_ptr current_exception();
         friend void rethrow_exception( exception_ptr const & );
 
- enum
- {
- bad_alloc_caught,
- clone_failed,
- ok
- } what_happened_;
-
- intrusive_ptr<exception_detail::counted_clone> c_;
+ shared_ptr<exception_detail::clone_base const> c_;
+ bool bad_alloc_;
 
- void
- rethrow() const
+ struct
+ bad_alloc_tag
             {
- switch(
- what_happened_ )
- {
- case
- bad_alloc_caught:
- throw enable_current_exception(std::bad_alloc());
- case
- clone_failed:
- throw enable_current_exception(std::bad_exception());
- case
- ok:
- BOOST_ASSERT(c_.get()!=0);
- c_->rethrow();
- }
- BOOST_ASSERT(0);
- }
-
- typedef intrusive_ptr<exception_detail::counted_clone> exception_ptr::*unspecified_bool_type;
-
- public:
+ };
 
         explicit
- exception_ptr( exception_detail::bad_alloc_tag ):
- what_happened_(bad_alloc_caught)
+ exception_ptr( bad_alloc_tag ):
+ bad_alloc_(true)
             {
             }
 
         explicit
- exception_ptr( exception_detail::bad_exception_tag ):
- what_happened_(clone_failed)
+ exception_ptr( shared_ptr<exception_detail::clone_base const> const & c ):
+ c_(c),
+ bad_alloc_(false)
             {
+ BOOST_ASSERT(c);
             }
 
+ public:
+
         exception_ptr():
- what_happened_(ok)
+ bad_alloc_(false)
             {
             }
 
- explicit
- exception_ptr( intrusive_ptr<exception_detail::counted_clone> const & c ):
- what_happened_(ok),
- c_(c)
+ operator unspecified_bool_type() const
             {
- BOOST_ASSERT(c_.get()!=0);
+ return (bad_alloc_ || c_) ? &exception_ptr::bad_alloc_ : 0;
             }
 
         friend
         bool
         operator==( exception_ptr const & a, exception_ptr const & b )
             {
- return
- a.what_happened_==ok &&
- b.what_happened_==ok &&
- a.c_==b.c_;
+ return a.c_==b.c_ && a.bad_alloc_==b.bad_alloc_;
             }
 
         friend
@@ -171,11 +73,6 @@
             {
             return !(a==b);
             }
-
- operator unspecified_bool_type() const
- {
- return (what_happened_!=ok || c_) ? &exception_ptr::c_ : 0;
- }
         };
 
     class
@@ -211,7 +108,7 @@
         void
         rethrow() const
             {
- throw *this;
+ throw*this;
             }
         };
 
@@ -288,55 +185,42 @@
 
         template <class T>
         inline
- exception_ptr
+ shared_ptr<clone_base const>
         current_exception_std_exception( T const & e1 )
             {
- intrusive_ptr<exception_detail::counted_clone> x(new exception_detail::counted_clone);
             if( boost::exception const * e2 = get_boost_exception(&e1) )
- x->set(new current_exception_std_exception_wrapper<T>(e1,*e2));
+ return shared_ptr<clone_base const>(new current_exception_std_exception_wrapper<T>(e1,*e2));
             else
- x->set(new current_exception_std_exception_wrapper<T>(e1));
- return exception_ptr(x);
+ return shared_ptr<clone_base const>(new current_exception_std_exception_wrapper<T>(e1));
             }
 
         inline
- exception_ptr
+ shared_ptr<clone_base const>
         current_exception_unknown_exception()
             {
- intrusive_ptr<exception_detail::counted_clone> x(new exception_detail::counted_clone);
- x->set(new unknown_exception());
- return exception_ptr(x);
+ return shared_ptr<clone_base const>(new unknown_exception());
             }
 
         inline
- exception_ptr
+ shared_ptr<clone_base const>
+ current_exception_unknown_boost_exception( boost::exception const & e )
+ {
+ return shared_ptr<clone_base const>(new unknown_exception(e));
+ }
+
+ inline
+ shared_ptr<clone_base const>
         current_exception_unknown_std_exception( std::exception const & e )
             {
             if( boost::exception const * be = get_boost_exception(&e) )
- {
- intrusive_ptr<exception_detail::counted_clone> x(new exception_detail::counted_clone);
- x->set(new unknown_exception(*be));
- return exception_ptr(x);
- }
+ return current_exception_unknown_boost_exception(*be);
             else
                 return current_exception_unknown_exception();
             }
 
         inline
- exception_ptr
- current_exception_unknown_boost_exception( boost::exception const & e )
- {
- intrusive_ptr<exception_detail::counted_clone> x(new exception_detail::counted_clone);
- x->set(new unknown_exception(e));
- return exception_ptr(x);
- }
- }
-
- inline
- exception_ptr
- current_exception()
- {
- try
+ shared_ptr<clone_base const>
+ current_exception_impl()
             {
             try
                 {
@@ -345,9 +229,7 @@
             catch(
             exception_detail::clone_base & e )
                 {
- intrusive_ptr<exception_detail::counted_clone> x(new exception_detail::counted_clone);
- x->set(e.clone());
- return exception_ptr(x);
+ return shared_ptr<exception_detail::clone_base const>(e.clone());
                 }
             catch(
             std::invalid_argument & e )
@@ -402,16 +284,38 @@
                 return exception_detail::current_exception_unknown_exception();
                 }
             }
+ }
+
+ inline
+ exception_ptr
+ current_exception()
+ {
+ try
+ {
+ return exception_ptr(exception_detail::current_exception_impl());
+ }
         catch(
         std::bad_alloc & )
             {
- return exception_ptr( exception_detail::bad_alloc_tag() );
             }
         catch(
         ... )
             {
- return exception_ptr( exception_detail::bad_exception_tag() );
+ try
+ {
+ return exception_ptr(exception_detail::current_exception_std_exception(std::bad_exception()));
+ }
+ catch(
+ std::bad_alloc & )
+ {
+ }
+ catch(
+ ... )
+ {
+ BOOST_ASSERT(0);
+ }
             }
+ return exception_ptr(exception_ptr::bad_alloc_tag());
         }
 
     template <class T>
@@ -423,7 +327,8 @@
             {
             throw enable_current_exception(e);
             }
- catch( ... )
+ catch(
+ ... )
             {
             return current_exception();
             }
@@ -433,7 +338,11 @@
     void
     rethrow_exception( exception_ptr const & p )
         {
- p.rethrow();
+ BOOST_ASSERT(p);
+ if( p.bad_alloc_ )
+ throw enable_current_exception(std::bad_alloc());
+ else
+ p.c_->rethrow();
         }
     }
 

Modified: trunk/boost/throw_exception.hpp
==============================================================================
--- trunk/boost/throw_exception.hpp (original)
+++ trunk/boost/throw_exception.hpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -38,6 +38,13 @@
 
 #if !defined( BOOST_NO_EXCEPTIONS ) && !defined( BOOST_EXCEPTION_DISABLE )
 # 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
 
 namespace boost

Modified: trunk/libs/exception/example/example_io.cpp
==============================================================================
--- trunk/libs/exception/example/example_io.cpp (original)
+++ trunk/libs/exception/example/example_io.cpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -66,11 +66,11 @@
     if( FILE * f = ::fopen(name,mode) )
         return boost::shared_ptr<FILE>(f,fclose);
     else
- throw fopen_error() << BOOST_ERROR_INFO <<
+ BOOST_THROW_EXCEPTION(fopen_error() <<
             errno_info(errno) <<
             file_name_info(name) <<
             open_mode_info(mode) <<
- function_info("fopen");
+ function_info("fopen"));
     }
 
 void
@@ -78,10 +78,10 @@
     {
     assert(stream);
     if( count!=fread(buffer,size,count,stream.get()) || ferror(stream.get()) )
- throw fread_error() << BOOST_ERROR_INFO <<
+ BOOST_THROW_EXCEPTION(fread_error() <<
             function_info("fread") <<
             errno_info(errno) <<
- file_stream_info(boost::weak_ptr<FILE>(stream));
+ file_stream_info(boost::weak_ptr<FILE>(stream)));
     }
 
 void
@@ -89,10 +89,10 @@
     {
     assert(stream);
     if( count!=fwrite(buffer,size,count,stream.get()) || ferror(stream.get()) )
- throw fwrite_error() << BOOST_ERROR_INFO <<
+ BOOST_THROW_EXCEPTION(fwrite_error() <<
             function_info("fwrite") <<
             errno_info(errno) <<
- file_stream_info(boost::weak_ptr<FILE>(stream));
+ file_stream_info(boost::weak_ptr<FILE>(stream)));
     }
 
 void

Modified: trunk/libs/exception/example/logging.cpp
==============================================================================
--- trunk/libs/exception/example/logging.cpp (original)
+++ trunk/libs/exception/example/logging.cpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -20,6 +20,6 @@
     catch(
     boost::exception & e )
         {
- std::cerr << e.diagnostic_information();
+ std::cerr << diagnostic_information(e);
         }
     }

Modified: trunk/libs/exception/test/Jamfile.v2
==============================================================================
--- trunk/libs/exception/test/Jamfile.v2 (original)
+++ trunk/libs/exception/test/Jamfile.v2 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -23,7 +23,6 @@
 run copy_exception_test.cpp ;
 run unknown_exception_test.cpp ;
 run exception_test.cpp ;
-run boost_error_info_test.cpp ;
 run enable_error_info_test.cpp helper1.cpp ;
 run throw_exception_test.cpp helper2.cpp ;
 run errno_test.cpp ;

Deleted: trunk/libs/exception/test/boost_error_info_test.cpp
==============================================================================
--- trunk/libs/exception/test/boost_error_info_test.cpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
+++ (empty file)
@@ -1,41 +0,0 @@
-//Copyright (c) 2006-2008 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)
-
-#include <boost/exception/get_error_info.hpp>
-#include <boost/exception/info.hpp>
-#include <boost/detail/lightweight_test.hpp>
-#include <stdexcept>
-
-namespace
-test
- {
- class my_exception: public boost::exception { };
-
- typedef boost::error_info<struct tag_my_info,int> my_info;
-
- void
- test_boost_error_info()
- {
- try
- {
- throw my_exception() << BOOST_ERROR_INFO << my_info(1);
- }
- catch(
- my_exception & x )
- {
- BOOST_TEST(1==*boost::get_error_info<my_info>(x));
- BOOST_TEST(boost::get_error_info<boost::throw_function>(x));
- BOOST_TEST(boost::get_error_info<boost::throw_file>(x));
- BOOST_TEST(boost::get_error_info<boost::throw_line>(x));
- }
- }
- }
-
-int
-main()
- {
- test::test_boost_error_info();
- return boost::report_errors();
- }

Modified: trunk/libs/exception/test/diagnostic_information_test.cpp
==============================================================================
--- trunk/libs/exception/test/diagnostic_information_test.cpp (original)
+++ trunk/libs/exception/test/diagnostic_information_test.cpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -11,29 +11,18 @@
 
 struct
 error1:
- public std::exception
- {
- char const *
- what() const throw()
- {
- return "error1";
- }
- };
-
-struct
-error2:
     public std::exception,
     public boost::exception
     {
     char const *
     what() const throw()
         {
- return "error2";
+ return "error1";
         }
     };
 
 struct
-error3:
+error2:
     public boost::exception
     {
     };
@@ -44,56 +33,17 @@
     using namespace boost;
     try
         {
- error1 x;
+ error1 x; x << tag_int(42);
         BOOST_TEST(x.what()==std::string("error1"));
         throw x;
         }
     catch(
- std::exception & x )
- {
- std::string di=boost::diagnostic_information(x);
- BOOST_TEST(di.find("type:")!=std::string::npos);
- BOOST_TEST(di.find("error1")!=std::string::npos);
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- try
- {
- error2 x; x << tag_int(42);
- BOOST_TEST(x.what()==std::string("error2"));
- throw x;
- }
- catch(
- std::exception & x )
- {
- std::string di=boost::diagnostic_information(x);
- BOOST_TEST(di.find("type:")!=std::string::npos);
- BOOST_TEST(di.find("error2")!=std::string::npos);
-#ifndef BOOST_NO_RTTI
- BOOST_TEST(di.find("test_tag")!=std::string::npos);
-#endif
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- try
- {
- error2 x; x << tag_int(42);
- BOOST_TEST(x.what()==std::string("error2"));
- throw x;
- }
- catch(
     boost::exception & x )
         {
         std::string di=boost::diagnostic_information(x);
- BOOST_TEST(di.find("type:")!=std::string::npos);
 #ifndef BOOST_NO_RTTI
- BOOST_TEST(di.find("error2")!=std::string::npos);
+ BOOST_TEST(di.find("type:")!=std::string::npos);
+ BOOST_TEST(di.find("error1")!=std::string::npos);
 #endif
         BOOST_TEST(di.find("test_tag")!=std::string::npos);
         }
@@ -104,7 +54,7 @@
         }
     try
         {
- error3 x;
+ error2 x;
         x << tag_int(1);
         throw x;
         }

Modified: trunk/libs/exception/test/refcount_ptr_test.cpp
==============================================================================
--- trunk/libs/exception/test/refcount_ptr_test.cpp (original)
+++ trunk/libs/exception/test/refcount_ptr_test.cpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -22,19 +22,17 @@
         count_=42;
         }
 
- friend
     void
- intrusive_ptr_add_ref( test_type const * c )
+ add_ref()
         {
- ++c->count_;
+ ++count_;
         }
 
- friend
     void
- intrusive_ptr_release( test_type const * c )
+ release()
         {
- if( !--c->count_ )
- delete c;
+ if( !--count_ )
+ delete this;
         }
 
     private:

Modified: trunk/libs/exception/test/throw_exception_test.cpp
==============================================================================
--- trunk/libs/exception/test/throw_exception_test.cpp (original)
+++ trunk/libs/exception/test/throw_exception_test.cpp 2008-09-01 17:06:09 EDT (Mon, 01 Sep 2008)
@@ -11,6 +11,66 @@
 
 typedef boost::error_info<struct tag_test_int,int> test_data;
 
+struct
+exception1:
+ std::exception
+ {
+ };
+
+struct
+exception2:
+ std::exception,
+ boost::exception
+ {
+ };
+
+void
+boost_throw_exception_test()
+ {
+ try
+ {
+ BOOST_THROW_EXCEPTION(exception1());
+ BOOST_TEST(false);
+ }
+ catch(
+ boost::exception & x )
+ {
+ boost::shared_ptr<char const * const> file=boost::get_error_info<boost::throw_function>(x);
+ boost::shared_ptr<char const * const> function=boost::get_error_info<boost::throw_file>(x);
+ boost::shared_ptr<int const> line=boost::get_error_info<boost::throw_line>(x);
+ BOOST_TEST( file && *file );
+ BOOST_TEST( function && *function );
+ BOOST_TEST( line && *line==32 );
+ }
+ catch(
+ ... )
+ {
+ BOOST_TEST(false);
+ }
+ try
+ {
+ BOOST_THROW_EXCEPTION(exception2() << test_data(42));
+ BOOST_TEST(false);
+ }
+ catch(
+ boost::exception & x )
+ {
+ boost::shared_ptr<char const * const> file=boost::get_error_info<boost::throw_function>(x);
+ boost::shared_ptr<char const * const> function=boost::get_error_info<boost::throw_file>(x);
+ boost::shared_ptr<int const> line=boost::get_error_info<boost::throw_line>(x);
+ boost::shared_ptr<int const> data=boost::get_error_info<test_data>(x);
+ BOOST_TEST( file && *file );
+ BOOST_TEST( function && *function );
+ BOOST_TEST( line && *line==52 );
+ BOOST_TEST( data && *data==42 );
+ }
+ catch(
+ ... )
+ {
+ BOOST_TEST(false);
+ }
+ }
+
 void
 throw_fwd( void (*thrower)(int) )
     {
@@ -80,6 +140,7 @@
 int
 main()
     {
+ boost_throw_exception_test();
     tester<boost::exception_test::derives_boost_exception>();
     tester<boost::exception_test::derives_boost_exception_virtually>();
     tester<boost::exception_test::derives_std_exception>();


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk