diff --git a/build/Jamfile.v2 b/build/Jamfile.v2
deleted file mode 100644
index fb47659..0000000
--- a/build/Jamfile.v2
+++ /dev/null
@@ -1,14 +0,0 @@
-# Boost Exception Library build Jamfile
-#
-# Copyright (c) 2006-2009 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)
-
-project boost/exception
- : source-location ../src
- : requirements static
- ;
-
-lib boost_exception : clone_current_exception_non_intrusive.cpp ;
-boost-install boost_exception ;
diff --git a/include/boost/exception/detail/clone_current_exception.hpp b/include/boost/exception/detail/clone_current_exception.hpp
deleted file mode 100644
index 3d86deb..0000000
--- a/include/boost/exception/detail/clone_current_exception.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-//Copyright (c) 2006-2013 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_81522C0EB56511DFAB613DB0DFD72085
-#define UUID_81522C0EB56511DFAB613DB0DFD72085
-
-#include
-
-#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
-#pragma GCC system_header
-#endif
-#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
-#pragma warning(push,1)
-#endif
-
-#ifdef BOOST_NO_EXCEPTIONS
-# error This header requires exception handling to be enabled.
-#endif
-
-namespace
-boost
- {
- namespace
- exception_detail
- {
- class clone_base;
-
-#ifdef BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR
- int clone_current_exception_non_intrusive( clone_base const * & cloned );
-#endif
-
- namespace
- clone_current_exception_result
- {
- int const success=0;
- int const bad_alloc=1;
- int const bad_exception=2;
- int const not_supported=3;
- }
-
- inline
- int
- clone_current_exception( clone_base const * & cloned )
- {
-#ifdef BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR
- return clone_current_exception_non_intrusive(cloned);
-#else
- return clone_current_exception_result::not_supported;
-#endif
- }
- }
- }
-
-#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
-#pragma warning(pop)
-#endif
-#endif
diff --git a/include/boost/exception/detail/error_info_impl.hpp b/include/boost/exception/detail/error_info_impl.hpp
index a3063b2..2c85d3c 100644
--- a/include/boost/exception/detail/error_info_impl.hpp
+++ b/include/boost/exception/detail/error_info_impl.hpp
@@ -32,8 +32,7 @@ boost
public:
virtual std::string name_value_string() const = 0;
-
- protected:
+ virtual error_info_base * clone() const = 0;
virtual
~error_info_base() throw()
@@ -47,6 +46,11 @@ boost
error_info:
public exception_detail::error_info_base
{
+ error_info_base *
+ clone() const
+ {
+ return new error_info(*this);
+ }
public:
typedef T value_type;
error_info( value_type const & v ):
diff --git a/include/boost/exception/detail/exception_ptr.hpp b/include/boost/exception/detail/exception_ptr.hpp
index 5aa4773..24c4fba 100644
--- a/include/boost/exception/detail/exception_ptr.hpp
+++ b/include/boost/exception/detail/exception_ptr.hpp
@@ -14,7 +14,6 @@
#include
#include
#include
-#include
#ifndef BOOST_NO_RTTI
#include
#endif
@@ -303,131 +302,101 @@ boost
exception_ptr
current_exception_impl()
{
- exception_detail::clone_base const * e=0;
- switch(
- exception_detail::clone_current_exception(e) )
+ try
{
- case exception_detail::clone_current_exception_result::
- success:
- {
- BOOST_ASSERT(e!=0);
- return exception_ptr(shared_ptr(e));
- }
- case exception_detail::clone_current_exception_result::
- bad_alloc:
- {
- BOOST_ASSERT(!e);
- return exception_detail::exception_ptr_static_exception_object::e;
- }
- case exception_detail::clone_current_exception_result::
- bad_exception:
- {
- BOOST_ASSERT(!e);
- return exception_detail::exception_ptr_static_exception_object::e;
- }
- default:
- BOOST_ASSERT(0);
- case exception_detail::clone_current_exception_result::
- not_supported:
- {
- BOOST_ASSERT(!e);
- try
- {
- throw;
- }
- catch(
- exception_detail::clone_base & e )
- {
- return exception_ptr(shared_ptr(e.clone()));
- }
- catch(
- std::domain_error & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::invalid_argument & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::length_error & 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::range_error & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::overflow_error & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::underflow_error & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::ios_base::failure & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::runtime_error & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
- catch(
- std::bad_alloc & e )
- {
- return exception_detail::current_exception_std_exception(e);
- }
+ throw;
+ }
+ catch(
+ exception_detail::clone_base & e )
+ {
+ return exception_ptr(shared_ptr(e.clone()));
+ }
+ catch(
+ std::domain_error & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::invalid_argument & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::length_error & 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::range_error & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::overflow_error & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::underflow_error & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::ios_base::failure & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::runtime_error & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::bad_alloc & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
#ifndef BOOST_NO_TYPEID
- 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_cast & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
+ catch(
+ std::bad_typeid & e )
+ {
+ return exception_detail::current_exception_std_exception(e);
+ }
#endif
- 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(
+ 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();
}
}
}
diff --git a/include/boost/exception/info.hpp b/include/boost/exception/info.hpp
index c99578a..f7ac50e 100644
--- a/include/boost/exception/info.hpp
+++ b/include/boost/exception/info.hpp
@@ -142,7 +142,11 @@ boost
refcount_ptr p;
error_info_container_impl * c=new error_info_container_impl;
p.adopt(c);
- c->info_ = info_;
+ for( error_info_map::const_iterator i=info_.begin(),e=info_.end(); i!=e; ++i )
+ {
+ shared_ptr cp(i->second->clone());
+ c->info_.insert(std::make_pair(i->first,cp));
+ }
return p;
}
};
diff --git a/src/clone_current_exception_non_intrusive.cpp b/src/clone_current_exception_non_intrusive.cpp
deleted file mode 100644
index 1710cd7..0000000
--- a/src/clone_current_exception_non_intrusive.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-//Copyright (c) 2006-2009 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)
-
-//This MSVC-specific cpp file implements non-intrusive cloning of exception objects.
-//Based on an exception_ptr implementation by Anthony Williams.
-
-#ifdef BOOST_NO_EXCEPTIONS
-#error This file requires exception handling to be enabled.
-#endif
-
-#include
-
-#if defined(BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR) && defined(_MSC_VER) && defined(_M_IX86) && !defined(_M_X64)
-
-//Non-intrusive cloning support implemented below, only for MSVC versions mentioned above.
-//Thanks Anthony Williams!
-
-#include
-#include
-#ifndef BOOST_NO_RTTI
-#include
-#endif
-#include
-#include
-
-namespace
- {
- unsigned const exception_maximum_parameters=15;
- unsigned const exception_noncontinuable=1;
-
-#if _MSC_VER==1310
- int const exception_info_offset=0x74;
-#elif (_MSC_VER==1400 || _MSC_VER==1500)
- int const exception_info_offset=0x80;
-#else
- int const exception_info_offset=-1;
-#endif
-
- struct
- exception_record
- {
- unsigned long ExceptionCode;
- unsigned long ExceptionFlags;
- exception_record * ExceptionRecord;
- void * ExceptionAddress;
- unsigned long NumberParameters;
- ULONG_PTR ExceptionInformation[exception_maximum_parameters];
- };
-
- struct
- exception_pointers
- {
- exception_record * ExceptionRecord;
- void * ContextRecord;
- };
-
- unsigned const cpp_exception_code=0xE06D7363;
- unsigned const cpp_exception_magic_flag=0x19930520;
- unsigned const cpp_exception_parameter_count=3;
-
- struct
- dummy_exception_type
- {
- };
-
- typedef int(dummy_exception_type::*normal_copy_constructor_ptr)(void * src);
- typedef int(dummy_exception_type::*copy_constructor_with_virtual_base_ptr)(void * src,void * dst);
- typedef void (dummy_exception_type::*destructor_ptr)();
-
- union
- cpp_copy_constructor
- {
- normal_copy_constructor_ptr normal_copy_constructor;
- copy_constructor_with_virtual_base_ptr copy_constructor_with_virtual_base;
- };
-
- enum
- cpp_type_flags
- {
- class_is_simple_type=1,
- class_has_virtual_base=4
- };
-
- struct
- cpp_type_info
- {
- unsigned flags;
-#ifndef BOOST_NO_RTTI
- void const * type_info;
-#else
- std::type_info * type_info;
-#endif
- int this_offset;
- int vbase_descr;
- int vbase_offset;
- unsigned long size;
- cpp_copy_constructor copy_constructor;
- };
-
- struct
- cpp_type_info_table
- {
- unsigned count;
- const cpp_type_info * info[1];
- };
-
- struct
- cpp_exception_type
- {
- unsigned flags;
- destructor_ptr destructor;
- void(*custom_handler)();
- cpp_type_info_table const * type_info_table;
- };
-
- struct
- exception_object_deleter
- {
- cpp_exception_type const & et_;
-
- exception_object_deleter( cpp_exception_type const & et ):
- et_(et)
- {
- }
-
- void
- operator()( void * obj )
- {
- BOOST_ASSERT(obj!=0);
- dummy_exception_type * dummy_exception_ptr=reinterpret_cast(obj);
- (dummy_exception_ptr->*(et_.destructor))();
- free(obj);
- }
- };
-
- cpp_type_info const &
- get_cpp_type_info( cpp_exception_type const & et )
- {
- cpp_type_info const * ti = et.type_info_table->info[0];
- BOOST_ASSERT(ti!=0);
- return *ti;
- }
-
- void
- copy_msvc_exception( void * dst, void * src, cpp_type_info const & ti )
- {
- if( !(ti.flags & class_is_simple_type) && ti.copy_constructor.normal_copy_constructor )
- {
- dummy_exception_type * dummy_exception_ptr = reinterpret_cast(dst);
- if( ti.flags & class_has_virtual_base )
- (dummy_exception_ptr->*(ti.copy_constructor.copy_constructor_with_virtual_base))(src,dst);
- else
- (dummy_exception_ptr->*(ti.copy_constructor.normal_copy_constructor))(src);
- }
- else
- memmove(dst,src,ti.size);
- }
-
- boost::shared_ptr
- clone_msvc_exception( void * src, cpp_exception_type const & et )
- {
- assert(src!=0);
- cpp_type_info const & ti=get_cpp_type_info(et);
- if( void * dst = malloc(ti.size) )
- {
- try
- {
- copy_msvc_exception(dst,src,ti);
- }
- catch(
- ... )
- {
- free(dst);
- throw;
- }
- return boost::shared_ptr(dst,exception_object_deleter(et));
- }
- else
- throw std::bad_alloc();
- }
-
- class
- cloned_exception:
- public boost::exception_detail::clone_base
- {
- cloned_exception( cloned_exception const & );
- cloned_exception & operator=( cloned_exception const & );
-
- cpp_exception_type const & et_;
- boost::shared_ptr exc_;
-
- public:
-
- cloned_exception( void * exc, cpp_exception_type const & et ):
- et_(et),
- exc_(clone_msvc_exception(exc,et_))
- {
- }
-
- ~cloned_exception() throw()
- {
- }
-
- boost::exception_detail::clone_base const *
- clone() const
- {
- return new cloned_exception(exc_.get(),et_);
- }
-
- void
- rethrow() const
- {
- cpp_type_info const & ti=get_cpp_type_info(et_);
- void * dst = _alloca(ti.size);
- copy_msvc_exception(dst,exc_.get(),ti);
- ULONG_PTR args[cpp_exception_parameter_count];
- args[0]=cpp_exception_magic_flag;
- args[1]=reinterpret_cast(dst);
- args[2]=reinterpret_cast(&et_);
- RaiseException(cpp_exception_code,EXCEPTION_NONCONTINUABLE,cpp_exception_parameter_count,args);
- }
- };
-
- bool
- is_cpp_exception( EXCEPTION_RECORD const * record )
- {
- return record &&
- (record->ExceptionCode==cpp_exception_code) &&
- (record->NumberParameters==cpp_exception_parameter_count) &&
- (record->ExceptionInformation[0]==cpp_exception_magic_flag);
- }
-
- unsigned long
- exception_cloning_filter( int & result, boost::exception_detail::clone_base const * & ptr, void * info_ )
- {
- BOOST_ASSERT(exception_info_offset>=0);
- BOOST_ASSERT(info_!=0);
- EXCEPTION_POINTERS * info=reinterpret_cast(info_);
- EXCEPTION_RECORD * record=info->ExceptionRecord;
- if( is_cpp_exception(record) )
- {
- if( !record->ExceptionInformation[2] )
- record = *reinterpret_cast(reinterpret_cast(_errno())+exception_info_offset);
- if( is_cpp_exception(record) && record->ExceptionInformation[2] )
- try
- {
- ptr = new cloned_exception(
- reinterpret_cast(record->ExceptionInformation[1]),
- *reinterpret_cast(record->ExceptionInformation[2]));
- result = boost::exception_detail::clone_current_exception_result::success;
- }
- catch(
- std::bad_alloc & )
- {
- result = boost::exception_detail::clone_current_exception_result::bad_alloc;
- }
- catch(
- ... )
- {
- result = boost::exception_detail::clone_current_exception_result::bad_exception;
- }
- }
- return EXCEPTION_EXECUTE_HANDLER;
- }
- }
-
-namespace
-boost
- {
- namespace
- exception_detail
- {
- int
- clone_current_exception_non_intrusive( clone_base const * & cloned )
- {
- BOOST_ASSERT(!cloned);
- int result = clone_current_exception_result::not_supported;
- if( exception_info_offset>=0 )
- {
- clone_base const * ptr=0;
- __try
- {
- throw;
- }
- __except(exception_cloning_filter(result,ptr,GetExceptionInformation()))
- {
- }
- if( result==clone_current_exception_result::success )
- cloned=ptr;
- }
- BOOST_ASSERT(result!=clone_current_exception_result::success || cloned);
- return result;
- }
- }
- }
-
-#else
-
-//On all other compilers, return clone_current_exception_result::not_supported.
-//On such platforms, only the intrusive enable_current_exception() cloning will work.
-
-#include
-
-namespace
-boost
- {
- namespace
- exception_detail
- {
- int
- clone_current_exception_non_intrusive( clone_base const * & )
- {
- return clone_current_exception_result::not_supported;
- }
- }
- }
-
-#endif
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index 53d277f..97bc3ec 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -44,7 +44,6 @@ run refcount_ptr_test.cpp ;
run current_exception_cast_test.cpp ;
run no_exceptions_test.cpp : : : off ;
run errinfos_test.cpp ;
-run exception_ptr_test.cpp/BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR ../../thread/src/tss_null.cpp /boost/exception /boost//thread : : : multi : non_intrusive_exception_ptr_test ;
run exception_ptr_test.cpp ../../thread/src/tss_null.cpp /boost//thread : : : multi ;
run N3757_test.cpp ;
diff --git a/test/cloning_test.cpp b/test/cloning_test.cpp
index c5a4ae9..70010aa 100644
--- a/test/cloning_test.cpp
+++ b/test/cloning_test.cpp
@@ -395,11 +395,6 @@ main()
BOOST_TEST(false);
}
catch(
- derives_std_exception & )
- {
- //Yay! Non-intrusive cloning supported!
- }
- catch(
boost::unknown_exception & e )
{
#ifndef BOOST_NO_RTTI
@@ -449,14 +444,6 @@ main()
BOOST_TEST(false);
}
catch(
- derives_std_boost_exception & x )
- {
- //Yay! Non-intrusive cloning supported!
- BOOST_TEST(boost::get_error_info(x));
- if( int const * p=boost::get_error_info(x) )
- BOOST_TEST(*p==42);
- }
- catch(
boost::unknown_exception & x )
{
BOOST_TEST(boost::get_error_info(x));
@@ -518,14 +505,6 @@ main()
BOOST_TEST(false);
}
catch(
- derives_boost_exception & x )
- {
- //Yay! Non-intrusive cloning supported!
- BOOST_TEST(boost::get_error_info(x));
- if( int const * p=boost::get_error_info(x) )
- BOOST_TEST(*p==42);
- }
- catch(
boost::unknown_exception & x )
{
BOOST_TEST(boost::get_error_info(x));
diff --git a/test/exception_ptr_test.cpp b/test/exception_ptr_test.cpp
index 193fabc..4c626c5 100644
--- a/test/exception_ptr_test.cpp
+++ b/test/exception_ptr_test.cpp
@@ -121,9 +121,42 @@ check( boost::shared_ptr const & t )
}
}
+void
+test_deep_copy()
+ {
+ int const * p1=0;
+ boost::exception_ptr p;
+ try
+ {
+ BOOST_THROW_EXCEPTION(exc() << answer(42));
+ BOOST_ERROR("BOOST_THROW_EXCEPTION didn't throw");
+ }
+ catch(
+ exc & e )
+ {
+ p1=boost::get_error_info(e);
+ p=boost::current_exception();
+ }
+ BOOST_TEST(p1!=0);
+ BOOST_TEST(p);
+ try
+ {
+ boost::rethrow_exception(p);
+ BOOST_ERROR("rethrow_exception didn't throw");
+ }
+ catch(
+ exc & e )
+ {
+ int const * p2=boost::get_error_info(e);
+ BOOST_TEST(p2!=0 && *p2==42);
+ BOOST_TEST(p2!=p1);
+ }
+ }
+
int
main()
{
+ test_deep_copy();
BOOST_TEST(++exc_count==1);
try
{
diff --git a/test/unknown_exception_test.cpp b/test/unknown_exception_test.cpp
index bf474ba..4918b44 100644
--- a/test/unknown_exception_test.cpp
+++ b/test/unknown_exception_test.cpp
@@ -62,15 +62,6 @@ main()
BOOST_TEST(false);
}
catch(
- boost::exception & x )
- {
- //Yay! Non-intrusive cloning supported!
- if( int const * d=boost::get_error_info(x) )
- BOOST_TEST( 42==*d );
- else
- BOOST_TEST(false);
- }
- catch(
... )
{
BOOST_TEST(false);
@@ -110,11 +101,6 @@ main()
{
}
catch(
- std::exception & )
- {
- //Yay! Non-intrusive cloning supported!
- }
- catch(
... )
{
BOOST_TEST(false);
@@ -128,11 +114,6 @@ main()
{
}
catch(
- std::exception & )
- {
- //Yay! Non-intrusive cloning supported!
- }
- catch(
... )
{
BOOST_TEST(false);