$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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();
     }