Boost logo

Boost-Commit :

From: emil_at_[hidden]
Date: 2008-08-29 15:27:38


Author: emildotchevski
Date: 2008-08-29 15:27:38 EDT (Fri, 29 Aug 2008)
New Revision: 48455
URL: http://svn.boost.org/trac/boost/changeset/48455

Log:
Further simplified enable_current_exception. Improved exception_ptr testing.
Removed:
   trunk/boost/exception/detail/cloning_base.hpp
Text files modified:
   trunk/boost/exception/enable_current_exception.hpp | 117 ++-------------
   trunk/boost/exception_ptr.hpp | 286 +++++++++++++++++++++++++++++----------
   trunk/libs/exception/test/cloning_test.cpp | 208 +++++++++++++++++++++++++++++
   3 files changed, 441 insertions(+), 170 deletions(-)

Deleted: trunk/boost/exception/detail/cloning_base.hpp
==============================================================================
--- trunk/boost/exception/detail/cloning_base.hpp 2008-08-29 15:27:38 EDT (Fri, 29 Aug 2008)
+++ (empty file)
@@ -1,48 +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)
-
-#ifndef UUID_F7D5662CCB0F11DCA353CAC656D89593
-#define UUID_F7D5662CCB0F11DCA353CAC656D89593
-
-#include <boost/detail/workaround.hpp>
-
-namespace
-boost
- {
- namespace
- exception_detail
- {
- class clone_base;
-
- struct
- new_clone
- {
- clone_base const * c_;
- void (*d_)(clone_base const *);
- };
-
- class
- cloning_base
- {
- public:
-
- virtual new_clone clone() const = 0;
-
- protected:
-
-#if BOOST_WORKAROUND( __GNUC__, BOOST_TESTED_AT(4) )
-virtual //Disable bogus GCC warning.
-#endif
-#if BOOST_WORKAROUND( BOOST_MSVC, BOOST_TESTED_AT(1500) )
-virtual //Disable bogus msvc warning.
-#endif
- ~cloning_base() throw()
- {
- }
- };
- }
- }
-
-#endif

Modified: trunk/boost/exception/enable_current_exception.hpp
==============================================================================
--- trunk/boost/exception/enable_current_exception.hpp (original)
+++ trunk/boost/exception/enable_current_exception.hpp 2008-08-29 15:27:38 EDT (Fri, 29 Aug 2008)
@@ -7,9 +7,6 @@
 #define UUID_78CC85B2914F11DC8F47B48E55D89593
 
 #include <boost/exception/exception.hpp>
-#include <boost/exception/detail/cloning_base.hpp>
-#include <boost/assert.hpp>
-#include <new>
 
 namespace
 boost
@@ -17,6 +14,22 @@
     namespace
     exception_detail
         {
+ class
+ clone_base
+ {
+ public:
+
+ virtual clone_base const * clone() const = 0;
+ virtual void rethrow() const = 0;
+ virtual ~clone_base() throw() = 0;
+ };
+
+ inline
+ clone_base::
+ ~clone_base() throw()
+ {
+ }
+
         inline
         void
         copy_boost_exception( exception * a, exception const * b )
@@ -31,13 +44,10 @@
             }
 
         template <class T>
- new_clone make_clone( T const & );
-
- template <class T>
         class
         clone_impl:
             public T,
- public cloning_base
+ public clone_base
             {
             public:
 
@@ -54,107 +64,18 @@
 
             private:
 
- new_clone
+ clone_base const *
             clone() const
                 {
- return make_clone<T>(*this);
+ return new clone_impl(*this);
                 }
- };
-
- class
- clone_base
- {
- public:
-
- virtual void rethrow() const=0;
- virtual ~clone_base() throw()=0;
- };
 
- inline
- clone_base::
- ~clone_base() throw()
- {
- }
-
- struct
- bad_alloc_impl:
- public clone_base,
- public std::bad_alloc
- {
             void
             rethrow() const
                 {
                 throw *this;
                 }
             };
-
- template <class T>
- class
- exception_clone:
- public T,
- public clone_base
- {
- public:
-
- explicit
- exception_clone( T const & x ):
- T(x)
- {
- copy_boost_exception(this,&x);
- }
-
- private:
-
- ~exception_clone() throw()
- {
- }
-
- void
- rethrow() const
- {
- throw clone_impl<T>(*this);
- }
- };
-
- inline
- void
- delete_clone( clone_base const * c )
- {
- BOOST_ASSERT(c!=0);
- delete c;
- }
-
- inline
- void
- delete_clone_noop( clone_base const * )
- {
- }
-
- template <class T>
- inline
- new_clone
- make_clone( T const & x )
- {
- new_clone tmp = {0,0};
- try
- {
- tmp.c_=new exception_clone<T>(x);
- tmp.d_=&delete_clone;
- }
- catch(
- std::bad_alloc & )
- {
- static bad_alloc_impl bad_alloc;
- tmp.c_=&bad_alloc;
- tmp.d_=&delete_clone_noop;
- }
- catch(
- ... )
- {
- BOOST_ASSERT(0);
- }
- return tmp;
- }
         }
 
     template <class T>

