diff --git a/example/cloning_1.cpp b/example/cloning_1.cpp index 55e8479..5aa700a 100644 --- a/example/cloning_1.cpp +++ b/example/cloning_1.cpp @@ -5,7 +5,7 @@ //This example shows how to enable cloning when throwing a boost::exception. -#include +#include #include #include #include @@ -18,5 +18,6 @@ void file_read( FILE * f, void * buffer, size_t size ) { if( size!=fread(buffer,1,size,f) ) - throw boost::enable_exception_cloning(file_read_error()) << errno_info(errno); + throw boost::enable_current_exception(file_read_error()) << + errno_info(errno); } diff --git a/example/cloning_2.cpp b/example/cloning_2.cpp index 157f0b5..8fe4ec2 100644 --- a/example/cloning_2.cpp +++ b/example/cloning_2.cpp @@ -20,13 +20,13 @@ worker_thread( boost::exception_ptr & error ) error = boost::exception_ptr(); } catch( - boost::exception & e ) + ... ) { - error = boost::clone_exception(e); + error = boost::current_exception(); } } -// +// ...continued void work() diff --git a/include/boost/exception/cloning.hpp b/include/boost/exception/cloning.hpp index 4025762..f401f35 100644 --- a/include/boost/exception/cloning.hpp +++ b/include/boost/exception/cloning.hpp @@ -6,10 +6,10 @@ #ifndef UUID_FA5836A2CADA11DC8CD47C8555D89593 #define UUID_FA5836A2CADA11DC8CD47C8555D89593 -#include +#include #include #include -#include +#include namespace boost @@ -21,31 +21,165 @@ boost { public: - explicit unknown_exception() { } explicit - unknown_exception( boost::exception const & x ): - boost::exception(x) + unknown_exception( boost::exception const & e ): + boost::exception(e) { } }; typedef intrusive_ptr exception_ptr; + namespace + exception_detail + { + template + class + current_exception_std_exception_wrapper: + public T, + public boost::exception + { + public: + + explicit + current_exception_std_exception_wrapper( T const & e1 ): + T(e1) + { + } + + current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ): + T(e1), + boost::exception(e2) + { + } + }; + + template + exception_ptr + current_exception_std_exception( T const & e1 ) + { + if( boost::exception const * e2 = dynamic_cast(&e1) ) + return exception_ptr(exception_detail::make_clone(current_exception_std_exception_wrapper(e1,*e2))); + else + return exception_ptr(exception_detail::make_clone(current_exception_std_exception_wrapper(e1))); + } + + inline + exception_ptr + current_exception_unknown_exception() + { + return exception_ptr(exception_detail::make_clone(unknown_exception())); + } + + inline + exception_ptr + current_exception_unknown_std_exception( std::exception const & e ) + { + if( boost::exception const * be = dynamic_cast(&e) ) + return exception_ptr(exception_detail::make_clone(unknown_exception(*be))); + else + return current_exception_unknown_exception(); + } + + inline + exception_ptr + current_exception_unknown_boost_exception( boost::exception const & e ) + { + return exception_ptr(exception_detail::make_clone(unknown_exception(e))); + } + } + + inline + exception_ptr + current_exception() + { + try + { + throw; + } + catch( + exception_detail::cloning_base & e ) + { + exception_detail::clone_base const * c = e.clone(); + BOOST_ASSERT(c!=0); + return exception_ptr(c); + } + catch( + ... ) + { + } + try + { + throw; + } + 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(); + } + } + template exception_ptr - clone_exception( T const & e ) + copy_exception( T const & e ) { - if( boost::exception_detail::cloning_base const * cb = dynamic_cast(&e) ) - if( exception_detail::clone_base const * c = cb->clone() ) - return exception_ptr(c); - if( boost::exception const * be = dynamic_cast(&e) ) - return exception_ptr(exception_detail::make_clone(unknown_exception(*be))); - else - return exception_ptr(exception_detail::make_clone(unknown_exception())); + try + { + throw enable_current_exception(e); + } + catch( ... ) + { + return current_exception(); + } } inline diff --git a/include/boost/exception/enable_exception_cloning.hpp b/include/boost/exception/enable_current_exception.hpp similarity index 98% rename from include/boost/exception/enable_exception_cloning.hpp rename to include/boost/exception/enable_current_exception.hpp index 2e732f5..976a881 100644 --- a/include/boost/exception/enable_exception_cloning.hpp +++ b/include/boost/exception/enable_current_exception.hpp @@ -139,7 +139,7 @@ boost template exception_detail::clone_impl - enable_exception_cloning( T const & x ) + enable_current_exception( T const & x ) { return exception_detail::clone_impl(x); } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index a08d0fc..e6db8e0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -16,6 +16,7 @@ compile-fail to_string_fail.cpp ; #exception run cloning_test.cpp ; +run copy_exception_test.cpp ; run unknown_exception_test.cpp ; run exception_test.cpp ; run boost_error_info_test.cpp ; diff --git a/test/cloning_test.cpp b/test/cloning_test.cpp index 9052cc5..39bc756 100644 --- a/test/cloning_test.cpp +++ b/test/cloning_test.cpp @@ -17,12 +17,12 @@ main() { try { - throw boost::enable_exception_cloning(test_exception()); + throw boost::enable_current_exception(test_exception()); } catch( - std::exception & x ) + ... ) { - boost::exception_ptr p = boost::clone_exception(x); + boost::exception_ptr p = boost::current_exception(); try { rethrow_exception(p); diff --git a/test/copy_exception_test.cpp b/test/copy_exception_test.cpp new file mode 100644 index 0000000..b61d0ac --- /dev/null +++ b/test/copy_exception_test.cpp @@ -0,0 +1,34 @@ +//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 +#include + +struct +test_exception: + std::exception + { + }; + +int +main() + { + boost::exception_ptr p = boost::copy_exception(test_exception()); + try + { + rethrow_exception(p); + BOOST_TEST(false); + } + catch( + test_exception & ) + { + } + catch( + ... ) + { + BOOST_TEST(false); + } + return boost::report_errors(); + } diff --git a/test/throw_exception_test.cpp b/test/throw_exception_test.cpp index 7f5ddfd..197bfea 100644 --- a/test/throw_exception_test.cpp +++ b/test/throw_exception_test.cpp @@ -35,9 +35,9 @@ tester() BOOST_ASSERT(false); } catch( - std::exception & x ) + ... ) { - boost::exception_ptr p = boost::clone_exception(x); + boost::exception_ptr p = boost::current_exception(); try { rethrow_exception(p); @@ -55,11 +55,6 @@ tester() BOOST_TEST(false); } } - catch( - ... ) - { - BOOST_TEST(false); - } } int diff --git a/test/unknown_exception_test.cpp b/test/unknown_exception_test.cpp index 9e46727..37ff54e 100644 --- a/test/unknown_exception_test.cpp +++ b/test/unknown_exception_test.cpp @@ -40,9 +40,9 @@ main() throw_boost_exception(); } catch( - boost::exception & x ) + ... ) { - boost::exception_ptr ep=boost::clone_exception(x); + boost::exception_ptr ep=boost::current_exception(); try { rethrow_exception(ep); @@ -53,6 +53,20 @@ main() BOOST_TEST( 42==*boost::get_error_info(x) ); } catch( + ... ) + { + BOOST_TEST(false); + } + try + { + rethrow_exception(ep); + } + catch( + boost::exception & x ) + { + BOOST_TEST( 42==*boost::get_error_info(x) ); + } + catch( ... ) { BOOST_TEST(false); @@ -63,9 +77,9 @@ main() throw_unknown_exception(); } catch( - std::exception & x ) + ... ) { - boost::exception_ptr ep=boost::clone_exception(x); + boost::exception_ptr ep=boost::current_exception(); try { rethrow_exception(ep); @@ -75,6 +89,19 @@ main() { } catch( + ... ) + { + BOOST_TEST(false); + } + try + { + rethrow_exception(ep); + } + catch( + boost::exception & ) + { + } + catch( ... ) { BOOST_TEST(false);