diff options
Diffstat (limited to 'src/boost/libs/exception')
70 files changed, 4144 insertions, 0 deletions
diff --git a/src/boost/libs/exception/CMakeLists.txt b/src/boost/libs/exception/CMakeLists.txt new file mode 100644 index 00000000..db7251bc --- /dev/null +++ b/src/boost/libs/exception/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright 2019 Mike Dev +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt +# +# NOTE: CMake support for Boost.Exception is currently experimental at best +# and the interface is likely to change in the future + +cmake_minimum_required( VERSION 3.5 ) +project( BoostException LANGUAGES CXX ) + +# We treat Boost.Exception as header only for now. +# See https://github.com/boostorg/exception/pull/17 +# for more information. + +add_library( boost_exception INTERFACE ) +add_library( Boost::exception ALIAS boost_exception ) + +target_include_directories( boost_exception INTERFACE include ) + +target_link_libraries( boost_exception + INTERFACE + Boost::assert + Boost::config + Boost::core + Boost::smart_ptr + Boost::throw_exception + Boost::tuple + Boost::type_traits +) + diff --git a/src/boost/libs/exception/build/Jamfile.v2 b/src/boost/libs/exception/build/Jamfile.v2 new file mode 100644 index 00000000..fb47659c --- /dev/null +++ b/src/boost/libs/exception/build/Jamfile.v2 @@ -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 ; diff --git a/src/boost/libs/exception/example/Jamfile b/src/boost/libs/exception/example/Jamfile new file mode 100644 index 00000000..44e18bfd --- /dev/null +++ b/src/boost/libs/exception/example/Jamfile @@ -0,0 +1,16 @@ +# Boost Exception Library example 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) + +exe example_io : example_io.cpp ; +obj error_info_1 : error_info_1.cpp ; +obj error_info_2 : error_info_2.cpp ; +obj cloning_1 : cloning_1.cpp ; +obj cloning_2 : cloning_2.cpp : <threading>multi ; +obj info_tuple : info_tuple.cpp ; +obj enable_error_info : enable_error_info.cpp ; +obj logging : logging.cpp ; +obj errinfos : errinfos.cpp ; diff --git a/src/boost/libs/exception/example/cloning_1.cpp b/src/boost/libs/exception/example/cloning_1.cpp new file mode 100644 index 00000000..16103a9d --- /dev/null +++ b/src/boost/libs/exception/example/cloning_1.cpp @@ -0,0 +1,21 @@ +//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 example shows how to enable cloning when throwing a boost::exception. + +#include <boost/exception/info.hpp> +#include <boost/exception/errinfo_errno.hpp> +#include <stdio.h> +#include <errno.h> + +struct file_read_error: virtual boost::exception { }; + +void +file_read( FILE * f, void * buffer, size_t size ) + { + if( size!=fread(buffer,1,size,f) ) + throw boost::enable_current_exception(file_read_error()) << + boost::errinfo_errno(errno); + } diff --git a/src/boost/libs/exception/example/cloning_2.cpp b/src/boost/libs/exception/example/cloning_2.cpp new file mode 100644 index 00000000..79b56cbb --- /dev/null +++ b/src/boost/libs/exception/example/cloning_2.cpp @@ -0,0 +1,39 @@ +//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 example shows how to transport cloning-enabled boost::exceptions between threads. + +#include <boost/exception_ptr.hpp> +#include <boost/thread.hpp> +#include <boost/bind.hpp> + +void do_work(); //throws cloning-enabled boost::exceptions + +void +worker_thread( boost::exception_ptr & error ) + { + try + { + do_work(); + error = boost::exception_ptr(); + } + catch( + ... ) + { + error = boost::current_exception(); + } + } + +// ...continued + +void +work() + { + boost::exception_ptr error; + boost::thread t( boost::bind(worker_thread,boost::ref(error)) ); + t.join(); + if( error ) + boost::rethrow_exception(error); + } diff --git a/src/boost/libs/exception/example/enable_error_info.cpp b/src/boost/libs/exception/example/enable_error_info.cpp new file mode 100644 index 00000000..5f9a6914 --- /dev/null +++ b/src/boost/libs/exception/example/enable_error_info.cpp @@ -0,0 +1,35 @@ +//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 example shows how to throw exception objects that support +//transporting of arbitrary data to the catch site, even for types +//that do not derive from boost::exception. + +#include <boost/exception/all.hpp> +#include <stdexcept> + +typedef boost::error_info<struct tag_std_range_min,size_t> std_range_min; +typedef boost::error_info<struct tag_std_range_max,size_t> std_range_max; +typedef boost::error_info<struct tag_std_range_index,size_t> std_range_index; + +template <class T> +class +my_container + { + public: + + size_t size() const; + + T const & + operator[]( size_t i ) const + { + if( i > size() ) + throw boost::enable_error_info(std::range_error("Index out of range")) << + std_range_min(0) << + std_range_max(size()) << + std_range_index(i); + //.... + } + }; diff --git a/src/boost/libs/exception/example/errinfos.cpp b/src/boost/libs/exception/example/errinfos.cpp new file mode 100644 index 00000000..2b3cff1b --- /dev/null +++ b/src/boost/libs/exception/example/errinfos.cpp @@ -0,0 +1,53 @@ +//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 example demonstrates the intended use of various commonly used +//error_info typedefs provided by Boost Exception. + +#include <boost/exception/errinfo_api_function.hpp> +#include <boost/exception/errinfo_at_line.hpp> +#include <boost/exception/errinfo_errno.hpp> +#include <boost/exception/errinfo_file_handle.hpp> +#include <boost/exception/errinfo_file_name.hpp> +#include <boost/exception/errinfo_file_open_mode.hpp> +#include <boost/exception/info.hpp> +#include <boost/throw_exception.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <stdio.h> +#include <errno.h> +#include <exception> + +struct error : virtual std::exception, virtual boost::exception { }; +struct file_error : virtual error { }; +struct file_open_error: virtual file_error { }; +struct file_read_error: virtual file_error { }; + +boost::shared_ptr<FILE> +open_file( char const * file, char const * mode ) + { + if( FILE * f=fopen(file,mode) ) + return boost::shared_ptr<FILE>(f,fclose); + else + BOOST_THROW_EXCEPTION( + file_open_error() << + boost::errinfo_api_function("fopen") << + boost::errinfo_errno(errno) << + boost::errinfo_file_name(file) << + boost::errinfo_file_open_mode(mode) ); + } + +size_t +read_file( boost::shared_ptr<FILE> const & f, void * buf, size_t size ) + { + size_t nr=fread(buf,1,size,f.get()); + if( ferror(f.get()) ) + BOOST_THROW_EXCEPTION( + file_read_error() << + boost::errinfo_api_function("fread") << + boost::errinfo_errno(errno) << + boost::errinfo_file_handle(f) ); + return nr; + } diff --git a/src/boost/libs/exception/example/error_info_1.cpp b/src/boost/libs/exception/example/error_info_1.cpp new file mode 100644 index 00000000..05339e91 --- /dev/null +++ b/src/boost/libs/exception/example/error_info_1.cpp @@ -0,0 +1,35 @@ +//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 example shows how to add data to boost::exception objects at the +//point of the throw, and how to retrieve that data at the point of the catch. + +#include <boost/exception/all.hpp> +#include <iostream> + +typedef boost::error_info<struct tag_my_info,int> my_info; //(1) + +struct my_error: virtual boost::exception, virtual std::exception { }; //(2) + +void +f() + { + throw my_error() << my_info(42); //(3) + } + +void +g() + { + try + { + f(); + } + catch( + my_error & x ) + { + if( int const * mi=boost::get_error_info<my_info>(x) ) + std::cerr << "My info: " << *mi; + } + } diff --git a/src/boost/libs/exception/example/error_info_2.cpp b/src/boost/libs/exception/example/error_info_2.cpp new file mode 100644 index 00000000..dea512a9 --- /dev/null +++ b/src/boost/libs/exception/example/error_info_2.cpp @@ -0,0 +1,45 @@ +//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 example shows how to add arbitrary data to active exception objects. + +#include <boost/exception/all.hpp> +#include <boost/shared_ptr.hpp> +#include <stdio.h> +#include <errno.h> + +// + +struct file_read_error: virtual boost::exception { }; + +void +file_read( FILE * f, void * buffer, size_t size ) + { + if( size!=fread(buffer,1,size,f) ) + throw file_read_error() << boost::errinfo_errno(errno); + } + +// + +boost::shared_ptr<FILE> file_open( char const * file_name, char const * mode ); +void file_read( FILE * f, void * buffer, size_t size ); + +void +parse_file( char const * file_name ) + { + boost::shared_ptr<FILE> f = file_open(file_name,"rb"); + assert(f); + try + { + char buf[1024]; + file_read( f.get(), buf, sizeof(buf) ); + } + catch( + boost::exception & e ) + { + e << boost::errinfo_file_name(file_name); + throw; + } + } diff --git a/src/boost/libs/exception/example/example_io.cpp b/src/boost/libs/exception/example/example_io.cpp new file mode 100644 index 00000000..f4893328 --- /dev/null +++ b/src/boost/libs/exception/example/example_io.cpp @@ -0,0 +1,209 @@ +//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 program simulates errors on copying simple data files. It demonstrates +//typical Boost Exception usage. + +//The output from this program can vary depending on the platform. + +#include <boost/throw_exception.hpp> +#include <boost/exception/info.hpp> +#include <boost/exception/get_error_info.hpp> +#include <boost/exception/diagnostic_information.hpp> +#include <boost/exception/errinfo_file_open_mode.hpp> +#include <boost/exception/errinfo_file_handle.hpp> +#include <boost/exception/errinfo_file_name.hpp> +#include <boost/exception/errinfo_api_function.hpp> +#include <boost/exception/errinfo_errno.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <iostream> + +typedef boost::error_info<struct tag_file_name_src,std::string> errinfo_src_file_name; +typedef boost::error_info<struct tag_file_name_dst,std::string> errinfo_dst_file_name; + +char const data[] = "example"; +size_t const data_size = sizeof(data); + +class +error: //Base for all exception objects we throw. + public virtual std::exception, + public virtual boost::exception + { + public: + + char const * + what() const BOOST_NOEXCEPT_OR_NOTHROW + { + return "example_io error"; + } + + protected: + + ~error() BOOST_NOEXCEPT_OR_NOTHROW + { + } + }; + +struct open_error: virtual error { }; +struct read_error: virtual error { }; +struct write_error: virtual error { }; +struct fopen_error: virtual open_error { }; +struct fread_error: virtual read_error { }; +struct fwrite_error: virtual write_error { }; + +boost::shared_ptr<FILE> +my_fopen( char const * name, char const * mode ) + { + if( FILE * f = ::fopen(name,mode) ) + return boost::shared_ptr<FILE>(f,fclose); + else + BOOST_THROW_EXCEPTION(fopen_error() << + boost::errinfo_errno (errno) << + boost::errinfo_file_name(name) << + boost::errinfo_file_open_mode(mode) << + boost::errinfo_api_function("fopen")); + } + +void +my_fread( void * buffer, size_t size, size_t count, boost::shared_ptr<FILE> const & stream ) + { + assert(stream); + if( count!=fread(buffer,size,count,stream.get()) || ferror(stream.get()) ) + BOOST_THROW_EXCEPTION(fread_error() << + boost::errinfo_api_function("fread") << + boost::errinfo_errno(errno) << + boost::errinfo_file_handle(boost::weak_ptr<FILE>(stream))); + } + +void +my_fwrite( void const * buffer, size_t size, size_t count, boost::shared_ptr<FILE> const & stream ) + { + assert(stream); + if( count!=fwrite(buffer,size,count,stream.get()) || ferror(stream.get()) ) + BOOST_THROW_EXCEPTION(fwrite_error() << + boost::errinfo_api_function("fwrite") << + boost::errinfo_errno(errno) << + boost::errinfo_file_handle(boost::weak_ptr<FILE>(stream))); + } + +void +reset_file( char const * file_name ) + { + (void) my_fopen(file_name,"wb"); + } + +void +create_data( char const * file_name ) + { + boost::shared_ptr<FILE> f = my_fopen(file_name,"wb"); + my_fwrite( data, 1, data_size, f ); + } + +void +copy_data( char const * src_file_name, char const * dst_file_name ) + { + boost::shared_ptr<FILE> src = my_fopen(src_file_name,"rb"); + boost::shared_ptr<FILE> dst = my_fopen(dst_file_name,"wb"); + try + { + char buffer[data_size]; + my_fread( buffer, 1, data_size, src ); + my_fwrite( buffer, 1, data_size, dst ); + } + catch( + boost::exception & x ) + { + if( boost::weak_ptr<FILE> const * f=boost::get_error_info<boost::errinfo_file_handle>(x) ) + if( boost::shared_ptr<FILE> fs = f->lock() ) + { + if( fs==src ) + x << boost::errinfo_file_name(src_file_name); + else if( fs==dst ) + x << boost::errinfo_file_name(dst_file_name); + } + x << + errinfo_src_file_name(src_file_name) << + errinfo_dst_file_name(dst_file_name); + throw; + } + } + +void +dump_copy_info( boost::exception const & x ) + { + if( std::string const * src = boost::get_error_info<errinfo_src_file_name>(x) ) + std::cerr << "Source file name: " << *src << "\n"; + if( std::string const * dst = boost::get_error_info<errinfo_dst_file_name>(x) ) + std::cerr << "Destination file name: " << *dst << "\n"; + } + +void +dump_file_info( boost::exception const & x ) + { + if( std::string const * fn = boost::get_error_info<boost::errinfo_file_name>(x) ) + std::cerr << "File name: " << *fn << "\n"; + } + +void +dump_clib_info( boost::exception const & x ) + { + if( int const * err=boost::get_error_info<boost::errinfo_errno>(x) ) + std::cerr << "OS error: " << *err << "\n"; + if( char const * const * fn=boost::get_error_info<boost::errinfo_api_function>(x) ) + std::cerr << "Failed function: " << *fn << "\n"; + } + +void +dump_all_info( boost::exception const & x ) + { + std::cerr << "-------------------------------------------------\n"; + dump_copy_info(x); + dump_file_info(x); + dump_clib_info(x); + std::cerr << "\nOutput from diagnostic_information():\n"; + std::cerr << diagnostic_information(x); + } + +int +main() + { + try + { + create_data( "tmp1.txt" ); + copy_data( "tmp1.txt", "tmp2.txt" ); //This should succeed. + + reset_file( "tmp1.txt" ); //Creates empty file. + try + { + copy_data( "tmp1.txt", "tmp2.txt" ); //This should fail, tmp1.txt is empty. + } + catch( + read_error & x ) + { + std::cerr << "\nCaught 'read_error' exception.\n"; + dump_all_info(x); + } + + remove( "tmp1.txt" ); + remove( "tmp2.txt" ); + try + { + copy_data( "tmp1.txt", "tmp2.txt" ); //This should fail, tmp1.txt does not exist. + } + catch( + open_error & x ) + { + std::cerr << "\nCaught 'open_error' exception.\n"; + dump_all_info(x); + } + } + catch( + ... ) + { + std::cerr << "\nCaught unexpected exception!\n"; + std::cerr << boost::current_exception_diagnostic_information(); + } + } diff --git a/src/boost/libs/exception/example/info_tuple.cpp b/src/boost/libs/exception/example/info_tuple.cpp new file mode 100644 index 00000000..f2e961f6 --- /dev/null +++ b/src/boost/libs/exception/example/info_tuple.cpp @@ -0,0 +1,31 @@ +//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 example shows how boost::tuple can be used to bundle the +//name of the function that fails together with the reported errno. + +#include <boost/exception/info_tuple.hpp> +#include <boost/exception/errinfo_file_name.hpp> +#include <boost/exception/errinfo_api_function.hpp> +#include <boost/exception/errinfo_errno.hpp> +#include <boost/shared_ptr.hpp> +#include <stdio.h> +#include <string> +#include <errno.h> + +typedef boost::tuple<boost::errinfo_api_function,boost::errinfo_errno> clib_failure; + +struct file_open_error: virtual boost::exception { }; + +boost::shared_ptr<FILE> +file_open( char const * name, char const * mode ) + { + if( FILE * f=fopen(name,mode) ) + return boost::shared_ptr<FILE>(f,fclose); + else + throw file_open_error() << + boost::errinfo_file_name(name) << + clib_failure("fopen",errno); + } diff --git a/src/boost/libs/exception/example/logging.cpp b/src/boost/libs/exception/example/logging.cpp new file mode 100644 index 00000000..c1b51e7d --- /dev/null +++ b/src/boost/libs/exception/example/logging.cpp @@ -0,0 +1,25 @@ +//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 example shows how to print all data contained in a boost::exception. + +#include <boost/exception/all.hpp> +#include <iostream> + +void f(); //throws unknown types that derive from boost::exception. + +void +g() + { + try + { + f(); + } + catch( + boost::exception & e ) + { + std::cerr << diagnostic_information(e); + } + } diff --git a/src/boost/libs/exception/index.html b/src/boost/libs/exception/index.html new file mode 100644 index 00000000..f91f9928 --- /dev/null +++ b/src/boost/libs/exception/index.html @@ -0,0 +1,15 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv=refresh content="0; URL=doc/boost-exception.html"> +<title>Automatic redirection</title> +</head> +<body> +Automatic redirection failed, please go to +<a href="doc/boost-exception.html">boost-exception.html</a>. <hr> +<p>© Copyright Beman Dawes, 2001</p> +<p>Distributed under the Boost Software License, Version 1.0. (See accompanying +file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy +at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p> +</body> +</html>
\ No newline at end of file diff --git a/src/boost/libs/exception/meta/libraries.json b/src/boost/libs/exception/meta/libraries.json new file mode 100644 index 00000000..a7dd2839 --- /dev/null +++ b/src/boost/libs/exception/meta/libraries.json @@ -0,0 +1,15 @@ +{ + "key": "exception", + "name": "Exception", + "authors": [ + "Emil Dotchevski" + ], + "description": "The Boost Exception library supports transporting of arbitrary data in exception objects, and transporting of exceptions between threads.", + "documentation": "doc/boost-exception.html", + "category": [ + "Emulation" + ], + "maintainers": [ + "Emil Dotchevski <emil -at- revergestudios.com>" + ] +} diff --git a/src/boost/libs/exception/src/clone_current_exception_non_intrusive.cpp b/src/boost/libs/exception/src/clone_current_exception_non_intrusive.cpp new file mode 100644 index 00000000..932bca89 --- /dev/null +++ b/src/boost/libs/exception/src/clone_current_exception_non_intrusive.cpp @@ -0,0 +1,349 @@ +//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/config.hpp> +#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! +//Thanks to Martin Weiss for implementing 64-bit support! + +#include <boost/exception/exception.hpp> +#include <boost/shared_ptr.hpp> +#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) && !defined _M_X64) + int const exception_info_offset=0x80; +#elif ((_MSC_VER==1400 || _MSC_VER==1500) && defined _M_X64) + int const exception_info_offset=0xE0; +#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; +#ifdef _M_X64 + unsigned const cpp_exception_parameter_count=4; +#else + unsigned const cpp_exception_parameter_count=3; +#endif + + 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 + { + void * address; + normal_copy_constructor_ptr normal_copy_constructor; + copy_constructor_with_virtual_base_ptr copy_constructor_with_virtual_base; + }; + + union + cpp_destructor + { + void * address; + destructor_ptr destructor; + }; + + enum + cpp_type_flags + { + class_is_simple_type=1, + class_has_virtual_base=4 + }; + + // ATTENTION: On x86 fields such as type_info and copy_constructor are really pointers + // but on 64bit these are 32bit offsets from HINSTANCE. Hints on the 64bit handling from + // http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx . + struct + cpp_type_info + { + unsigned flags; + int type_info; + int this_offset; + int vbase_descr; + int vbase_offset; + unsigned long size; + int copy_constructor; + }; + + struct + cpp_type_info_table + { + unsigned count; + int info; + }; + + struct + cpp_exception_type + { + unsigned flags; + int destructor; + int custom_handler; + int type_info_table; + }; + + struct + exception_object_deleter + { + cpp_exception_type const & et_; + size_t image_base_; + + exception_object_deleter( cpp_exception_type const & et, size_t image_base ): + et_(et), + image_base_(image_base) + { + } + + void + operator()( void * obj ) + { + BOOST_ASSERT(obj!=0); + dummy_exception_type* dummy_exception_ptr = static_cast<dummy_exception_type *>(obj); + if( et_.destructor ) + { + cpp_destructor destructor; + destructor.address = reinterpret_cast<void *>(et_.destructor + image_base_); + (dummy_exception_ptr->*(destructor.destructor))(); + } + free(obj); + } + }; + + cpp_type_info const & + get_cpp_type_info( cpp_exception_type const & et, size_t image_base ) + { + cpp_type_info_table * const typearray = reinterpret_cast<cpp_type_info_table * const>(et.type_info_table + image_base); + cpp_type_info * const ti = reinterpret_cast<cpp_type_info * const>(typearray->info + image_base); + BOOST_ASSERT(ti!=0); + return *ti; + } + + void + copy_msvc_exception( void * dst, void * src, cpp_type_info const & ti, size_t image_base ) + { + cpp_copy_constructor copy_constructor; + copy_constructor.address = reinterpret_cast<void *>(ti.copy_constructor + image_base); + + if( !(ti.flags & class_is_simple_type) && copy_constructor.normal_copy_constructor ) + { + dummy_exception_type * dummy_exception_ptr = static_cast<dummy_exception_type *>(dst); + if( ti.flags & class_has_virtual_base ) + (dummy_exception_ptr->*(copy_constructor.copy_constructor_with_virtual_base))(src,dst); + else + (dummy_exception_ptr->*(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, size_t image_base ) + { + BOOST_ASSERT(src!=0); + cpp_type_info const & ti=get_cpp_type_info(et,image_base); + if( void * dst = malloc(ti.size) ) + { + try + { + copy_msvc_exception(dst,src,ti,image_base); + } + catch( + ... ) + { + free(dst); + throw; + } + return boost::shared_ptr<void>(dst,exception_object_deleter(et,image_base)); + } + 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_; + size_t image_base_; + boost::shared_ptr<void> exc_; + + public: + cloned_exception( EXCEPTION_RECORD const * record ): + et_(*reinterpret_cast<cpp_exception_type const *>(record->ExceptionInformation[2])), + image_base_((cpp_exception_parameter_count==4) ? record->ExceptionInformation[3] : 0), + exc_(clone_msvc_exception(reinterpret_cast<void *>(record->ExceptionInformation[1]),et_,image_base_)) + { + } + + cloned_exception( void * exc, cpp_exception_type const & et, size_t image_base ): + et_(et), + image_base_(image_base), + exc_(clone_msvc_exception(exc,et_,image_base)) + { + } + + ~cloned_exception() BOOST_NOEXCEPT_OR_NOTHROW + { + } + + boost::exception_detail::clone_base const * + clone() const + { + return new cloned_exception(exc_.get(),et_,image_base_); + } + + void + rethrow() const + { + cpp_type_info const & ti=get_cpp_type_info(et_,image_base_); + void * dst = _alloca(ti.size); + copy_msvc_exception(dst,exc_.get(),ti,image_base_); + 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_); + if (cpp_exception_parameter_count==4) + args[3]=image_base_; + + 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_RECORD* record = static_cast<EXCEPTION_POINTERS *>(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(record); + 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. + +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/src/boost/libs/exception/test/1-throw_exception_test.cpp b/src/boost/libs/exception/test/1-throw_exception_test.cpp new file mode 100644 index 00000000..5106e862 --- /dev/null +++ b/src/boost/libs/exception/test/1-throw_exception_test.cpp @@ -0,0 +1,31 @@ +//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) + +#include <boost/throw_exception.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/config.hpp> + +class my_exception: public std::exception { }; + +int +main() + { + try + { + boost::throw_exception(my_exception()); + BOOST_ERROR("boost::throw_exception failed to throw."); + } + catch( + my_exception & ) + { + } + catch( + ... ) + { + BOOST_ERROR("boost::throw_exception malfunction."); + } + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/2-throw_exception_no_exceptions_test.cpp b/src/boost/libs/exception/test/2-throw_exception_no_exceptions_test.cpp new file mode 100644 index 00000000..02f0e96d --- /dev/null +++ b/src/boost/libs/exception/test/2-throw_exception_no_exceptions_test.cpp @@ -0,0 +1,26 @@ +//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) + +#define BOOST_NO_EXCEPTIONS +#include <boost/throw_exception.hpp> + +class my_exception: public std::exception { }; + +namespace +boost + { + void + throw_exception( std::exception const & ) + { + exit(0); + } + } + +int +main() + { + boost::throw_exception(my_exception()); + return 1; + } diff --git a/src/boost/libs/exception/test/3-throw_exception_no_integration_test.cpp b/src/boost/libs/exception/test/3-throw_exception_no_integration_test.cpp new file mode 100644 index 00000000..6fa78f54 --- /dev/null +++ b/src/boost/libs/exception/test/3-throw_exception_no_integration_test.cpp @@ -0,0 +1,30 @@ +//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) + +#define BOOST_EXCEPTION_DISABLE +#include <boost/throw_exception.hpp> +#include <boost/detail/lightweight_test.hpp> + +class my_exception: public std::exception { }; + +int +main() + { + try + { + boost::throw_exception(my_exception()); + BOOST_ERROR("boost::throw_exception failed to throw."); + } + catch( + my_exception & ) + { + } + catch( + ... ) + { + BOOST_ERROR("boost::throw_exception malfunction."); + } + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/4-throw_exception_no_both_test.cpp b/src/boost/libs/exception/test/4-throw_exception_no_both_test.cpp new file mode 100644 index 00000000..421ad458 --- /dev/null +++ b/src/boost/libs/exception/test/4-throw_exception_no_both_test.cpp @@ -0,0 +1,27 @@ +//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) + +#define BOOST_NO_EXCEPTIONS +#define BOOST_EXCEPTION_DISABLE +#include <boost/throw_exception.hpp> + +class my_exception: public std::exception { }; + +namespace +boost + { + void + throw_exception( std::exception const & ) + { + exit(0); + } + } + +int +main() + { + boost::throw_exception(my_exception()); + return 1; + } diff --git a/src/boost/libs/exception/test/Jamfile.v2 b/src/boost/libs/exception/test/Jamfile.v2 new file mode 100644 index 00000000..2b4cad8e --- /dev/null +++ b/src/boost/libs/exception/test/Jamfile.v2 @@ -0,0 +1,75 @@ +# Boost Exception Library test Jamfile +# +# 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) + +import testing ; + +project + : requirements + <link>static + <exception-handling>on + ; + +#to_string + +run is_output_streamable_test.cpp ; +run has_to_string_test.cpp ; +run to_string_test.cpp ; +run to_string_stub_test.cpp ; +compile-fail to_string_fail.cpp ; + +#exception + +run 1-throw_exception_test.cpp ; +run 2-throw_exception_no_exceptions_test.cpp ; +run 3-throw_exception_no_integration_test.cpp ; +run 4-throw_exception_no_both_test.cpp ; +run cloning_test.cpp ; +run copy_exception_test.cpp ../../thread/src/tss_null.cpp /boost//thread : : : <threading>multi ; +run unknown_exception_test.cpp ; +run exception_test.cpp ; +run enable_error_info_test.cpp helper1.cpp ; +run throw_exception_test.cpp helper2.cpp ; +run errno_test.cpp ; +run error_info_basic_test.cpp ; +run error_info_lv_test.cpp ; +run error_info_lv_const_test.cpp ; +run error_info_rv_test.cpp ; +run error_info_rv_const_test.cpp ; +run diagnostic_information_test.cpp ; +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 ; + +compile-fail exception_fail.cpp ; +compile-fail throw_exception_fail.cpp ; +compile-fail error_info_const_fail.cpp ; + +#headers + +compile exception_ptr_hpp_test.cpp ; +compile diagnostic_information_hpp_test.cpp ; +compile error_info_hpp_test.cpp ; +compile get_error_info_hpp_test.cpp ; +compile info_hpp_test.cpp ; +compile info_tuple_hpp_test.cpp ; +compile to_string_hpp_test.cpp ; +compile to_string_stub_hpp_test.cpp ; +compile all_hpp_test.cpp ; +compile current_exception_cast_hpp_test.cpp ; +compile errinfo_api_function_hpp_test.cpp ; +compile errinfo_at_line_hpp_test.cpp ; +compile errinfo_errno_hpp_test.cpp ; +compile errinfo_file_handle_hpp_test.cpp ; +compile errinfo_file_name_hpp_test.cpp ; +compile errinfo_file_open_mode_hpp_test.cpp ; +compile errinfo_nested_exception_hpp_test.cpp ; +compile errinfo_type_info_name_hpp_test.cpp ; + +compile bug_11874_test.cpp ; diff --git a/src/boost/libs/exception/test/all_hpp_test.cpp b/src/boost/libs/exception/test/all_hpp_test.cpp new file mode 100644 index 00000000..0e3fe58c --- /dev/null +++ b/src/boost/libs/exception/test/all_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/all.hpp> +#include <boost/exception/all.hpp> diff --git a/src/boost/libs/exception/test/bug_11874_test.cpp b/src/boost/libs/exception/test/bug_11874_test.cpp new file mode 100644 index 00000000..3d8fd4ad --- /dev/null +++ b/src/boost/libs/exception/test/bug_11874_test.cpp @@ -0,0 +1,10 @@ +//Copyright (c) 2006-2017 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 <boost/thread.hpp> + +int main() +{ +} diff --git a/src/boost/libs/exception/test/cloning_test.cpp b/src/boost/libs/exception/test/cloning_test.cpp new file mode 100644 index 00000000..138a38c1 --- /dev/null +++ b/src/boost/libs/exception/test/cloning_test.cpp @@ -0,0 +1,598 @@ +//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) + +#include <boost/exception_ptr.hpp> +#include <boost/exception/get_error_info.hpp> +#include <boost/exception/errinfo_nested_exception.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/detail/workaround.hpp> +#include <string> + +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 + { + int & count; + + explicit + derives_nothing( int & c ): + count(c) + { + ++count; + } + + derives_nothing( derives_nothing const & x ): + count(x.count) + { + ++count; + } + + ~derives_nothing() + { + --count; + } + }; + +struct +derives_std_exception: + std::exception + { + }; + +struct +derives_std_boost_exception: + std::exception, + boost::exception + { + char const * const wh_; + + derives_std_boost_exception( char const * wh="derives_std_boost_exception" ): + wh_(wh) + { + } + + char const * what() const BOOST_NOEXCEPT_OR_NOTHROW + { + return wh_; + } + }; + +struct +derives_boost_exception: + boost::exception + { + }; + +template <class T> +void +test_std_exception() + { + try + { + throw T(); + } + 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( + 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( + ... ) + { + BOOST_TEST(false); + } + try + { + rethrow_exception(p); + BOOST_TEST(false); + } + catch( + boost::exception & x ) + { +#ifndef BOOST_NO_RTTI + std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(x); + BOOST_TEST(t!=0 && *t!=0 && **t==typeid(T)); + std::string s=diagnostic_information(x); + BOOST_TEST(!s.empty()); +#endif + } + catch( + T & ) + { + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + } + +template <class T> +void +test_std_exception_what() + { + try + { + throw T("what"); + } + 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( + T & x ) + { + BOOST_TEST(std::string(x.what()).find("what")!=std::string::npos); + 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(x.what()).find("what")!=std::string::npos); + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + catch( + ... ) + { + BOOST_TEST(false); + } + try + { + rethrow_exception(p); + BOOST_TEST(false); + } + catch( + boost::exception & x ) + { +#ifndef BOOST_NO_RTTI + std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(x); + BOOST_TEST(t!=0 && *t!=0 && **t==typeid(T)); +#endif + } + catch( + T & ) + { + } + 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( + ... ) + { + BOOST_TEST(false); + } + } + } + +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 + { + throw boost::enable_current_exception(derives_nothing(count)); + } + 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( + derives_nothing & ) + { + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + BOOST_TEST(count==0); + + try + { + throw boost::enable_current_exception(derives_std_exception()); + } + 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( + 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( + ... ) + { + BOOST_TEST(false); + } + } + + try + { + throw derives_std_exception(); + } + 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( + derives_std_exception & ) + { + //Yay! Non-intrusive cloning supported! + } + catch( + boost::unknown_exception & e ) + { +#ifndef BOOST_NO_RTTI + std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(e); + BOOST_TEST(t!=0 && *t!=0 && **t==typeid(derives_std_exception)); +#endif + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + + test_std_exception_what<std::domain_error>(); + test_std_exception_what<std::invalid_argument>(); + test_std_exception_what<std::length_error>(); + test_std_exception_what<std::out_of_range>(); + test_std_exception_what<std::logic_error>(); + test_std_exception_what<std::range_error>(); + test_std_exception_what<std::overflow_error>(); + test_std_exception_what<std::underflow_error>(); + test_std_exception_what<std::ios_base::failure>(); + test_std_exception_what<std::runtime_error>(); + test_std_exception<std::bad_alloc>(); +#ifndef BOOST_NO_TYPEID + test_std_exception<std::bad_cast>(); + test_std_exception<std::bad_typeid>(); +#endif + test_std_exception<std::bad_exception>(); + test_std_exception<std::exception>(); + + try + { + throw derives_std_boost_exception() << my_info(42); + } + 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( + 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)); + if( int const * p=boost::get_error_info<my_info>(x) ) + BOOST_TEST(*p==42); +#ifndef BOOST_NO_RTTI + { + std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(x); + BOOST_TEST(t && *t && **t==typeid(derives_std_boost_exception)); + } +#endif + 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( int const * p=boost::get_error_info<my_info>(x) ) + BOOST_TEST(*p==42); +#ifndef BOOST_NO_RTTI + std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(x); + BOOST_TEST(t && *t && **t==typeid(derives_std_boost_exception)); +#endif + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + + try + { + throw derives_boost_exception() << my_info(42); + } + 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( + 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)); + if( int const * p=boost::get_error_info<my_info>(x) ) + BOOST_TEST(*p==42); +#ifndef BOOST_NO_RTTI + { + std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(x); + BOOST_TEST(t && *t && **t==typeid(derives_boost_exception)); + } +#endif + 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( int const * p=boost::get_error_info<my_info>(x) ) + BOOST_TEST(*p==42); + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + + test_throw_on_copy<std::bad_alloc,std::bad_alloc>(); + test_throw_on_copy<int,std::bad_exception>(); + + try + { + throw boost::enable_current_exception(derives_std_boost_exception("what1")); + } + catch( + ... ) + { + boost::exception_ptr p=boost::current_exception(); + { + std::string s=diagnostic_information(p); + BOOST_TEST(s.find("what1")!=s.npos); + } + try + { + throw boost::enable_current_exception(derives_std_boost_exception("what2") << boost::errinfo_nested_exception(p) ); + } + catch( + ... ) + { + std::string s=boost::current_exception_diagnostic_information(); + BOOST_TEST(s.find("what1")!=s.npos); + BOOST_TEST(s.find("what2")!=s.npos); + } + } + BOOST_TEST(!diagnostic_information(boost::exception_ptr()).empty()); + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/copy_exception_test.cpp b/src/boost/libs/exception/test/copy_exception_test.cpp new file mode 100644 index 00000000..69acb655 --- /dev/null +++ b/src/boost/libs/exception/test/copy_exception_test.cpp @@ -0,0 +1,146 @@ +//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) + +#include <boost/exception_ptr.hpp> +#include <boost/exception/get_error_info.hpp> +#include <boost/thread.hpp> +#include <boost/detail/atomic_count.hpp> +#include <boost/detail/lightweight_test.hpp> + +typedef boost::error_info<struct tag_answer,int> answer; + +boost::detail::atomic_count exc_count(0); + +struct +err: + virtual boost::exception, + virtual std::exception + { + err() + { + ++exc_count; + } + + err( err const & ) + { + ++exc_count; + } + + virtual + ~err() BOOST_NOEXCEPT_OR_NOTHROW + { + --exc_count; + } + + private: + + err & operator=( err const & ); + }; + +class +future + { + public: + + future (): + ready_ (false) + { + } + + void + set_exception( boost::exception_ptr const & e ) + { + boost::unique_lock<boost::mutex> lck (mux_); + exc_ = e; + ready_ = true; + cond_.notify_all(); + } + + void + get_exception() const + { + boost::unique_lock<boost::mutex> lck (mux_); + while (! ready_) + cond_.wait (lck); + rethrow_exception (exc_); + } + + private: + + bool ready_; + boost::exception_ptr exc_; + mutable boost::mutex mux_; + mutable boost::condition_variable cond_; + }; + +void +producer( future & f ) + { + f.set_exception (boost::copy_exception (err () << answer(42))); + } + +void +consumer() + { + future f; + boost::thread thr (boost::bind (&producer, boost::ref (f))); + try + { + f.get_exception (); + } + catch( + err & e ) + { + int const * ans=boost::get_error_info<answer>(e); + BOOST_TEST(ans && *ans==42); + } + thr.join(); + } + +void +consume() + { + for( int i=0; i!=100; ++i ) + consumer(); + } + +void +thread_test() + { + boost::thread_group grp; + for( int i=0; i!=50; ++i ) + grp.create_thread(&consume); + grp.join_all (); + } + +void +simple_test() + { + boost::exception_ptr p = boost::copy_exception(err()); + try + { + rethrow_exception(p); + BOOST_TEST(false); + } + catch( + err & ) + { + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + +int +main() + { + BOOST_TEST(++exc_count==1); + simple_test(); + thread_test(); + BOOST_TEST(!--exc_count); + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/current_exception_cast_hpp_test.cpp b/src/boost/libs/exception/test/current_exception_cast_hpp_test.cpp new file mode 100644 index 00000000..d3211e27 --- /dev/null +++ b/src/boost/libs/exception/test/current_exception_cast_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/current_exception_cast.hpp> +#include <boost/exception/current_exception_cast.hpp> diff --git a/src/boost/libs/exception/test/current_exception_cast_test.cpp b/src/boost/libs/exception/test/current_exception_cast_test.cpp new file mode 100644 index 00000000..1f2e6b36 --- /dev/null +++ b/src/boost/libs/exception/test/current_exception_cast_test.cpp @@ -0,0 +1,47 @@ +//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) + +#include <boost/exception/current_exception_cast.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <exception> + +class +my_exception: + public std::exception + { + }; + +class +polymorphic + { + virtual + ~polymorphic() + { + } + }; + +int +main() + { + try + { + throw my_exception(); + } + catch( + std::exception & e ) + { + try + { + throw; + } + catch( + ...) + { + BOOST_TEST(boost::current_exception_cast<std::exception>()==&e); + BOOST_TEST(!boost::current_exception_cast<polymorphic>()); + } + } + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/diagnostic_information_hpp_test.cpp b/src/boost/libs/exception/test/diagnostic_information_hpp_test.cpp new file mode 100644 index 00000000..92a37513 --- /dev/null +++ b/src/boost/libs/exception/test/diagnostic_information_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/diagnostic_information.hpp> +#include <boost/exception/diagnostic_information.hpp> diff --git a/src/boost/libs/exception/test/diagnostic_information_test.cpp b/src/boost/libs/exception/test/diagnostic_information_test.cpp new file mode 100644 index 00000000..35eb5e8b --- /dev/null +++ b/src/boost/libs/exception/test/diagnostic_information_test.cpp @@ -0,0 +1,246 @@ +//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) + +#include <boost/exception/diagnostic_information.hpp> +#include <boost/exception/info.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) +struct test_tag1 {}; +struct test_tag2 {}; +#endif + +typedef boost::error_info<struct test_tag1,int> tagged_int1; +typedef boost::error_info<struct test_tag2,int> tagged_int2; + +std::string +to_string( tagged_int2 const & x ) + { + return '[' +boost::error_info_name(x) + "] = " + (x.value()==42 ? "fourty-two" : "bad value"); + } + +struct +error1: + std::exception, + boost::exception + { + char const * + what() const BOOST_NOEXCEPT_OR_NOTHROW + { + return "error1"; + } + }; + +struct +error2: + boost::exception + { + }; + +struct +error3: + std::exception + { + char const * + what() const BOOST_NOEXCEPT_OR_NOTHROW + { + return "error3"; + } + }; + +struct +error4: + std::exception, + boost::exception + { + char const * + what() const BOOST_NOEXCEPT_OR_NOTHROW + { + return diagnostic_information_what(*this); + } + }; + +void +test1( std::string const & di1, std::string const & di2 ) + { + BOOST_TEST( di1!=di2 ); +#ifndef BOOST_NO_RTTI + BOOST_TEST(di1.find("type:")!=std::string::npos); + BOOST_TEST(di1.find("error1")!=std::string::npos); +#endif + BOOST_TEST(di1.find("test_tag1")!=std::string::npos); + BOOST_TEST(di1.find("test_tag2")!=std::string::npos); + BOOST_TEST(di1.find("fourty-two")!=std::string::npos); +#ifndef BOOST_NO_RTTI + BOOST_TEST(di2.find("type:")!=std::string::npos); + BOOST_TEST(di2.find("error1")!=std::string::npos); +#endif + BOOST_TEST(di2.find("test_tag1")!=std::string::npos); + BOOST_TEST(di2.find("test_tag2")!=std::string::npos); + BOOST_TEST(di2.find("bad value")!=std::string::npos); + } + +void +test2( std::string const & di1, std::string const & di2 ) + { + BOOST_TEST( di1!=di2 ); + BOOST_TEST(di1.find("test_tag1")!=std::string::npos); + BOOST_TEST(di1.find("test_tag2")!=std::string::npos); + BOOST_TEST(di1.find("fourty-two")!=std::string::npos); + BOOST_TEST(di2.find("test_tag1")!=std::string::npos); + BOOST_TEST(di2.find("test_tag2")!=std::string::npos); + BOOST_TEST(di2.find("bad value")!=std::string::npos); + } + +void +test3( std::string const & di ) + { +#ifndef BOOST_NO_RTTI + BOOST_TEST(di.find("type:")!=std::string::npos); +#endif + BOOST_TEST(di.find("error3")!=std::string::npos); + } + +void +test4( std::string const & di1, std::string const & di2 ) + { + BOOST_TEST( di1!=di2 ); +#ifndef BOOST_NO_RTTI + BOOST_TEST(di1.find("type:")!=std::string::npos); +#endif + BOOST_TEST(di1.find("test_tag1")!=std::string::npos); + BOOST_TEST(di1.find("test_tag2")!=std::string::npos); + BOOST_TEST(di1.find("fourty-two")!=std::string::npos); +#ifndef BOOST_NO_RTTI + BOOST_TEST(di2.find("type:")!=std::string::npos); +#endif + BOOST_TEST(di2.find("test_tag1")!=std::string::npos); + BOOST_TEST(di2.find("test_tag2")!=std::string::npos); + BOOST_TEST(di2.find("bad value")!=std::string::npos); + } + +int +main() + { + using namespace boost; + try + { + error1 x; x << tagged_int1(42) << tagged_int2(42); + BOOST_TEST(x.what()==std::string("error1")); + throw x; + } + catch( + error1 & x ) + { + std::string di1=boost::diagnostic_information(x); + x << tagged_int1(2) << tagged_int2(2); + std::string di2 = diagnostic_information(x); + test1(di1,di2); + } + try + { + error1 x; x << tagged_int1(42) << tagged_int2(42); + BOOST_TEST(x.what()==std::string("error1")); + throw x; + } + catch( + error1 & x ) + { + std::string di1=boost::current_exception_diagnostic_information(); + x << tagged_int1(2) << tagged_int2(2); + std::string di2 = current_exception_diagnostic_information(); + test1(di1,di2); + } + try + { + error2 x; + x << tagged_int1(42) << tagged_int2(42); + throw x; + } + catch( + error2 & x ) + { + std::string di1 = diagnostic_information(x); + x << tagged_int1(2) << tagged_int2(2); + std::string di2 = diagnostic_information(x); + test2(di1,di2); + } + try + { + error2 x; + x << tagged_int1(42) << tagged_int2(42); + throw x; + } + catch( + error2 & x ) + { + std::string di1 = current_exception_diagnostic_information(); + BOOST_TEST(di1==boost::diagnostic_information_what(x)); + x << tagged_int1(2) << tagged_int2(2); + std::string di2 = current_exception_diagnostic_information(); + BOOST_TEST(di2==boost::diagnostic_information_what(x)); + test2(di1,di2); + } + try + { + error3 x; + std::string di=diagnostic_information(x); + test3(di); + throw x; + } + catch( + ... ) + { + std::string di=current_exception_diagnostic_information(); + test3(di); + } + try + { + throw error4(); + } + catch( + error4 & x ) + { + std::string di1=boost::diagnostic_information(x); + std::string wh1=x.what(); + BOOST_TEST(wh1==di1); + } + try + { + error4 x; x << tagged_int1(42) << tagged_int2(42); + throw x; + } + catch( + error4 & x ) + { + std::string di1=boost::diagnostic_information(x); + std::string wh1=x.what(); + BOOST_TEST(wh1==di1); + x << tagged_int1(2) << tagged_int2(2); + std::string di2 = diagnostic_information(x); + std::string wh2=x.what(); + BOOST_TEST(wh2==di2); + test4(di1,di2); + } + try + { + error4 x; x << tagged_int1(42) << tagged_int2(42); + throw x; + } + catch( + error4 & x ) + { + std::string di1=boost::current_exception_diagnostic_information(); + std::string wh1=x.what(); + BOOST_TEST(wh1==di1); + x << tagged_int1(2) << tagged_int2(2); + std::string di2 = current_exception_diagnostic_information(); + std::string wh2=x.what(); + BOOST_TEST(wh2==di2); + test4(di1,di2); + } + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/enable_error_info_test.cpp b/src/boost/libs/exception/test/enable_error_info_test.cpp new file mode 100644 index 00000000..351c5f85 --- /dev/null +++ b/src/boost/libs/exception/test/enable_error_info_test.cpp @@ -0,0 +1,76 @@ +//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) + +#include "helper1.hpp" +#include <boost/exception/get_error_info.hpp> +#include <boost/exception/info.hpp> +#include <boost/exception/diagnostic_information.hpp> +#include <boost/detail/lightweight_test.hpp> + +namespace + { + typedef boost::error_info<struct tag_test_int,int> test_int; + + void + throw_wrapper() + { + try + { + boost::exception_test::throw_length_error(); + } + catch( + boost::exception & x ) + { + x << test_int(42); + throw; + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + } + +int +main() + { + try + { + throw_wrapper(); + BOOST_TEST(false); + } + catch( + std::exception & x ) + { +#ifdef BOOST_NO_RTTI + try + { + throw; + } + catch( + boost::exception & x ) + { +#endif + BOOST_TEST( boost::get_error_info<test_int>(x) ); + if( int const * p=boost::get_error_info<test_int>(x) ) + BOOST_TEST( 42==*p ); +#ifdef BOOST_NO_RTTI + } + catch( + ... ) + { + BOOST_TEST(false); + } +#endif + BOOST_TEST( std::string(x.what())==std::string("exception test length error") ); + } + catch( + ... ) + { + BOOST_TEST(false); + } + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/errinfo_api_function_hpp_test.cpp b/src/boost/libs/exception/test/errinfo_api_function_hpp_test.cpp new file mode 100644 index 00000000..fcb92346 --- /dev/null +++ b/src/boost/libs/exception/test/errinfo_api_function_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/errinfo_api_function.hpp> +#include <boost/exception/errinfo_api_function.hpp> diff --git a/src/boost/libs/exception/test/errinfo_at_line_hpp_test.cpp b/src/boost/libs/exception/test/errinfo_at_line_hpp_test.cpp new file mode 100644 index 00000000..cf13e308 --- /dev/null +++ b/src/boost/libs/exception/test/errinfo_at_line_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/errinfo_at_line.hpp> +#include <boost/exception/errinfo_at_line.hpp> diff --git a/src/boost/libs/exception/test/errinfo_errno_hpp_test.cpp b/src/boost/libs/exception/test/errinfo_errno_hpp_test.cpp new file mode 100644 index 00000000..6bd627ec --- /dev/null +++ b/src/boost/libs/exception/test/errinfo_errno_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/errinfo_errno.hpp> +#include <boost/exception/errinfo_errno.hpp> diff --git a/src/boost/libs/exception/test/errinfo_file_handle_hpp_test.cpp b/src/boost/libs/exception/test/errinfo_file_handle_hpp_test.cpp new file mode 100644 index 00000000..84197498 --- /dev/null +++ b/src/boost/libs/exception/test/errinfo_file_handle_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/errinfo_file_handle.hpp> +#include <boost/exception/errinfo_file_handle.hpp> diff --git a/src/boost/libs/exception/test/errinfo_file_name_hpp_test.cpp b/src/boost/libs/exception/test/errinfo_file_name_hpp_test.cpp new file mode 100644 index 00000000..2018d6be --- /dev/null +++ b/src/boost/libs/exception/test/errinfo_file_name_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/errinfo_file_name.hpp> +#include <boost/exception/errinfo_file_name.hpp> diff --git a/src/boost/libs/exception/test/errinfo_file_open_mode_hpp_test.cpp b/src/boost/libs/exception/test/errinfo_file_open_mode_hpp_test.cpp new file mode 100644 index 00000000..4d6ebd30 --- /dev/null +++ b/src/boost/libs/exception/test/errinfo_file_open_mode_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/errinfo_file_open_mode.hpp> +#include <boost/exception/errinfo_file_open_mode.hpp> diff --git a/src/boost/libs/exception/test/errinfo_nested_exception_hpp_test.cpp b/src/boost/libs/exception/test/errinfo_nested_exception_hpp_test.cpp new file mode 100644 index 00000000..2018d6be --- /dev/null +++ b/src/boost/libs/exception/test/errinfo_nested_exception_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/errinfo_file_name.hpp> +#include <boost/exception/errinfo_file_name.hpp> diff --git a/src/boost/libs/exception/test/errinfo_type_info_name_hpp_test.cpp b/src/boost/libs/exception/test/errinfo_type_info_name_hpp_test.cpp new file mode 100644 index 00000000..20888ef2 --- /dev/null +++ b/src/boost/libs/exception/test/errinfo_type_info_name_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/errinfo_type_info_name.hpp> +#include <boost/exception/errinfo_type_info_name.hpp> diff --git a/src/boost/libs/exception/test/errinfos_test.cpp b/src/boost/libs/exception/test/errinfos_test.cpp new file mode 100644 index 00000000..bf3ad5fc --- /dev/null +++ b/src/boost/libs/exception/test/errinfos_test.cpp @@ -0,0 +1,67 @@ +//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) + +#include <boost/exception/errinfo_api_function.hpp> +#include <boost/exception/errinfo_at_line.hpp> +#include <boost/exception/errinfo_errno.hpp> +#include <boost/exception/errinfo_file_handle.hpp> +#include <boost/exception/errinfo_file_name.hpp> +#include <boost/exception/errinfo_file_open_mode.hpp> +#include <boost/exception/errinfo_type_info_name.hpp> +#include <boost/exception/info.hpp> +#include <boost/exception/get_error_info.hpp> +#include <boost/throw_exception.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <exception> + +struct +test_exception: + virtual boost::exception, + virtual std::exception + { + }; + +int +main() + { + using namespace boost; + try + { + test_exception e; + e << + errinfo_api_function("failed_api_function") << + errinfo_at_line(42) << + errinfo_errno(0) << + errinfo_file_handle(weak_ptr<FILE>()) << + errinfo_file_name("filename.txt") << + errinfo_file_open_mode("rb"); +#ifdef BOOST_NO_TYPEID + BOOST_THROW_EXCEPTION(e); +#else + BOOST_THROW_EXCEPTION(e<<errinfo_type_info_name(typeid(int).name())); +#endif + BOOST_ERROR("BOOST_THROW_EXCEPTION failed to throw."); + } + catch( + boost::exception & e ) + { + BOOST_TEST(get_error_info<errinfo_api_function>(e) && *get_error_info<errinfo_api_function>(e)==std::string("failed_api_function")); + BOOST_TEST(get_error_info<errinfo_at_line>(e) && *get_error_info<errinfo_at_line>(e)==42); + BOOST_TEST(get_error_info<errinfo_errno>(e) && *get_error_info<errinfo_errno>(e)==0); + BOOST_TEST(get_error_info<errinfo_file_handle>(e) && get_error_info<errinfo_file_handle>(e)->expired()); + BOOST_TEST(get_error_info<errinfo_file_name>(e) && *get_error_info<errinfo_file_name>(e)=="filename.txt"); + BOOST_TEST(get_error_info<errinfo_file_open_mode>(e) && *get_error_info<errinfo_file_open_mode>(e)=="rb"); +#ifndef BOOST_NO_TYPEID + BOOST_TEST(get_error_info<errinfo_type_info_name>(e) && *get_error_info<errinfo_type_info_name>(e)==typeid(int).name()); +#endif + } + catch( + ... ) + { + BOOST_TEST(false); + } + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/errno_test.cpp b/src/boost/libs/exception/test/errno_test.cpp new file mode 100644 index 00000000..9324d6b3 --- /dev/null +++ b/src/boost/libs/exception/test/errno_test.cpp @@ -0,0 +1,34 @@ +//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) + +#include <boost/exception/get_error_info.hpp> +#include <boost/exception/info.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/detail/workaround.hpp> +#include <errno.h> + +typedef boost::error_info<struct tag_errno,int> info_errno; + +class +my_exception: + public boost::exception + { + }; + +int +main() + { + try + { + errno=1; + throw my_exception() << info_errno(errno); + } + catch( + my_exception & x ) + { + BOOST_TEST(1==*boost::get_error_info<info_errno>(x)); + } + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/error_info_basic_test.cpp b/src/boost/libs/exception/test/error_info_basic_test.cpp new file mode 100644 index 00000000..488360d2 --- /dev/null +++ b/src/boost/libs/exception/test/error_info_basic_test.cpp @@ -0,0 +1,29 @@ +//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) + +#include <boost/exception/error_info.hpp> +#include <boost/exception/exception.hpp> +#include <boost/exception/info.hpp> +#include <boost/exception/get_error_info.hpp> +#include <boost/core/lightweight_test.hpp> +#include <string> +#include <string.h> + +struct my_exception: virtual boost::exception {}; +typedef boost::error_info<struct error_info_string_, std::string> error_info_string; + +int +main() + { + try + { + throw my_exception() << error_info_string("doh"); + } + catch( my_exception & e ) + { + BOOST_TEST(boost::get_error_info<error_info_string>(e) && !strcmp(boost::get_error_info<error_info_string>(e)->c_str(),"doh")); + } + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/error_info_const_fail.cpp b/src/boost/libs/exception/test/error_info_const_fail.cpp new file mode 100644 index 00000000..6612dbaa --- /dev/null +++ b/src/boost/libs/exception/test/error_info_const_fail.cpp @@ -0,0 +1,14 @@ +//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) + +#include <boost/exception/get_error_info.hpp> + +typedef boost::error_info<struct foo_,int> foo; + +void +test( boost::exception const * e ) + { + ++*boost::get_error_info<foo>(*e); + } diff --git a/src/boost/libs/exception/test/error_info_hpp_test.cpp b/src/boost/libs/exception/test/error_info_hpp_test.cpp new file mode 100644 index 00000000..ffe9ac80 --- /dev/null +++ b/src/boost/libs/exception/test/error_info_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/error_info.hpp> +#include <boost/exception/error_info.hpp> diff --git a/src/boost/libs/exception/test/error_info_lv_const_test.cpp b/src/boost/libs/exception/test/error_info_lv_const_test.cpp new file mode 100644 index 00000000..68e57a9b --- /dev/null +++ b/src/boost/libs/exception/test/error_info_lv_const_test.cpp @@ -0,0 +1,13 @@ +//Copyright (c) 2006-2015 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 <boost/exception/info.hpp> +template <class E,class I> +E const & +add_info( E const & e, I const & i ) + { + return e << i; + } +#include "error_info_test.hpp" diff --git a/src/boost/libs/exception/test/error_info_lv_test.cpp b/src/boost/libs/exception/test/error_info_lv_test.cpp new file mode 100644 index 00000000..66334b40 --- /dev/null +++ b/src/boost/libs/exception/test/error_info_lv_test.cpp @@ -0,0 +1,13 @@ +//Copyright (c) 2006-2015 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 <boost/exception/info.hpp> +template <class E,class I> +E const & +add_info( E const & e, I i ) + { + return e << i; + } +#include "error_info_test.hpp" diff --git a/src/boost/libs/exception/test/error_info_rv_const_test.cpp b/src/boost/libs/exception/test/error_info_rv_const_test.cpp new file mode 100644 index 00000000..23b137ff --- /dev/null +++ b/src/boost/libs/exception/test/error_info_rv_const_test.cpp @@ -0,0 +1,28 @@ +//Copyright (c) 2006-2015 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 <boost/exception/info.hpp> + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES +int +main() + { + return 0; + } +#else +template <class I> +I const +rv_const( I i ) + { + return i; + } +template <class E,class I> +E const & +add_info( E const & e, I i ) + { + return e << rv_const(i); + } +#include "error_info_test.hpp" +#endif diff --git a/src/boost/libs/exception/test/error_info_rv_test.cpp b/src/boost/libs/exception/test/error_info_rv_test.cpp new file mode 100644 index 00000000..3c8c718f --- /dev/null +++ b/src/boost/libs/exception/test/error_info_rv_test.cpp @@ -0,0 +1,22 @@ +//Copyright (c) 2006-2015 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 <boost/exception/info.hpp> + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES +int +main() + { + return 0; + } +#else +template <class E,class I> +E const & +add_info( E const & e, I i ) + { + return e << std::move(i); + } +#include "error_info_test.hpp" +#endif diff --git a/src/boost/libs/exception/test/error_info_test.hpp b/src/boost/libs/exception/test/error_info_test.hpp new file mode 100644 index 00000000..8648362f --- /dev/null +++ b/src/boost/libs/exception/test/error_info_test.hpp @@ -0,0 +1,404 @@ +//Copyright (c) 2006-2015 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 <boost/exception/get_error_info.hpp> +#include <boost/exception/info_tuple.hpp> +#include <boost/exception_ptr.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/detail/workaround.hpp> + +struct throws_on_copy; +struct non_printable { }; + +struct +user_data + { + int & count; + + explicit + user_data( int & count ): + count(count) + { + ++count; + } + + user_data( user_data const & x ): + count(x.count) + { + ++count; + } + + ~user_data() + { + --count; + } + }; + +typedef boost::error_info<struct tag_test_1,int> test_1; +typedef boost::error_info<struct tag_test_2,unsigned int> test_2; +typedef boost::error_info<struct tag_test_3,float> test_3; +typedef boost::error_info<struct tag_test_4,throws_on_copy> test_4; +typedef boost::error_info<struct tag_test_5,std::string> test_5; +typedef boost::error_info<struct tag_test_6,non_printable> test_6; +typedef boost::error_info<struct tag_user_data,user_data> test_7; + +struct +test_exception: + boost::exception + { + }; + +struct +throws_on_copy + { + throws_on_copy() + { + } + + throws_on_copy( throws_on_copy const & ) + { + throw test_exception(); + } + }; + +void +basic_test() + { + try + { + test_exception x; + add_info(add_info(add_info(x,test_1(1)),test_2(2u)),test_3(3.14159f)); + throw x; + } + catch( + test_exception & x ) + { + ++*boost::get_error_info<test_1>(x); + ++*boost::get_error_info<test_2>(x); + ++*boost::get_error_info<test_3>(x); + BOOST_TEST(*boost::get_error_info<test_1>(x)==2); + BOOST_TEST(*boost::get_error_info<test_2>(x)==3u); + BOOST_TEST(*boost::get_error_info<test_3>(x)==4.14159f); + BOOST_TEST(!boost::get_error_info<test_4>(x)); + } + try + { + test_exception x; + add_info(add_info(add_info(x,test_1(1)),test_2(2u)),test_3(3.14159f)); + throw x; + } + catch( + test_exception const & x ) + { + BOOST_TEST(*boost::get_error_info<test_1>(x)==1); + BOOST_TEST(*boost::get_error_info<test_2>(x)==2u); + BOOST_TEST(*boost::get_error_info<test_3>(x)==3.14159f); + BOOST_TEST(!boost::get_error_info<test_4>(x)); + } + } + +void +exception_safety_test() + { + test_exception x; + try + { + add_info(x,test_4(throws_on_copy())); + BOOST_TEST(false); + } + catch( + test_exception & ) + { + BOOST_TEST(!boost::get_error_info<test_4>(x)); + } + } + +void +throw_empty() + { + throw test_exception(); + } + +void +throw_test_1( char const * value ) + { + throw add_info(test_exception(),test_5(std::string(value))); + } + +void +throw_test_2() + { + throw add_info(test_exception(),test_6(non_printable())); + } + +void +throw_catch_add_file_name( char const * name ) + { + try + { + throw_empty(); + BOOST_TEST(false); + } + catch( + boost::exception & x ) + { + add_info(x,test_5(std::string(name))); + throw; + } + } + +void +test_empty() + { + try + { + throw_empty(); + BOOST_TEST(false); + } + catch( + boost::exception & x ) + { +#ifndef BOOST_NO_RTTI + BOOST_TEST( dynamic_cast<test_exception *>(&x) ); +#endif + BOOST_TEST( !boost::get_error_info<test_1>(x) ); + } + catch( + ... ) + { + BOOST_TEST(false); + } + + try + { + throw_empty(); + BOOST_TEST(false); + } + catch( + test_exception & x ) + { +#ifndef BOOST_NO_RTTI + BOOST_TEST( dynamic_cast<boost::exception const *>(&x)!=0 ); +#endif + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + +void +test_basic_throw_catch() + { + try + { + throw_test_1("test"); + BOOST_ASSERT(false); + } + catch( + boost::exception & x ) + { + BOOST_TEST(*boost::get_error_info<test_5>(x)==std::string("test")); + } + catch( + ... ) + { + BOOST_TEST(false); + } + + try + { + throw_test_2(); + BOOST_ASSERT(false); + } + catch( + boost::exception & x ) + { + BOOST_TEST(boost::get_error_info<test_6>(x)); + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + +void +test_catch_add_info() + { + try + { + throw_catch_add_file_name("test"); + BOOST_TEST(false); + } + catch( + boost::exception & x ) + { + BOOST_TEST(*boost::get_error_info<test_5>(x)==std::string("test")); + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + +void +test_add_tuple() + { + typedef boost::tuple<> tuple_test_; + typedef boost::tuple<test_1> tuple_test_1; + typedef boost::tuple<test_1,test_2> tuple_test_12; + typedef boost::tuple<test_1,test_2,test_3> tuple_test_123; + typedef boost::tuple<test_1,test_2,test_3,test_5> tuple_test_1235; + try + { + throw add_info(test_exception(),tuple_test_()); + } + catch( + test_exception & ) + { + } + catch( + ... ) + { + BOOST_TEST(false); + } + try + { + throw add_info(test_exception(),tuple_test_1(42)); + } + catch( + test_exception & x ) + { + BOOST_TEST( *boost::get_error_info<test_1>(x)==42 ); + } + catch( + ... ) + { + BOOST_TEST(false); + } + try + { + throw add_info(test_exception(),tuple_test_12(42,42u)); + } + catch( + test_exception & x ) + { + BOOST_TEST( *boost::get_error_info<test_1>(x)==42 ); + BOOST_TEST( *boost::get_error_info<test_2>(x)==42u ); + } + catch( + ... ) + { + BOOST_TEST(false); + } + try + { + throw add_info(test_exception(),tuple_test_123(42,42u,42.0f)); + } + catch( + test_exception & x ) + { + BOOST_TEST( *boost::get_error_info<test_1>(x)==42 ); + BOOST_TEST( *boost::get_error_info<test_2>(x)==42u ); + BOOST_TEST( *boost::get_error_info<test_3>(x)==42.0f ); + } + catch( + ... ) + { + BOOST_TEST(false); + } + try + { + throw add_info(test_exception(),tuple_test_1235(42,42u,42.0f,std::string("42"))); + } + catch( + test_exception & x ) + { + BOOST_TEST( *boost::get_error_info<test_1>(x)==42 ); + BOOST_TEST( *boost::get_error_info<test_2>(x)==42u ); + BOOST_TEST( *boost::get_error_info<test_3>(x)==42.0f ); + BOOST_TEST( *boost::get_error_info<test_5>(x)=="42" ); + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + +void +test_lifetime1() + { + int count=0; + try + { + throw add_info(test_exception(),test_7(user_data(count))); + } + catch( + boost::exception & x ) + { + BOOST_TEST(count==1); + BOOST_TEST( boost::get_error_info<test_7>(x) ); + } + catch( + ... ) + { + BOOST_TEST(false); + } + BOOST_TEST(!count); + } + +void +test_lifetime2() + { + int count=0; + { + boost::exception_ptr ep; + test_exception e; add_info(e,test_7(user_data(count))); + ep=boost::copy_exception(e); + BOOST_TEST(count>0); + } + BOOST_TEST(!count); + } + +bool +is_const( int const * ) + { + return true; + } + +bool +is_const( int * ) + { + return false; + } + +void +test_const() + { + test_exception e; + boost::exception const & c(e); + boost::exception & m(e); + BOOST_TEST(is_const(boost::get_error_info<test_1>(c))); + BOOST_TEST(!is_const(boost::get_error_info<test_1>(m))); + } + +int +main() + { + basic_test(); + exception_safety_test(); + test_empty(); + test_basic_throw_catch(); + test_catch_add_info(); + test_add_tuple(); + test_lifetime1(); + test_lifetime2(); + test_const(); + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/exception_fail.cpp b/src/boost/libs/exception/test/exception_fail.cpp new file mode 100644 index 00000000..3249f5c5 --- /dev/null +++ b/src/boost/libs/exception/test/exception_fail.cpp @@ -0,0 +1,12 @@ +//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) + +#include <boost/exception/exception.hpp> + +void +tester( boost::exception & x ) + { + throw x; //must not compile. + } diff --git a/src/boost/libs/exception/test/exception_ptr_hpp_test.cpp b/src/boost/libs/exception/test/exception_ptr_hpp_test.cpp new file mode 100644 index 00000000..dbfebbf4 --- /dev/null +++ b/src/boost/libs/exception/test/exception_ptr_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception_ptr.hpp> +#include <boost/exception_ptr.hpp> diff --git a/src/boost/libs/exception/test/exception_ptr_test.cpp b/src/boost/libs/exception/test/exception_ptr_test.cpp new file mode 100644 index 00000000..ebcb1d56 --- /dev/null +++ b/src/boost/libs/exception/test/exception_ptr_test.cpp @@ -0,0 +1,178 @@ +//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) + +#include <boost/exception_ptr.hpp> +#include <boost/exception/info.hpp> +#include <boost/exception/get_error_info.hpp> +#include <boost/exception/diagnostic_information.hpp> +#include <boost/function.hpp> +#include <boost/bind.hpp> +#include <boost/thread.hpp> +#include <boost/detail/atomic_count.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> + +class thread_handle; +boost::shared_ptr<thread_handle> create_thread( boost::function<void()> const & f ); +void join( thread_handle & t ); + +class +thread_handle + { + thread_handle( thread_handle const & ); + thread_handle & operator=( thread_handle const & ); + + boost::exception_ptr err_; + boost::thread t_; + + static + void + thread_wrapper( boost::function<void()> const & f, boost::exception_ptr & ep ) + { + BOOST_ASSERT(!ep); + try + { + f(); + } + catch(...) + { + ep = boost::current_exception(); + } + } + + explicit + thread_handle( boost::function<void()> const & f ): + t_(boost::bind(thread_wrapper,f,boost::ref(err_))) + { + } + + friend boost::shared_ptr<thread_handle> create_thread( boost::function<void()> const & f ); + friend void join( thread_handle & t ); + }; + +boost::shared_ptr<thread_handle> +create_thread( boost::function<void()> const & f ) + { + boost::shared_ptr<thread_handle> t( new thread_handle(f) ); + return t; + } + +void +join( thread_handle & t ) + { + t.t_.join(); + assert(t.err_); + rethrow_exception(t.err_); + } + +boost::detail::atomic_count exc_count(0); + +struct +exc: + virtual boost::exception, + virtual std::exception + { + exc() + { + ++exc_count; + } + + exc( exc const & e ): + boost::exception(e), + std::exception(e) + { + ++exc_count; + } + + virtual + ~exc() BOOST_NOEXCEPT_OR_NOTHROW + { + --exc_count; + } + + private: + + exc & operator=( exc const & ); + }; + +typedef boost::error_info<struct answer_,int> answer; + +void +thread_func() + { + BOOST_THROW_EXCEPTION(exc() << answer(42)); + } + +void +check( boost::shared_ptr<thread_handle> const & t ) + { + try + { + join(*t); + BOOST_TEST(false); + } + catch( + exc & e ) + { + int const * a = boost::get_error_info<answer>(e); + BOOST_TEST(a && *a==42); + } + } + +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 +main() + { + test_deep_copy(); + BOOST_TEST(++exc_count==1); + try + { + std::vector< boost::shared_ptr<thread_handle> > threads; + std::generate_n(std::inserter(threads,threads.end()),1,boost::bind(create_thread,thread_func)); + std::for_each(threads.begin(),threads.end(),check); + return boost::report_errors(); + } + catch( + ... ) + { + std::cerr << + "Caught unexpected exception.\n" + "Output from current_exception_diagnostic_information:\n" << + boost::current_exception_diagnostic_information() << std::endl; + return 42; + } + BOOST_TEST(!--exc_count); + } diff --git a/src/boost/libs/exception/test/exception_test.cpp b/src/boost/libs/exception/test/exception_test.cpp new file mode 100644 index 00000000..cc6537a8 --- /dev/null +++ b/src/boost/libs/exception/test/exception_test.cpp @@ -0,0 +1,35 @@ +//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) + +#include <boost/exception/exception.hpp> +#include <boost/detail/lightweight_test.hpp> + +class +test_exception: + public boost::exception + { + }; + +void +test_throw() + { + throw test_exception(); + } + +int +main() + { + try + { + test_throw(); + BOOST_TEST(false); + } + catch( + test_exception & ) + { + BOOST_TEST(true); + } + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/get_error_info_hpp_test.cpp b/src/boost/libs/exception/test/get_error_info_hpp_test.cpp new file mode 100644 index 00000000..61013fc8 --- /dev/null +++ b/src/boost/libs/exception/test/get_error_info_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/get_error_info.hpp> +#include <boost/exception/get_error_info.hpp> diff --git a/src/boost/libs/exception/test/has_to_string_test.cpp b/src/boost/libs/exception/test/has_to_string_test.cpp new file mode 100644 index 00000000..4479d50e --- /dev/null +++ b/src/boost/libs/exception/test/has_to_string_test.cpp @@ -0,0 +1,57 @@ +//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) + +#include <boost/exception/to_string.hpp> +#include <boost/detail/lightweight_test.hpp> + +namespace +n1 + { + struct + c1 + { + }; + } + +namespace +n2 + { + struct + c2 + { + }; + + std::string + to_string( c2 const & ) + { + return "c2"; + } + } + +namespace +n3 + { + struct + c3 + { + }; + + std::ostream & + operator<<( std::ostream & s, c3 const & ) + { + return s << "c3"; + } + } + +int +main() + { + using namespace boost; + BOOST_TEST( !has_to_string<n1::c1>::value ); + BOOST_TEST( has_to_string<n2::c2>::value ); + BOOST_TEST( has_to_string<n3::c3>::value ); + BOOST_TEST( has_to_string<int>::value ); + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/helper1.cpp b/src/boost/libs/exception/test/helper1.cpp new file mode 100644 index 00000000..f25f49f8 --- /dev/null +++ b/src/boost/libs/exception/test/helper1.cpp @@ -0,0 +1,22 @@ +//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) + +#include <boost/exception/exception.hpp> +#include <stdexcept> +#include <string> + +namespace +boost + { + namespace + exception_test + { + void + throw_length_error() + { + throw enable_error_info( std::length_error("exception test length error") ); + } + } + } diff --git a/src/boost/libs/exception/test/helper1.hpp b/src/boost/libs/exception/test/helper1.hpp new file mode 100644 index 00000000..adf6ec12 --- /dev/null +++ b/src/boost/libs/exception/test/helper1.hpp @@ -0,0 +1,19 @@ +//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) + +#ifndef UUID_4AEB7924CA2E11DC888A8C9355D89593 +#define UUID_4AEB7924CA2E11DC888A8C9355D89593 + +namespace +boost + { + namespace + exception_test + { + void throw_length_error(); + } + } + +#endif diff --git a/src/boost/libs/exception/test/helper2.cpp b/src/boost/libs/exception/test/helper2.cpp new file mode 100644 index 00000000..88809a7e --- /dev/null +++ b/src/boost/libs/exception/test/helper2.cpp @@ -0,0 +1,72 @@ +//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) + +#include "helper2.hpp" +#include <boost/throw_exception.hpp> + +namespace +boost + { + namespace + exception_test + { + inline + derives_boost_exception:: + derives_boost_exception( int x ): + x_(x) + { + } + + derives_boost_exception:: + ~derives_boost_exception() BOOST_NOEXCEPT_OR_NOTHROW + { + } + + inline + derives_boost_exception_virtually:: + derives_boost_exception_virtually( int x ): + x_(x) + { + } + + derives_boost_exception_virtually:: + ~derives_boost_exception_virtually() BOOST_NOEXCEPT_OR_NOTHROW + { + } + + inline + derives_std_exception:: + derives_std_exception( int x ): + x_(x) + { + } + + derives_std_exception:: + ~derives_std_exception() BOOST_NOEXCEPT_OR_NOTHROW + { + } + + template <> + void + throw_test_exception<derives_boost_exception>( int x ) + { + boost::throw_exception( derives_boost_exception(x) ); + } + + template <> + void + throw_test_exception<derives_boost_exception_virtually>( int x ) + { + boost::throw_exception( derives_boost_exception_virtually(x) ); + } + + template <> + void + throw_test_exception<derives_std_exception>( int x ) + { + boost::throw_exception( derives_std_exception(x) ); + } + } + } diff --git a/src/boost/libs/exception/test/helper2.hpp b/src/boost/libs/exception/test/helper2.hpp new file mode 100644 index 00000000..885eee57 --- /dev/null +++ b/src/boost/libs/exception/test/helper2.hpp @@ -0,0 +1,61 @@ +//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) + +#ifndef UUID_BC765EB4CA2A11DCBDC5828355D89593 +#define UUID_BC765EB4CA2A11DCBDC5828355D89593 + +#include <boost/exception/exception.hpp> +#include <exception> + +namespace +boost + { + namespace + exception_test + { + struct + derives_boost_exception: + public boost::exception, + public std::exception + { + explicit derives_boost_exception( int x ); + virtual ~derives_boost_exception() BOOST_NOEXCEPT_OR_NOTHROW; + int x_; + }; + + struct + derives_boost_exception_virtually: + public virtual boost::exception, + public std::exception + { + explicit derives_boost_exception_virtually( int x ); + virtual ~derives_boost_exception_virtually() BOOST_NOEXCEPT_OR_NOTHROW; + int x_; + }; + + struct + derives_std_exception: + public std::exception + { + explicit derives_std_exception( int x ); + virtual ~derives_std_exception() BOOST_NOEXCEPT_OR_NOTHROW; + int x_; + }; + + template <class> + void throw_test_exception( int ); + + template <> + void throw_test_exception<derives_boost_exception>( int ); + + template <> + void throw_test_exception<derives_boost_exception_virtually>( int ); + + template <> + void throw_test_exception<derives_std_exception>( int ); + } + } + +#endif diff --git a/src/boost/libs/exception/test/info_hpp_test.cpp b/src/boost/libs/exception/test/info_hpp_test.cpp new file mode 100644 index 00000000..25d382d1 --- /dev/null +++ b/src/boost/libs/exception/test/info_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/info.hpp> +#include <boost/exception/info.hpp> diff --git a/src/boost/libs/exception/test/info_tuple_hpp_test.cpp b/src/boost/libs/exception/test/info_tuple_hpp_test.cpp new file mode 100644 index 00000000..293329cc --- /dev/null +++ b/src/boost/libs/exception/test/info_tuple_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/info_tuple.hpp> +#include <boost/exception/info_tuple.hpp> diff --git a/src/boost/libs/exception/test/is_output_streamable_test.cpp b/src/boost/libs/exception/test/is_output_streamable_test.cpp new file mode 100644 index 00000000..963989f3 --- /dev/null +++ b/src/boost/libs/exception/test/is_output_streamable_test.cpp @@ -0,0 +1,49 @@ +//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) + +#include <boost/exception/detail/is_output_streamable.hpp> + +namespace +n1 + { + class + c1 + { + }; + } + +namespace +n2 + { + class + c2 + { + }; + + std::ostream & + operator<<( std::ostream & s, c2 const & ) + { + s << "c2"; + return s; + } + } + +template <bool Test> +struct test; + +template <> +struct +test<true> + { + }; + +int +main() + { + test<!boost::is_output_streamable<n1::c1>::value>(); + test<boost::is_output_streamable<n2::c2>::value>(); + test<boost::is_output_streamable<int>::value>(); + return 0; + } diff --git a/src/boost/libs/exception/test/no_exceptions_test.cpp b/src/boost/libs/exception/test/no_exceptions_test.cpp new file mode 100644 index 00000000..2e8665a7 --- /dev/null +++ b/src/boost/libs/exception/test/no_exceptions_test.cpp @@ -0,0 +1,52 @@ +//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) + +#define BOOST_NO_EXCEPTIONS +#include <boost/config.hpp> +#include <boost/throw_exception.hpp> +#include <boost/exception/info.hpp> +#include <boost/exception/diagnostic_information.hpp> +#include <boost/core/lightweight_test.hpp> +#include <stdlib.h> + +struct +my_exception: + boost::exception, + std::exception + { + char const * + what() const BOOST_NOEXCEPT_OR_NOTHROW + { + return "my_exception"; + } + }; + +typedef boost::error_info<struct my_tag,int> my_int; + +bool called=false; + +namespace +boost + { + void + throw_exception( std::exception const & x ) + { + called=true; + std::string s=boost::diagnostic_information(x); + std::cout << s; +#ifndef BOOST_NO_RTTI + BOOST_TEST(s.find("my_tag")!=std::string::npos); +#endif + exit(boost::report_errors()); + } + } + +int +main() + { + BOOST_THROW_EXCEPTION( my_exception() << my_int(42) ); + BOOST_TEST(called); + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/refcount_ptr_test.cpp b/src/boost/libs/exception/test/refcount_ptr_test.cpp new file mode 100644 index 00000000..283f5703 --- /dev/null +++ b/src/boost/libs/exception/test/refcount_ptr_test.cpp @@ -0,0 +1,108 @@ +//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) + +#include <boost/exception/exception.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct +test_type + { + test_type( int & count ): + count_(count) + { + BOOST_TEST(count_==42); + count_=0; + } + + ~test_type() + { + BOOST_TEST(!count_); + count_=42; + } + + void + add_ref() + { + ++count_; + } + + bool + release() + { + if( --count_ ) + return false; + else + { + delete this; + return true; + } + } + + private: + + test_type( test_type const & ); + test_type & operator=( test_type const & ); + + int & count_; + }; + +int +main() + { + using boost::exception_detail::refcount_ptr; + + { + refcount_ptr<test_type> x; + BOOST_TEST(!x.get()); + } + + { + int count=42; + test_type * a=new test_type(count); + BOOST_TEST(!count); + { + refcount_ptr<test_type> p; + BOOST_TEST(0==count); + p.adopt(a); + BOOST_TEST(p.get()==a); + BOOST_TEST(1==count); + { + refcount_ptr<test_type> q; + q.adopt(p.get()); + BOOST_TEST(q.get()==a); + BOOST_TEST(2==count); + { + refcount_ptr<test_type> t(p); + BOOST_TEST(t.get()==a); + BOOST_TEST(3==count); + { + refcount_ptr<test_type> n; + n=t; + BOOST_TEST(n.get()==a); + BOOST_TEST(4==count); + int cb=42; + test_type * b=new test_type(cb); + BOOST_TEST(0==cb); + n.adopt(b); + BOOST_TEST(1==cb); + BOOST_TEST(n.get()==b); + BOOST_TEST(3==count); + n.adopt(0); + BOOST_TEST(42==cb); + } + BOOST_TEST(t.get()==a); + BOOST_TEST(3==count); + } + BOOST_TEST(q.get()==a); + BOOST_TEST(2==count); + } + BOOST_TEST(p.get()==a); + BOOST_TEST(1==count); + } + BOOST_TEST(42==count); + } + + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/throw_exception_fail.cpp b/src/boost/libs/exception/test/throw_exception_fail.cpp new file mode 100644 index 00000000..9f34104e --- /dev/null +++ b/src/boost/libs/exception/test/throw_exception_fail.cpp @@ -0,0 +1,18 @@ +//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) + +#include <boost/throw_exception.hpp> + +struct +my_exception + { + }; + +void +tester() + { + //Must not compile, throw_exception requires exception types to derive std::exception. + boost::throw_exception(my_exception()); + } diff --git a/src/boost/libs/exception/test/throw_exception_test.cpp b/src/boost/libs/exception/test/throw_exception_test.cpp new file mode 100644 index 00000000..c6c0eeb7 --- /dev/null +++ b/src/boost/libs/exception/test/throw_exception_test.cpp @@ -0,0 +1,148 @@ +//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) + +#include "helper2.hpp" +#include <boost/exception/get_error_info.hpp> +#include <boost/exception/info.hpp> +#include <boost/exception_ptr.hpp> +#include <boost/detail/lightweight_test.hpp> + +typedef boost::error_info<struct tag_test_int,int> test_data; + +struct +exception1: + std::exception + { + }; + +struct +exception2: + std::exception, + boost::exception + { + }; + +void +boost_throw_exception_test() + { + try + { + BOOST_THROW_EXCEPTION(exception1()); + BOOST_ERROR("BOOST_THROW_EXCEPTION failed to throw."); + } + catch( + boost::exception & x ) + { + char const * const * function=boost::get_error_info<boost::throw_function>(x); + char const * const * file=boost::get_error_info<boost::throw_file>(x); + int const * line=boost::get_error_info<boost::throw_line>(x); + BOOST_TEST( file && *file ); + BOOST_TEST( function && *function ); + BOOST_TEST( line && *line==32 ); + } + catch( + ... ) + { + BOOST_TEST(false); + } + try + { + BOOST_THROW_EXCEPTION(exception2() << test_data(42)); + BOOST_ERROR("BOOST_THROW_EXCEPTION failed to throw."); + } + catch( + boost::exception & x ) + { + char const * const * function=boost::get_error_info<boost::throw_function>(x); + char const * const * file=boost::get_error_info<boost::throw_file>(x); + int const * line=boost::get_error_info<boost::throw_line>(x); + int const * data=boost::get_error_info<test_data>(x); + BOOST_TEST( file && *file ); + BOOST_TEST( function && *function ); + BOOST_TEST( line && *line==52 ); + BOOST_TEST( data && *data==42 ); + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + +void +throw_fwd( void (*thrower)(int) ) + { + try + { + thrower(42); + } + catch( + boost::exception & x ) + { + x << test_data(42); + throw; + } + } + +template <class T> +void +tester() + { + try + { + throw_fwd( &boost::exception_test::throw_test_exception<T> ); + BOOST_ASSERT(false); + } + catch( + ... ) + { + boost::exception_ptr p = boost::current_exception(); + try + { + rethrow_exception(p); + BOOST_TEST(false); + } + catch( + T & y ) + { +#ifdef BOOST_NO_RTTI + try + { + throw; + } + catch( + boost::exception & y ) + { +#endif + BOOST_TEST(boost::get_error_info<test_data>(y)); + if( int const * d=boost::get_error_info<test_data>(y) ) + BOOST_TEST(*d==42); +#ifdef BOOST_NO_RTTI + } + catch( + ... ) + { + BOOST_TEST(false); + } +#endif + BOOST_TEST(y.x_==42); + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + } + +int +main() + { + boost_throw_exception_test(); + tester<boost::exception_test::derives_boost_exception>(); + tester<boost::exception_test::derives_boost_exception_virtually>(); + tester<boost::exception_test::derives_std_exception>(); + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/to_string_fail.cpp b/src/boost/libs/exception/test/to_string_fail.cpp new file mode 100644 index 00000000..1bb3a2c8 --- /dev/null +++ b/src/boost/libs/exception/test/to_string_fail.cpp @@ -0,0 +1,23 @@ +//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) + +#include <boost/exception/to_string.hpp> + +namespace +n1 + { + struct + c1 + { + }; + } + +int +tester() + { + using namespace boost; + (void) to_string(n1::c1()); + return 1; + } diff --git a/src/boost/libs/exception/test/to_string_hpp_test.cpp b/src/boost/libs/exception/test/to_string_hpp_test.cpp new file mode 100644 index 00000000..560e3b16 --- /dev/null +++ b/src/boost/libs/exception/test/to_string_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/to_string.hpp> +#include <boost/exception/to_string.hpp> diff --git a/src/boost/libs/exception/test/to_string_stub_hpp_test.cpp b/src/boost/libs/exception/test/to_string_stub_hpp_test.cpp new file mode 100644 index 00000000..c5ad03f1 --- /dev/null +++ b/src/boost/libs/exception/test/to_string_stub_hpp_test.cpp @@ -0,0 +1,7 @@ +//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) + +#include <boost/exception/to_string_stub.hpp> +#include <boost/exception/to_string_stub.hpp> diff --git a/src/boost/libs/exception/test/to_string_stub_test.cpp b/src/boost/libs/exception/test/to_string_stub_test.cpp new file mode 100644 index 00000000..0b5cab87 --- /dev/null +++ b/src/boost/libs/exception/test/to_string_stub_test.cpp @@ -0,0 +1,98 @@ +//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) + +#include <boost/exception/to_string_stub.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> + +namespace +n1 + { + class + c1 + { + }; + + std::string + to_string( c1 const & ) + { + return "c1"; + } + } + +namespace +n2 + { + class + c2 + { + }; + + std::ostream & + operator<<( std::ostream & s, c2 const & ) + { + s << "c2"; + return s; + } + } + +namespace +n3 + { + class + c3 + { + }; + + std::ostream & + operator<<( std::ostream & s, c3 const & ) + { + s << "bad"; + return s; + } + + std::string + to_string( c3 const & ) + { + return "c3"; + } + } + +namespace +boost + { + class + to_string_tester + { + }; + } + +template <class T> +struct +my_stub + { + std::string + operator()( T const & ) + { + return "stub"; + } + }; + +int +main() + { + using namespace boost; + BOOST_TEST( to_string(42)=="42" ); + BOOST_TEST( to_string(n1::c1())=="c1" ); + BOOST_TEST( to_string(n2::c2())=="c2" ); + BOOST_TEST( to_string(n3::c3())=="c3" ); + BOOST_TEST( to_string_stub(42)=="42" ); + BOOST_TEST( to_string_stub(n1::c1())=="c1" ); + BOOST_TEST( to_string_stub(n2::c2())=="c2" ); + BOOST_TEST( to_string_stub(n3::c3())=="c3" ); + BOOST_TEST( to_string_stub(to_string_tester(),my_stub<to_string_tester>())=="stub" ); + BOOST_TEST( !to_string_stub(to_string_tester()).empty() ); + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/to_string_test.cpp b/src/boost/libs/exception/test/to_string_test.cpp new file mode 100644 index 00000000..eb185342 --- /dev/null +++ b/src/boost/libs/exception/test/to_string_test.cpp @@ -0,0 +1,56 @@ +//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) + +#include <boost/exception/to_string.hpp> +#include <boost/detail/lightweight_test.hpp> + +namespace +n1 + { + struct + c1 + { + }; + } + +namespace +n2 + { + struct + c2 + { + }; + + std::string + to_string( c2 const & ) + { + return "c2"; + } + } + +namespace +n3 + { + struct + c3 + { + }; + + std::ostream & + operator<<( std::ostream & s, c3 const & ) + { + return s << "c3"; + } + } + +int +main() + { + using namespace boost; + BOOST_TEST( "c2"==to_string(n2::c2()) ); + BOOST_TEST( "c3"==to_string(n3::c3()) ); + BOOST_TEST( "42"==to_string(42) ); + return boost::report_errors(); + } diff --git a/src/boost/libs/exception/test/unknown_exception_test.cpp b/src/boost/libs/exception/test/unknown_exception_test.cpp new file mode 100644 index 00000000..bf474ba1 --- /dev/null +++ b/src/boost/libs/exception/test/unknown_exception_test.cpp @@ -0,0 +1,142 @@ +//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) + +#include <boost/exception_ptr.hpp> +#include <boost/exception/get_error_info.hpp> +#include <boost/exception/info.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) +struct tag_test {}; +#endif + +typedef boost::error_info<struct tag_test,int> test; + +struct +test_boost_exception: + boost::exception + { + }; + +void +throw_boost_exception() + { + throw test_boost_exception() << test(42); + } + +void +throw_unknown_exception() + { + struct + test_exception: + std::exception + { + }; + throw test_exception(); + } + +int +main() + { + try + { + throw_boost_exception(); + } + catch( + ... ) + { + boost::exception_ptr ep=boost::current_exception(); + try + { + rethrow_exception(ep); + } + catch( + boost::unknown_exception & x ) + { + if( int const * d=boost::get_error_info<test>(x) ) + BOOST_TEST( 42==*d ); + else + 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); + } + try + { + rethrow_exception(ep); + } + catch( + boost::exception & x ) + { + if( int const * d=boost::get_error_info<test>(x) ) + BOOST_TEST( 42==*d ); + else + BOOST_TEST(false); + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + try + { + throw_unknown_exception(); + } + catch( + ... ) + { + boost::exception_ptr ep=boost::current_exception(); + try + { + rethrow_exception(ep); + } + catch( + boost::unknown_exception & ) + { + } + catch( + std::exception & ) + { + //Yay! Non-intrusive cloning supported! + } + catch( + ... ) + { + BOOST_TEST(false); + } + try + { + rethrow_exception(ep); + } + catch( + boost::exception & ) + { + } + catch( + std::exception & ) + { + //Yay! Non-intrusive cloning supported! + } + catch( + ... ) + { + BOOST_TEST(false); + } + } + return boost::report_errors(); + } |