Modified: trunk/boost/exception_ptr.hpp
==============================================================================
--- trunk/boost/exception_ptr.hpp (original)
+++ trunk/boost/exception_ptr.hpp 2008-08-29 15:27:38 EDT (Fri, 29 Aug 2008)
@@ -6,8 +6,8 @@
 #ifndef UUID_FA5836A2CADA11DC8CD47C8555D89593
 #define UUID_FA5836A2CADA11DC8CD47C8555D89593
 
-#include <boost/exception/enable_current_exception.hpp>
 #include <boost/exception/detail/get_boost_exception.hpp>
+#include <boost/exception/enable_current_exception.hpp>
 #include <boost/detail/atomic_count.hpp>
 #include <stdexcept>
 #include <new>
@@ -31,19 +31,19 @@
                 }
 
             void
- set( new_clone const & nc )
+ set( clone_base const * c )
                 {
- clone_ = nc.c_;
- clone_deleter_ = nc.d_;
+ clone_ = c;
                 BOOST_ASSERT(clone_!=0);
- BOOST_ASSERT(clone_deleter_!=0);
                 }
 
             void
             rethrow() const
                 {
- BOOST_ASSERT(clone_!=0);
- clone_->rethrow();
+ if( clone_ )
+ clone_->rethrow();
+ else
+ throw enable_current_exception(std::bad_alloc());
                 }
 
             private:
@@ -58,7 +58,7 @@
             ~counted_clone() throw()
                 {
                 if( clone_ )
- clone_deleter_(clone_);
+ delete clone_;
                 }
 
             void
@@ -74,14 +74,114 @@
                     delete this;
                 }
             };
+
+ struct
+ bad_alloc_tag
+ {
+ };
+
+ struct
+ bad_exception_tag
+ {
+ };
         }
 
- typedef intrusive_ptr<exception_detail::counted_clone const> exception_ptr;
+ class exception_ptr;
+ void rethrow_exception( exception_ptr const & );
+
+ class
+ exception_ptr
+ {
+ private:
+
+ friend void rethrow_exception( exception_ptr const & );
+
+ enum
+ {
+ bad_alloc_caught,
+ clone_failed,
+ ok
+ } what_happened_;
+
+ intrusive_ptr<exception_detail::counted_clone> c_;
+
+ void
+ rethrow() const
+ {
+ 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)
+ {
+ }
+
+ explicit
+ exception_ptr( exception_detail::bad_exception_tag ):
+ what_happened_(clone_failed)
+ {
+ }
+
+ exception_ptr():
+ what_happened_(ok)
+ {
+ }
+
+ explicit
+ exception_ptr( intrusive_ptr<exception_detail::counted_clone> const & c ):
+ what_happened_(ok),
+ c_(c)
+ {
+ BOOST_ASSERT(c_.get()!=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_;
+ }
+
+ friend
+ bool
+ operator!=( exception_ptr const & a, exception_ptr const & b )
+ {
+ return !(a==b);
+ }
+
+ operator unspecified_bool_type() const
+ {
+ return (what_happened_!=ok || c_) ? &exception_ptr::c_ : 0;
+ }
+ };
 
     class
     unknown_exception:
         public exception,
- public std::exception
+ public std::exception,
+ public exception_detail::clone_base
         {
         public:
 
@@ -98,6 +198,20 @@
         ~unknown_exception() throw()
             {
             }
+
+ private:
+
+ clone_base const *
+ clone() const
+ {
+ return new unknown_exception(*this);
+ }
+
+ void
+ rethrow() const
+ {
+ throw *this;
+ }
         };
 
     namespace
@@ -107,7 +221,8 @@
         class
         current_exception_std_exception_wrapper:
             public T,
- public boost::exception
+ public boost::exception,
+ public clone_base
             {
             public:
 
@@ -126,6 +241,20 @@
             ~current_exception_std_exception_wrapper() throw()
                 {
                 }
+
+ private:
+
+ clone_base const *
+ clone() const
+ {
+ return new current_exception_std_exception_wrapper(*this);
+ }
+
+ void
+ rethrow() const
+ {
+ throw *this;
+ }
             };
 
         template <class T>
@@ -135,10 +264,10 @@
             {
             intrusive_ptr<exception_detail::counted_clone> x(new exception_detail::counted_clone);
             if( boost::exception const * e2 = get_boost_exception(&e1) )
- x->set(exception_detail::make_clone(current_exception_std_exception_wrapper<T>(e1,*e2)));
+ x->set(new current_exception_std_exception_wrapper<T>(e1,*e2));
             else
- x->set(exception_detail::make_clone(current_exception_std_exception_wrapper<T>(e1)));
- return x;
+ x->set(new current_exception_std_exception_wrapper<T>(e1));
+ return exception_ptr(x);
             }
 
         inline
@@ -146,8 +275,8 @@
         current_exception_unknown_exception()
             {
             intrusive_ptr<exception_detail::counted_clone> x(new exception_detail::counted_clone);
- x->set(exception_detail::make_clone(unknown_exception()));
- return x;
+ x->set(new unknown_exception());
+ return exception_ptr(x);
             }
 
         inline
@@ -157,8 +286,8 @@
             if( boost::exception const * be = get_boost_exception(&e) )
                 {
                 intrusive_ptr<exception_detail::counted_clone> x(new exception_detail::counted_clone);
- x->set(exception_detail::make_clone(unknown_exception(*be)));
- return x;
+ x->set(new unknown_exception(*be));
+ return exception_ptr(x);
                 }
             else
                 return current_exception_unknown_exception();
@@ -169,8 +298,8 @@
         current_exception_unknown_boost_exception( boost::exception const & e )
             {
             intrusive_ptr<exception_detail::counted_clone> x(new exception_detail::counted_clone);
- x->set(exception_detail::make_clone(unknown_exception(e)));
- return x;
+ x->set(new unknown_exception(e));
+ return exception_ptr(x);
             }
         }
 
