forked from boostorg/exception
restoring non-intrusive exception_ptr code
This commit is contained in:
14
build/Jamfile.v2
Normal file
14
build/Jamfile.v2
Normal file
@ -0,0 +1,14 @@
|
||||
# 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 <link>static
|
||||
;
|
||||
|
||||
lib boost_exception : clone_current_exception_non_intrusive.cpp ;
|
||||
boost-install boost_exception ;
|
56
include/boost/exception/detail/clone_current_exception.hpp
Normal file
56
include/boost/exception/detail/clone_current_exception.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
//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
|
||||
#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
|
@ -13,6 +13,7 @@
|
||||
#include <boost/exception/exception.hpp>
|
||||
#include <boost/exception/info.hpp>
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#include <boost/exception/detail/clone_current_exception.hpp>
|
||||
#include <boost/exception/detail/type_info.hpp>
|
||||
#ifndef BOOST_NO_RTTI
|
||||
#include <boost/core/demangle.hpp>
|
||||
@ -302,101 +303,131 @@ boost
|
||||
exception_ptr
|
||||
current_exception_impl()
|
||||
{
|
||||
try
|
||||
exception_detail::clone_base const * e=0;
|
||||
switch(
|
||||
exception_detail::clone_current_exception(e) )
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch(
|
||||
exception_detail::clone_base & e )
|
||||
{
|
||||
return exception_ptr(shared_ptr<exception_detail::clone_base const>(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);
|
||||
}
|
||||
#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();
|
||||
case exception_detail::clone_current_exception_result::
|
||||
success:
|
||||
{
|
||||
BOOST_ASSERT(e!=0);
|
||||
return exception_ptr(shared_ptr<exception_detail::clone_base const>(e));
|
||||
}
|
||||
case exception_detail::clone_current_exception_result::
|
||||
bad_alloc:
|
||||
{
|
||||
BOOST_ASSERT(!e);
|
||||
return exception_detail::exception_ptr_static_exception_object<bad_alloc_>::e;
|
||||
}
|
||||
case exception_detail::clone_current_exception_result::
|
||||
bad_exception:
|
||||
{
|
||||
BOOST_ASSERT(!e);
|
||||
return exception_detail::exception_ptr_static_exception_object<bad_exception_>::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<exception_detail::clone_base const>(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);
|
||||
}
|
||||
#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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
320
src/clone_current_exception_non_intrusive.cpp
Normal file
320
src/clone_current_exception_non_intrusive.cpp
Normal file
@ -0,0 +1,320 @@
|
||||
//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 <boost/exception/detail/clone_current_exception.hpp>
|
||||
|
||||
#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 <boost/exception/exception.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#ifndef BOOST_NO_RTTI
|
||||
#include <typeinfo>
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <malloc.h>
|
||||
|
||||
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<dummy_exception_type *>(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<dummy_exception_type *>(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<void>
|
||||
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<void>(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<void> 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<ULONG_PTR>(dst);
|
||||
args[2]=reinterpret_cast<ULONG_PTR>(&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<EXCEPTION_POINTERS *>(info_);
|
||||
EXCEPTION_RECORD * record=info->ExceptionRecord;
|
||||
if( is_cpp_exception(record) )
|
||||
{
|
||||
if( !record->ExceptionInformation[2] )
|
||||
record = *reinterpret_cast<EXCEPTION_RECORD * *>(reinterpret_cast<char *>(_errno())+exception_info_offset);
|
||||
if( is_cpp_exception(record) && record->ExceptionInformation[2] )
|
||||
try
|
||||
{
|
||||
ptr = new cloned_exception(
|
||||
reinterpret_cast<void *>(record->ExceptionInformation[1]),
|
||||
*reinterpret_cast<cpp_exception_type const *>(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 <boost/config.hpp>
|
||||
|
||||
namespace
|
||||
boost
|
||||
{
|
||||
namespace
|
||||
exception_detail
|
||||
{
|
||||
int
|
||||
clone_current_exception_non_intrusive( clone_base const * & )
|
||||
{
|
||||
return clone_current_exception_result::not_supported;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -44,6 +44,7 @@ run refcount_ptr_test.cpp ;
|
||||
run current_exception_cast_test.cpp ;
|
||||
run no_exceptions_test.cpp : : : <exception-handling>off ;
|
||||
run errinfos_test.cpp ;
|
||||
run exception_ptr_test.cpp/<define>BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR ../../thread/src/tss_null.cpp /boost/exception /boost//thread : : : <threading>multi : non_intrusive_exception_ptr_test ;
|
||||
run exception_ptr_test.cpp ../../thread/src/tss_null.cpp /boost//thread : : : <threading>multi ;
|
||||
run N3757_test.cpp ;
|
||||
|
||||
|
@ -395,6 +395,11 @@ main()
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch(
|
||||
derives_std_exception & )
|
||||
{
|
||||
//Yay! Non-intrusive cloning supported!
|
||||
}
|
||||
catch(
|
||||
boost::unknown_exception & e )
|
||||
{
|
||||
#ifndef BOOST_NO_RTTI
|
||||
@ -444,6 +449,14 @@ main()
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch(
|
||||
derives_std_boost_exception & x )
|
||||
{
|
||||
//Yay! Non-intrusive cloning supported!
|
||||
BOOST_TEST(boost::get_error_info<my_info>(x));
|
||||
if( int const * p=boost::get_error_info<my_info>(x) )
|
||||
BOOST_TEST(*p==42);
|
||||
}
|
||||
catch(
|
||||
boost::unknown_exception & x )
|
||||
{
|
||||
BOOST_TEST(boost::get_error_info<my_info>(x));
|
||||
@ -505,6 +518,14 @@ main()
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch(
|
||||
derives_boost_exception & x )
|
||||
{
|
||||
//Yay! Non-intrusive cloning supported!
|
||||
BOOST_TEST(boost::get_error_info<my_info>(x));
|
||||
if( int const * p=boost::get_error_info<my_info>(x) )
|
||||
BOOST_TEST(*p==42);
|
||||
}
|
||||
catch(
|
||||
boost::unknown_exception & x )
|
||||
{
|
||||
BOOST_TEST(boost::get_error_info<my_info>(x));
|
||||
|
@ -123,40 +123,40 @@ check( boost::shared_ptr<thread_handle> 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<answer>(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<answer>(e);
|
||||
BOOST_TEST(p2!=0 && *p2==42);
|
||||
BOOST_TEST(p2!=p1);
|
||||
}
|
||||
}
|
||||
{
|
||||
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<answer>(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<answer>(e);
|
||||
BOOST_TEST(p2!=0 && *p2==42);
|
||||
BOOST_TEST(p2!=p1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test_deep_copy();
|
||||
test_deep_copy();
|
||||
BOOST_TEST(++exc_count==1);
|
||||
try
|
||||
{
|
||||
|
@ -62,6 +62,15 @@ main()
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch(
|
||||
boost::exception & x )
|
||||
{
|
||||
//Yay! Non-intrusive cloning supported!
|
||||
if( int const * d=boost::get_error_info<test>(x) )
|
||||
BOOST_TEST( 42==*d );
|
||||
else
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch(
|
||||
... )
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
@ -101,6 +110,11 @@ main()
|
||||
{
|
||||
}
|
||||
catch(
|
||||
std::exception & )
|
||||
{
|
||||
//Yay! Non-intrusive cloning supported!
|
||||
}
|
||||
catch(
|
||||
... )
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
@ -114,6 +128,11 @@ main()
|
||||
{
|
||||
}
|
||||
catch(
|
||||
std::exception & )
|
||||
{
|
||||
//Yay! Non-intrusive cloning supported!
|
||||
}
|
||||
catch(
|
||||
... )
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
|
Reference in New Issue
Block a user