@@ -180,64 +309,77 @@
         {
         try
             {
- throw;
- }
- catch(
- exception_detail::cloning_base & e )
- {
- intrusive_ptr<exception_detail::counted_clone> x(new exception_detail::counted_clone);
- x->set(e.clone());
- return x;
- }
- catch(
- std::invalid_argument & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::out_of_range & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::logic_error & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::bad_alloc & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::bad_cast & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::bad_typeid & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::bad_exception & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::exception & e )
- {
- return exception_detail::current_exception_unknown_std_exception(e);
+ try
+ {
+ throw;
+ }
+ 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);
+ }
+ catch(
+ std::invalid_argument & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::out_of_range & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::logic_error & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::bad_alloc & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::bad_cast & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::bad_typeid & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::bad_exception & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::exception & e )
+ {
+ return exception_detail::current_exception_unknown_std_exception(e);
+ }
+ catch(
+ boost::exception & e )
+ {
+ return exception_detail::current_exception_unknown_boost_exception(e);
+ }
+ catch(
+ ... )
+ {
+ return exception_detail::current_exception_unknown_exception();
+ }
             }
         catch(
- boost::exception & e )
+ std::bad_alloc & )
             {
- return exception_detail::current_exception_unknown_boost_exception(e);
+ return exception_ptr( exception_detail::bad_alloc_tag() );
             }
         catch(
         ... )
             {
- return exception_detail::current_exception_unknown_exception();
+ return exception_ptr( exception_detail::bad_exception_tag() );
             }
         }
 
@@ -260,7 +402,7 @@
     void
     rethrow_exception( exception_ptr const & p )
         {
- p->rethrow();
+ p.rethrow();
         }
     }
 

Modified: trunk/libs/exception/test/cloning_test.cpp
==============================================================================
--- trunk/libs/exception/test/cloning_test.cpp (original)
+++ trunk/libs/exception/test/cloning_test.cpp 2008-08-29 15:27:38 EDT (Fri, 29 Aug 2008)
@@ -11,6 +11,25 @@
 
 typedef boost::error_info<struct my_tag,int> my_info;
 
+template <class T>
+struct
+may_throw_on_copy
+ {
+ may_throw_on_copy():
+ throw_(false)
+ {
+ }
+
+ may_throw_on_copy( may_throw_on_copy const & x ):
+ throw_(x.throw_)
+ {
+ if( throw_ )
+ throw T();
+ }
+
+ bool throw_;
+ };
+
 struct
 derives_nothing
     {
@@ -66,6 +85,9 @@
     ... )
         {
         boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
         try
             {
             rethrow_exception(p);
@@ -74,6 +96,24 @@
         catch(
         T & )
             {
+ boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
+ try
+ {
+ rethrow_exception(p);
+ BOOST_TEST(false);
+ }
+ catch(
+ T & )
+ {
+ }
+ catch(
+ ... )
+ {
+ BOOST_TEST(false);
+ }
             }
         catch(
         ... )
@@ -95,6 +135,9 @@
     ... )
         {
         boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
         try
             {
             rethrow_exception(p);
@@ -104,6 +147,89 @@
         T & x )
             {
             BOOST_TEST(std::string("what")==x.what());
+ boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
+ try
+ {
+ rethrow_exception(p);
+ BOOST_TEST(false);
+ }
+ catch(
+ T & x )
+ {
+ BOOST_TEST(std::string("what")==x.what());
+ }
+ catch(
+ ... )
+ {
+ BOOST_TEST(false);
+ }
+ }
+ catch(
+ ... )
+ {
+ BOOST_TEST(false);
+ }
+ }
+ }
+
+template <class Throw,class Catch>
+void
+test_throw_on_copy()
+ {
+ try
+ {
+ try
+ {
+ throw boost::enable_current_exception(may_throw_on_copy<Throw>());
+ }
+ catch(
+ may_throw_on_copy<Throw> & x )
+ {
+ x.throw_=true;
+ throw;
+ }
+ catch(
+ ... )
+ {
+ BOOST_TEST(false);
+ }
+ }
+ catch(
+ ... )
+ {
+ boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
+ try
+ {
+ rethrow_exception(p);
+ BOOST_TEST(false);
+ }
+ catch(
+ Catch & )
+ {
+ boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
+ try
+ {
+ boost::rethrow_exception(p);
+ BOOST_TEST(false);
+ }
+ catch(
+ Catch & )
+ {
+ }
+ catch(
+ ... )
+ {
+ BOOST_TEST(false);
+ }
             }
         catch(
         ... )
@@ -116,6 +242,10 @@
 int
 main()
     {
+ BOOST_TEST( boost::exception_ptr()==boost::exception_ptr() );
+ BOOST_TEST( !(boost::exception_ptr()!=boost::exception_ptr()) );
+ BOOST_TEST( !boost::exception_ptr() );
+
     int count=0;
     try
         {
@@ -125,6 +255,9 @@
     ... )
         {
         boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
         try
             {
             rethrow_exception(p);
@@ -150,6 +283,9 @@
     ... )
         {
         boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
         try
             {
             rethrow_exception(p);
@@ -158,6 +294,24 @@
         catch(
         derives_std_exception & )
             {
+ boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
+ try
+ {
+ rethrow_exception(p);
+ BOOST_TEST(false);
+ }
+ catch(
+ derives_std_exception & )
+ {
+ }
+ catch(
+ ... )
+ {
+ BOOST_TEST(false);
+ }
             }
         catch(
         ... )
@@ -174,6 +328,9 @@
     ... )
         {
         boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
         try
             {
             rethrow_exception(p);
@@ -206,6 +363,9 @@
     ... )
         {
         boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
         try
             {
             rethrow_exception(p);
@@ -217,6 +377,27 @@
             BOOST_TEST(boost::get_error_info<my_info>(x));
             if( boost::shared_ptr<int const> p=boost::get_error_info<my_info>(x) )
                 BOOST_TEST(*p==42);
+ boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
+ try
+ {
+ rethrow_exception(p);
+ BOOST_TEST(false);
+ }
+ catch(
+ boost::unknown_exception & x )
+ {
+ BOOST_TEST(boost::get_error_info<my_info>(x));
+ if( boost::shared_ptr<int const> p=boost::get_error_info<my_info>(x) )
+ BOOST_TEST(*p==42);
+ }
+ catch(
+ ... )
+ {
+ BOOST_TEST(false);
+ }
             }
         catch(
         ... )
@@ -233,6 +414,9 @@
     ... )
         {
         boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
         try
             {
             rethrow_exception(p);
@@ -244,6 +428,27 @@
             BOOST_TEST(boost::get_error_info<my_info>(x));
             if( boost::shared_ptr<int const> p=boost::get_error_info<my_info>(x) )
                 BOOST_TEST(*p==42);
+ boost::exception_ptr p = boost::current_exception();
+ BOOST_TEST(!(p==boost::exception_ptr()));
+ BOOST_TEST(p!=boost::exception_ptr());
+ BOOST_TEST(p);
+ try
+ {
+ rethrow_exception(p);
+ BOOST_TEST(false);
+ }
+ catch(
+ boost::unknown_exception & x )
+ {
+ BOOST_TEST(boost::get_error_info<my_info>(x));
+ if( boost::shared_ptr<int const> p=boost::get_error_info<my_info>(x) )
+ BOOST_TEST(*p==42);
+ }
+ catch(
+ ... )
+ {
+ BOOST_TEST(false);
+ }
             }
         catch(
         ... )
@@ -252,5 +457,8 @@
             }
         }
 
+ test_throw_on_copy<std::bad_alloc,std::bad_alloc>();
+ test_throw_on_copy<int,std::bad_exception>();
+
     return boost::report_errors();
     }


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