diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /boost/exception | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'boost/exception')
27 files changed, 2382 insertions, 0 deletions
diff --git a/boost/exception/all.hpp b/boost/exception/all.hpp new file mode 100644 index 0000000000..9ffe42a9d0 --- /dev/null +++ b/boost/exception/all.hpp @@ -0,0 +1,36 @@ +//Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_316FDA946C0D11DEA9CBAE5255D89593 +#define UUID_316FDA946C0D11DEA9CBAE5255D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <boost/exception/diagnostic_information.hpp> +#include <boost/exception/error_info.hpp> +#include <boost/exception/exception.hpp> +#include <boost/exception/get_error_info.hpp> +#include <boost/exception/info.hpp> +#include <boost/exception/info_tuple.hpp> +#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> +#ifndef BOOST_NO_EXCEPTIONS +#include <boost/exception/errinfo_nested_exception.hpp> +#include <boost/exception_ptr.hpp> +#endif + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/current_exception_cast.hpp b/boost/exception/current_exception_cast.hpp new file mode 100644 index 0000000000..af2f153113 --- /dev/null +++ b/boost/exception/current_exception_cast.hpp @@ -0,0 +1,43 @@ +//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_7E83C166200811DE885E826156D89593 +#define UUID_7E83C166200811DE885E826156D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + template <class E> + inline + E * + current_exception_cast() + { + try + { + throw; + } + catch( + E & e ) + { + return &e; + } + catch( + ...) + { + return 0; + } + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/attribute_noreturn.hpp b/boost/exception/detail/attribute_noreturn.hpp new file mode 100644 index 0000000000..f6a0b5903e --- /dev/null +++ b/boost/exception/detail/attribute_noreturn.hpp @@ -0,0 +1,17 @@ +//Copyright (c) 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_61531AB0680611DEADD5846855D89593 +#define UUID_61531AB0680611DEADD5846855D89593 + +#if defined(_MSC_VER) +#define BOOST_ATTRIBUTE_NORETURN __declspec(noreturn) +#elif defined(__GNUC__) +#define BOOST_ATTRIBUTE_NORETURN __attribute__((noreturn)) +#else +#define BOOST_ATTRIBUTE_NORETURN +#endif + +#endif diff --git a/boost/exception/detail/clone_current_exception.hpp b/boost/exception/detail/clone_current_exception.hpp new file mode 100644 index 0000000000..cc201b908d --- /dev/null +++ b/boost/exception/detail/clone_current_exception.hpp @@ -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) + +#ifndef UUID_81522C0EB56511DFAB613DB0DFD72085 +#define UUID_81522C0EB56511DFAB613DB0DFD72085 + +#ifdef BOOST_NO_EXCEPTIONS +# error This header requires exception handling to be enabled. +#endif + +namespace +boost + { + namespace + exception_detail + { + class clone_base; + +#ifdef BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR + int clone_current_exception_non_intrusive( clone_base const * & cloned ); +#endif + + namespace + clone_current_exception_result + { + int const success=0; + int const bad_alloc=1; + int const bad_exception=2; + int const not_supported=3; + } + + inline + int + clone_current_exception( clone_base const * & cloned ) + { +#ifdef BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR + return clone_current_exception_non_intrusive(cloned); +#else + return clone_current_exception_result::not_supported; +#endif + } + } + } + +#endif diff --git a/boost/exception/detail/error_info_impl.hpp b/boost/exception/detail/error_info_impl.hpp new file mode 100644 index 0000000000..883d313a98 --- /dev/null +++ b/boost/exception/detail/error_info_impl.hpp @@ -0,0 +1,75 @@ +//Copyright (c) 2006-2010 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_CE6983AC753411DDA764247956D89593 +#define UUID_CE6983AC753411DDA764247956D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <string> + +namespace +boost + { + namespace + exception_detail + { + class + error_info_base + { + public: + + virtual std::string tag_typeid_name() const = 0; + virtual std::string value_as_string() const = 0; + + protected: + + ~error_info_base() throw() + { + } + }; + } + + template <class Tag,class T> + class + error_info: + public exception_detail::error_info_base + { + public: + + typedef T value_type; + + error_info( value_type const & value ); + ~error_info() throw(); + + value_type const & + value() const + { + return value_; + } + + value_type & + value() + { + return value_; + } + + private: + + std::string tag_typeid_name() const; + std::string value_as_string() const; + + value_type value_; + }; + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/exception_ptr.hpp b/boost/exception/detail/exception_ptr.hpp new file mode 100644 index 0000000000..b6ccf7e18c --- /dev/null +++ b/boost/exception/detail/exception_ptr.hpp @@ -0,0 +1,503 @@ +//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_618474C2DE1511DEB74A388C56D89593 +#define UUID_618474C2DE1511DEB74A388C56D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <boost/config.hpp> +#ifdef BOOST_NO_EXCEPTIONS +#error This header requires exception handling to be enabled. +#endif +#include <boost/exception/exception.hpp> +#include <boost/exception/info.hpp> +#include <boost/exception/diagnostic_information.hpp> +#include <boost/exception/detail/type_info.hpp> +#include <boost/exception/detail/clone_current_exception.hpp> +#include <boost/shared_ptr.hpp> +#include <stdexcept> +#include <new> +#include <ios> +#include <cstdlib> + +namespace +boost + { + class exception_ptr; + BOOST_ATTRIBUTE_NORETURN void rethrow_exception( exception_ptr const & ); + exception_ptr current_exception(); + + class + exception_ptr + { + typedef boost::shared_ptr<exception_detail::clone_base const> impl; + impl ptr_; + friend void rethrow_exception( exception_ptr const & ); + typedef exception_detail::clone_base const * (impl::*unspecified_bool_type)() const; + public: + exception_ptr() + { + } + explicit + exception_ptr( impl const & ptr ): + ptr_(ptr) + { + } + bool + operator==( exception_ptr const & other ) const + { + return ptr_==other.ptr_; + } + bool + operator!=( exception_ptr const & other ) const + { + return ptr_!=other.ptr_; + } + operator unspecified_bool_type() const + { + return ptr_?&impl::get:0; + } + }; + + template <class T> + inline + exception_ptr + copy_exception( T const & e ) + { + try + { + throw enable_current_exception(e); + } + catch( + ... ) + { + return current_exception(); + } + } + +#ifndef BOOST_NO_RTTI + typedef error_info<struct tag_original_exception_type,std::type_info const *> original_exception_type; + + inline + std::string + to_string( original_exception_type const & x ) + { + return x.value()->name(); + } +#endif + + namespace + exception_detail + { + struct + bad_alloc_: + boost::exception, + std::bad_alloc + { + ~bad_alloc_() throw() { } + }; + + struct + bad_exception_: + boost::exception, + std::bad_exception + { + ~bad_exception_() throw() { } + }; + + template <class Exception> + exception_ptr + get_static_exception_object() + { + Exception ba; + exception_detail::clone_impl<Exception> c(ba); + c << + throw_function(BOOST_CURRENT_FUNCTION) << + throw_file(__FILE__) << + throw_line(__LINE__); + static exception_ptr ep(shared_ptr<exception_detail::clone_base const>(new exception_detail::clone_impl<Exception>(c))); + return ep; + } + + template <class Exception> + struct + exception_ptr_static_exception_object + { + static exception_ptr const e; + }; + + template <class Exception> + exception_ptr const + exception_ptr_static_exception_object<Exception>:: + e = get_static_exception_object<Exception>(); + } + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + class + unknown_exception: + public boost::exception, + public std::exception + { + public: + + unknown_exception() + { + } + + explicit + unknown_exception( std::exception const & e ) + { + add_original_type(e); + } + + explicit + unknown_exception( boost::exception const & e ): + boost::exception(e) + { + add_original_type(e); + } + + ~unknown_exception() throw() + { + } + + private: + + template <class E> + void + add_original_type( E const & e ) + { +#ifndef BOOST_NO_RTTI + (*this) << original_exception_type(&typeid(e)); +#endif + } + }; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + namespace + exception_detail + { + template <class T> + class + current_exception_std_exception_wrapper: + public T, + public boost::exception + { + public: + + explicit + current_exception_std_exception_wrapper( T const & e1 ): + T(e1) + { + add_original_type(e1); + } + + current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ): + T(e1), + boost::exception(e2) + { + add_original_type(e1); + } + + ~current_exception_std_exception_wrapper() throw() + { + } + + private: + + template <class E> + void + add_original_type( E const & e ) + { +#ifndef BOOST_NO_RTTI + (*this) << original_exception_type(&typeid(e)); +#endif + } + }; + +#ifdef BOOST_NO_RTTI + template <class T> + boost::exception const * + get_boost_exception( T const * ) + { + try + { + throw; + } + catch( + boost::exception & x ) + { + return &x; + } + catch(...) + { + return 0; + } + } +#else + template <class T> + boost::exception const * + get_boost_exception( T const * x ) + { + return dynamic_cast<boost::exception const *>(x); + } +#endif + + template <class T> + inline + exception_ptr + current_exception_std_exception( T const & e1 ) + { + if( boost::exception const * e2 = get_boost_exception(&e1) ) + return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1,*e2)); + else + return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1)); + } + + inline + exception_ptr + current_exception_unknown_exception() + { + return boost::copy_exception(unknown_exception()); + } + + inline + exception_ptr + current_exception_unknown_boost_exception( boost::exception const & e ) + { + return boost::copy_exception(unknown_exception(e)); + } + + inline + exception_ptr + current_exception_unknown_std_exception( std::exception const & e ) + { + if( boost::exception const * be = get_boost_exception(&e) ) + return current_exception_unknown_boost_exception(*be); + else + return boost::copy_exception(unknown_exception(e)); + } + + inline + exception_ptr + current_exception_impl() + { + exception_detail::clone_base const * e=0; + switch( + exception_detail::clone_current_exception(e) ) + { + case exception_detail::clone_current_exception_result:: + success: + { + BOOST_ASSERT(e!=0); + return exception_ptr(shared_ptr<exception_detail::clone_base const>(e)); + } + case exception_detail::clone_current_exception_result:: + bad_alloc: + { + BOOST_ASSERT(!e); + return exception_detail::exception_ptr_static_exception_object<bad_alloc_>::e; + } + case exception_detail::clone_current_exception_result:: + bad_exception: + { + BOOST_ASSERT(!e); + return exception_detail::exception_ptr_static_exception_object<bad_exception_>::e; + } + default: + BOOST_ASSERT(0); + case exception_detail::clone_current_exception_result:: + not_supported: + { + BOOST_ASSERT(!e); + try + { + throw; + } + catch( + exception_detail::clone_base & e ) + { + return exception_ptr(shared_ptr<exception_detail::clone_base const>(e.clone())); + } + catch( + std::domain_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::invalid_argument & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::length_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::out_of_range & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::logic_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::range_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::overflow_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::underflow_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::ios_base::failure & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::runtime_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::bad_alloc & e ) + { + return exception_detail::current_exception_std_exception(e); + } +#ifndef BOOST_NO_TYPEID + catch( + std::bad_cast & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::bad_typeid & e ) + { + return exception_detail::current_exception_std_exception(e); + } +#endif + catch( + std::bad_exception & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::exception & e ) + { + return exception_detail::current_exception_unknown_std_exception(e); + } + catch( + boost::exception & e ) + { + return exception_detail::current_exception_unknown_boost_exception(e); + } + catch( + ... ) + { + return exception_detail::current_exception_unknown_exception(); + } + } + } + } + } + + inline + exception_ptr + current_exception() + { + exception_ptr ret; + try + { + ret=exception_detail::current_exception_impl(); + } + catch( + std::bad_alloc & ) + { + ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_alloc_>::e; + } + catch( + ... ) + { + ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_exception_>::e; + } + BOOST_ASSERT(ret); + return ret; + } + + BOOST_ATTRIBUTE_NORETURN + inline + void + rethrow_exception( exception_ptr const & p ) + { + BOOST_ASSERT(p); + p.ptr_->rethrow(); + BOOST_ASSERT(0); + std::abort(); + } + + inline + std::string + diagnostic_information( exception_ptr const & p ) + { + if( p ) + try + { + rethrow_exception(p); + } + catch( + ... ) + { + return current_exception_diagnostic_information(); + } + return "<empty>"; + } + + inline + std::string + to_string( exception_ptr const & p ) + { + std::string s='\n'+diagnostic_information(p); + std::string padding(" "); + std::string r; + bool f=false; + for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i ) + { + if( f ) + r+=padding; + char c=*i; + r+=c; + f=(c=='\n'); + } + return r; + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/is_output_streamable.hpp b/boost/exception/detail/is_output_streamable.hpp new file mode 100644 index 0000000000..743313c1ec --- /dev/null +++ b/boost/exception/detail/is_output_streamable.hpp @@ -0,0 +1,60 @@ +//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_898984B4076411DD973EDFA055D89593 +#define UUID_898984B4076411DD973EDFA055D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <ostream> + +namespace +boost + { + namespace + to_string_detail + { + struct + partial_ordering_helper1 + { + template <class CharT,class Traits> + partial_ordering_helper1( std::basic_ostream<CharT,Traits> & ); + }; + + struct + partial_ordering_helper2 + { + template <class T> + partial_ordering_helper2( T const & ); + }; + + char operator<<( partial_ordering_helper1, partial_ordering_helper2 ); + + template <class T,class CharT,class Traits> + struct + is_output_streamable_impl + { + static std::basic_ostream<CharT,Traits> & f(); + static T const & g(); + enum e { value=1!=(sizeof(f()<<g())) }; + }; + } + + template <class T, class CharT=char, class Traits=std::char_traits<CharT> > + struct + is_output_streamable + { + enum e { value=to_string_detail::is_output_streamable_impl<T,CharT,Traits>::value }; + }; + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/object_hex_dump.hpp b/boost/exception/detail/object_hex_dump.hpp new file mode 100644 index 0000000000..ccf1bac3f7 --- /dev/null +++ b/boost/exception/detail/object_hex_dump.hpp @@ -0,0 +1,50 @@ +//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_6F463AC838DF11DDA3E6909F56D89593 +#define UUID_6F463AC838DF11DDA3E6909F56D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <boost/exception/detail/type_info.hpp> +#include <iomanip> +#include <ios> +#include <string> +#include <sstream> +#include <cstdlib> + +namespace +boost + { + namespace + exception_detail + { + template <class T> + inline + std::string + object_hex_dump( T const & x, std::size_t max_size=16 ) + { + std::ostringstream s; + s << "type: " << type_name<T>() << ", size: " << sizeof(T) << ", dump: "; + std::size_t n=sizeof(T)>max_size?max_size:sizeof(T); + s.fill('0'); + s.width(2); + unsigned char const * b=reinterpret_cast<unsigned char const *>(&x); + s << std::setw(2) << std::hex << (unsigned int)*b; + for( unsigned char const * e=b+n; ++b!=e; ) + s << " " << std::setw(2) << std::hex << (unsigned int)*b; + return s.str(); + } + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/type_info.hpp b/boost/exception/detail/type_info.hpp new file mode 100644 index 0000000000..92f846468c --- /dev/null +++ b/boost/exception/detail/type_info.hpp @@ -0,0 +1,83 @@ +//Copyright (c) 2006-2010 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_C3E1741C754311DDB2834CCA55D89593 +#define UUID_C3E1741C754311DDB2834CCA55D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <boost/detail/sp_typeinfo.hpp> +#include <boost/current_function.hpp> +#include <boost/config.hpp> +#ifndef BOOST_NO_TYPEID +#include <boost/units/detail/utility.hpp> +#endif +#include <string> + +namespace +boost + { + template <class T> + inline + std::string + tag_type_name() + { +#ifdef BOOST_NO_TYPEID + return BOOST_CURRENT_FUNCTION; +#else + return units::detail::demangle(typeid(T*).name()); +#endif + } + + template <class T> + inline + std::string + type_name() + { +#ifdef BOOST_NO_TYPEID + return BOOST_CURRENT_FUNCTION; +#else + return units::detail::demangle(typeid(T).name()); +#endif + } + + namespace + exception_detail + { + struct + type_info_ + { + detail::sp_typeinfo const * type_; + + explicit + type_info_( detail::sp_typeinfo const & type ): + type_(&type) + { + } + + friend + bool + operator<( type_info_ const & a, type_info_ const & b ) + { + return 0!=(a.type_->before(*b.type_)); + } + }; + } + } + +#define BOOST_EXCEPTION_STATIC_TYPEID(T) ::boost::exception_detail::type_info_(BOOST_SP_TYPEID(T)) + +#ifndef BOOST_NO_RTTI +#define BOOST_EXCEPTION_DYNAMIC_TYPEID(x) ::boost::exception_detail::type_info_(typeid(x)) +#endif + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/diagnostic_information.hpp b/boost/exception/diagnostic_information.hpp new file mode 100644 index 0000000000..ef89d73144 --- /dev/null +++ b/boost/exception/diagnostic_information.hpp @@ -0,0 +1,200 @@ +//Copyright (c) 2006-2010 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_0552D49838DD11DD90146B8956D89593 +#define UUID_0552D49838DD11DD90146B8956D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <boost/config.hpp> +#include <boost/exception/get_error_info.hpp> +#include <boost/exception/info.hpp> +#include <boost/utility/enable_if.hpp> +#ifndef BOOST_NO_RTTI +#include <boost/units/detail/utility.hpp> +#endif +#include <exception> +#include <sstream> +#include <string> + +#ifndef BOOST_NO_EXCEPTIONS +#include <boost/exception/current_exception_cast.hpp> +namespace +boost + { + namespace + exception_detail + { + std::string diagnostic_information_impl( boost::exception const *, std::exception const *, bool ); + } + + inline + std::string + current_exception_diagnostic_information() + { + boost::exception const * be=current_exception_cast<boost::exception const>(); + std::exception const * se=current_exception_cast<std::exception const>(); + if( be || se ) + return exception_detail::diagnostic_information_impl(be,se,true); + else + return "No diagnostic information available."; + } + } +#endif + +namespace +boost + { + namespace + exception_detail + { + inline + exception const * + get_boost_exception( exception const * e ) + { + return e; + } + + inline + exception const * + get_boost_exception( ... ) + { + return 0; + } + + inline + std::exception const * + get_std_exception( std::exception const * e ) + { + return e; + } + + inline + std::exception const * + get_std_exception( ... ) + { + return 0; + } + + inline + char const * + get_diagnostic_information( exception const & x, char const * header ) + { +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + error_info_container * c=x.data_.get(); + if( !c ) + x.data_.adopt(c=new exception_detail::error_info_container_impl); + char const * di=c->diagnostic_information(header); + BOOST_ASSERT(di!=0); + return di; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(...) + { + return 0; + } +#endif + } + + inline + std::string + diagnostic_information_impl( boost::exception const * be, std::exception const * se, bool with_what ) + { + if( !be && !se ) + return "Unknown exception."; +#ifndef BOOST_NO_RTTI + if( !be ) + be=dynamic_cast<boost::exception const *>(se); + if( !se ) + se=dynamic_cast<std::exception const *>(be); +#endif + char const * wh=0; + if( with_what && se ) + { + wh=se->what(); + if( be && exception_detail::get_diagnostic_information(*be,0)==wh ) + return wh; + } + std::ostringstream tmp; + if( be ) + { + char const * const * f=get_error_info<throw_file>(*be); + int const * l=get_error_info<throw_line>(*be); + char const * const * fn=get_error_info<throw_function>(*be); + if( !f && !l && !fn ) + tmp << "Throw location unknown (consider using BOOST_THROW_EXCEPTION)\n"; + else + { + if( f ) + { + tmp << *f; + if( int const * l=get_error_info<throw_line>(*be) ) + tmp << '(' << *l << "): "; + } + tmp << "Throw in function "; + if( char const * const * fn=get_error_info<throw_function>(*be) ) + tmp << *fn; + else + tmp << "(unknown)"; + tmp << '\n'; + } + } +#ifndef BOOST_NO_RTTI + tmp << std::string("Dynamic exception type: ") << + units::detail::demangle((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()) << '\n'; +#endif + if( with_what && se ) + tmp << "std::exception::what: " << wh << '\n'; + if( be ) + if( char const * s=exception_detail::get_diagnostic_information(*be,tmp.str().c_str()) ) + if( *s ) + return s; + return tmp.str(); + } + } + + template <class T> + std::string + diagnostic_information( T const & e ) + { + return exception_detail::diagnostic_information_impl(exception_detail::get_boost_exception(&e),exception_detail::get_std_exception(&e),true); + } + + inline + char const * + diagnostic_information_what( exception const & e ) throw() + { + char const * w=0; +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + (void) exception_detail::diagnostic_information_impl(&e,0,false); + if( char const * di=exception_detail::get_diagnostic_information(e,0) ) + return di; + else + return "Failed to produce boost::diagnostic_information_what()"; +#ifndef BOOST_NO_EXCEPTIONS + } + catch( + ... ) + { + } +#endif + return w; + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/enable_current_exception.hpp b/boost/exception/enable_current_exception.hpp new file mode 100644 index 0000000000..988105378c --- /dev/null +++ b/boost/exception/enable_current_exception.hpp @@ -0,0 +1,6 @@ +//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> diff --git a/boost/exception/enable_error_info.hpp b/boost/exception/enable_error_info.hpp new file mode 100644 index 0000000000..988105378c --- /dev/null +++ b/boost/exception/enable_error_info.hpp @@ -0,0 +1,6 @@ +//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> diff --git a/boost/exception/errinfo_api_function.hpp b/boost/exception/errinfo_api_function.hpp new file mode 100644 index 0000000000..481c61314e --- /dev/null +++ b/boost/exception/errinfo_api_function.hpp @@ -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) + +#ifndef UUID_DDFBB4546C1211DEA4659E9055D89593 +#define UUID_DDFBB4546C1211DEA4659E9055D89593 + +#include "boost/exception/error_info.hpp" + +namespace +boost + { + //Usage hint: + //if( api_function(....)!=0 ) + // BOOST_THROW_EXCEPTION( + // failure() << + // errinfo_api_function("api_function") ); + typedef error_info<struct errinfo_api_function_,char const *> errinfo_api_function; + } + +#endif diff --git a/boost/exception/errinfo_at_line.hpp b/boost/exception/errinfo_at_line.hpp new file mode 100644 index 0000000000..cbd5ccefba --- /dev/null +++ b/boost/exception/errinfo_at_line.hpp @@ -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) + +#ifndef UUID_E7255CE26C1211DE85800C9155D89593 +#define UUID_E7255CE26C1211DE85800C9155D89593 + +namespace +boost + { + template <class Tag,class T> class error_info; + + //Use with parsing errors exceptions, for example in a XML file parser. + typedef error_info<struct errinfo_at_line_,int> errinfo_at_line; + } + +#endif diff --git a/boost/exception/errinfo_errno.hpp b/boost/exception/errinfo_errno.hpp new file mode 100644 index 0000000000..ea74010c94 --- /dev/null +++ b/boost/exception/errinfo_errno.hpp @@ -0,0 +1,44 @@ +//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_F0EE17BE6C1211DE87FF459155D89593 +#define UUID_F0EE17BE6C1211DE87FF459155D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include "boost/exception/info.hpp" +#include <errno.h> +#include <string.h> + +namespace +boost + { + typedef error_info<struct errinfo_errno_,int> errinfo_errno; + + //Usage hint: + //if( c_function(....)!=0 ) + // BOOST_THROW_EXCEPTION( + // failure() << + // errinfo_errno(errno) << + // errinfo_api_function("c_function") ); + inline + std::string + to_string( errinfo_errno const & e ) + { + std::ostringstream tmp; + int v=e.value(); + tmp << v << ", \"" << strerror(v) << "\""; + return tmp.str(); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/errinfo_file_handle.hpp b/boost/exception/errinfo_file_handle.hpp new file mode 100644 index 0000000000..8e6cff8fd8 --- /dev/null +++ b/boost/exception/errinfo_file_handle.hpp @@ -0,0 +1,20 @@ +//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_F79E6EE26C1211DEB26E929155D89593 +#define UUID_F79E6EE26C1211DEB26E929155D89593 + +#include <stdio.h> + +namespace +boost + { + template <class> class weak_ptr; + template <class Tag,class T> class error_info; + + typedef error_info<struct errinfo_file_handle_,weak_ptr<FILE> > errinfo_file_handle; + } + +#endif diff --git a/boost/exception/errinfo_file_name.hpp b/boost/exception/errinfo_file_name.hpp new file mode 100644 index 0000000000..d3cce4d356 --- /dev/null +++ b/boost/exception/errinfo_file_name.hpp @@ -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) + +#ifndef UUID_FEE5120A6C1211DE94E8BC9155D89593 +#define UUID_FEE5120A6C1211DE94E8BC9155D89593 + +#include <string> + +namespace +boost + { + template <class Tag,class T> class error_info; + + //Usage hint: + //FILE * f=fopen(name,mode); + //if( !f ) + // BOOST_THROW_EXCEPTION( + // file_open_error() << + // errinfo_file_name(name) << + // errinfo_file_open_mode(mode) ); + typedef error_info<struct errinfo_file_name_,std::string> errinfo_file_name; + } + +#endif diff --git a/boost/exception/errinfo_file_open_mode.hpp b/boost/exception/errinfo_file_open_mode.hpp new file mode 100644 index 0000000000..f4fba0d5cc --- /dev/null +++ b/boost/exception/errinfo_file_open_mode.hpp @@ -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) + +#ifndef UUID_056F1F266C1311DE8E74299255D89593 +#define UUID_056F1F266C1311DE8E74299255D89593 + +#include <string> + +namespace +boost + { + template <class Tag,class T> class error_info; + + //Usage hint: + //FILE * f=fopen(name,mode); + //if( !f ) + // BOOST_THROW_EXCEPTION( + // file_open_error() << + // errinfo_file_name(name) << + // errinfo_file_open_mode(mode) ); + typedef error_info<struct errinfo_file_open_mode_,std::string> errinfo_file_open_mode; + } + +#endif diff --git a/boost/exception/errinfo_nested_exception.hpp b/boost/exception/errinfo_nested_exception.hpp new file mode 100644 index 0000000000..c3299d1475 --- /dev/null +++ b/boost/exception/errinfo_nested_exception.hpp @@ -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) + +#ifndef UUID_45CC9A82B77511DEB330FC4956D89593 +#define UUID_45CC9A82B77511DEB330FC4956D89593 + +namespace +boost + { + namespace exception_detail { class clone_base; } + template <class Tag,class T> class error_info; + class exception_ptr; + typedef error_info<struct errinfo_nested_exception_,exception_ptr> errinfo_nested_exception; + } + +#endif diff --git a/boost/exception/errinfo_type_info_name.hpp b/boost/exception/errinfo_type_info_name.hpp new file mode 100644 index 0000000000..0b060e2e11 --- /dev/null +++ b/boost/exception/errinfo_type_info_name.hpp @@ -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) + +#ifndef UUID_0E11109E6C1311DEB7EA649255D89593 +#define UUID_0E11109E6C1311DEB7EA649255D89593 + +#include <string> + +namespace +boost + { + template <class Tag,class T> class error_info; + + //Usage hint: + //BOOST_THROW_EXCEPTION( + // bad_type() << + // errinfo_type_info_name(typeid(x).name()) ); + typedef error_info<struct errinfo_type_info_name_,std::string> errinfo_type_info_name; + } + +#endif diff --git a/boost/exception/error_info.hpp b/boost/exception/error_info.hpp new file mode 100644 index 0000000000..2e6832a338 --- /dev/null +++ b/boost/exception/error_info.hpp @@ -0,0 +1,6 @@ +//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) + +namespace boost { template <class Tag,class T> class error_info; } diff --git a/boost/exception/exception.hpp b/boost/exception/exception.hpp new file mode 100644 index 0000000000..9cdfd5c6e8 --- /dev/null +++ b/boost/exception/exception.hpp @@ -0,0 +1,456 @@ +//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_274DA366004E11DCB1DDFE2E56D89593 +#define UUID_274DA366004E11DCB1DDFE2E56D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + namespace + exception_detail + { + template <class T> + class + refcount_ptr + { + public: + + refcount_ptr(): + px_(0) + { + } + + ~refcount_ptr() + { + release(); + } + + refcount_ptr( refcount_ptr const & x ): + px_(x.px_) + { + add_ref(); + } + + refcount_ptr & + operator=( refcount_ptr const & x ) + { + adopt(x.px_); + return *this; + } + + void + adopt( T * px ) + { + release(); + px_=px; + add_ref(); + } + + T * + get() const + { + return px_; + } + + private: + + T * px_; + + void + add_ref() + { + if( px_ ) + px_->add_ref(); + } + + void + release() + { + if( px_ && px_->release() ) + px_=0; + } + }; + } + + //////////////////////////////////////////////////////////////////////// + + template <class Tag,class T> + class error_info; + + typedef error_info<struct throw_function_,char const *> throw_function; + typedef error_info<struct throw_file_,char const *> throw_file; + typedef error_info<struct throw_line_,int> throw_line; + + template <> + class + error_info<throw_function_,char const *> + { + public: + typedef char const * value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info<throw_file_,char const *> + { + public: + typedef char const * value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info<throw_line_,int> + { + public: + typedef int value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + class exception; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + template <class T> + class shared_ptr; + + namespace + exception_detail + { + class error_info_base; + struct type_info_; + + struct + error_info_container + { + virtual char const * diagnostic_information( char const * ) const = 0; + virtual shared_ptr<error_info_base> get( type_info_ const & ) const = 0; + virtual void set( shared_ptr<error_info_base> const &, type_info_ const & ) = 0; + virtual void add_ref() const = 0; + virtual bool release() const = 0; + virtual refcount_ptr<exception_detail::error_info_container> clone() const = 0; + + protected: + + ~error_info_container() throw() + { + } + }; + + template <class> + struct get_info; + + template <> + struct get_info<throw_function>; + + template <> + struct get_info<throw_file>; + + template <> + struct get_info<throw_line>; + + char const * get_diagnostic_information( exception const &, char const * ); + + void copy_boost_exception( exception *, exception const * ); + + template <class E,class Tag,class T> + E const & set_info( E const &, error_info<Tag,T> const & ); + + template <class E> + E const & set_info( E const &, throw_function const & ); + + template <class E> + E const & set_info( E const &, throw_file const & ); + + template <class E> + E const & set_info( E const &, throw_line const & ); + } + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + class + exception + { + protected: + + exception(): + throw_function_(0), + throw_file_(0), + throw_line_(-1) + { + } + +#ifdef __HP_aCC + //On HP aCC, this protected copy constructor prevents throwing boost::exception. + //On all other platforms, the same effect is achieved by the pure virtual destructor. + exception( exception const & x ) throw(): + data_(x.data_), + throw_function_(x.throw_function_), + throw_file_(x.throw_file_), + throw_line_(x.throw_line_) + { + } +#endif + + virtual ~exception() throw() +#ifndef __HP_aCC + = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors. +#endif + ; + +#if (defined(__MWERKS__) && __MWERKS__<=0x3207) || (defined(_MSC_VER) && _MSC_VER<=1310) + public: +#else + private: + + template <class E> + friend E const & exception_detail::set_info( E const &, throw_function const & ); + + template <class E> + friend E const & exception_detail::set_info( E const &, throw_file const & ); + + template <class E> + friend E const & exception_detail::set_info( E const &, throw_line const & ); + + template <class E,class Tag,class T> + friend E const & exception_detail::set_info( E const &, error_info<Tag,T> const & ); + + friend char const * exception_detail::get_diagnostic_information( exception const &, char const * ); + + template <class> + friend struct exception_detail::get_info; + friend struct exception_detail::get_info<throw_function>; + friend struct exception_detail::get_info<throw_file>; + friend struct exception_detail::get_info<throw_line>; + friend void exception_detail::copy_boost_exception( exception *, exception const * ); +#endif + mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_; + mutable char const * throw_function_; + mutable char const * throw_file_; + mutable int throw_line_; + }; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + inline + exception:: + ~exception() throw() + { + } + + namespace + exception_detail + { + template <class E> + E const & + set_info( E const & x, throw_function const & y ) + { + x.throw_function_=y.v_; + return x; + } + + template <class E> + E const & + set_info( E const & x, throw_file const & y ) + { + x.throw_file_=y.v_; + return x; + } + + template <class E> + E const & + set_info( E const & x, throw_line const & y ) + { + x.throw_line_=y.v_; + return x; + } + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { + template <class T> + struct + error_info_injector: + public T, + public exception + { + explicit + error_info_injector( T const & x ): + T(x) + { + } + + ~error_info_injector() throw() + { + } + }; + + struct large_size { char c[256]; }; + large_size dispatch_boost_exception( exception const * ); + + struct small_size { }; + small_size dispatch_boost_exception( void const * ); + + template <class,int> + struct enable_error_info_helper; + + template <class T> + struct + enable_error_info_helper<T,sizeof(large_size)> + { + typedef T type; + }; + + template <class T> + struct + enable_error_info_helper<T,sizeof(small_size)> + { + typedef error_info_injector<T> type; + }; + + template <class T> + struct + enable_error_info_return_type + { + typedef typename enable_error_info_helper<T,sizeof(exception_detail::dispatch_boost_exception(static_cast<T *>(0)))>::type type; + }; + } + + template <class T> + inline + typename + exception_detail::enable_error_info_return_type<T>::type + enable_error_info( T const & x ) + { + typedef typename exception_detail::enable_error_info_return_type<T>::type rt; + return rt(x); + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { + class + clone_base + { + public: + + virtual clone_base const * clone() const = 0; + virtual void rethrow() const = 0; + + virtual + ~clone_base() throw() + { + } + }; + + inline + void + copy_boost_exception( exception * a, exception const * b ) + { + refcount_ptr<error_info_container> data; + if( error_info_container * d=b->data_.get() ) + data = d->clone(); + a->throw_file_ = b->throw_file_; + a->throw_line_ = b->throw_line_; + a->throw_function_ = b->throw_function_; + a->data_ = data; + } + + inline + void + copy_boost_exception( void *, void const * ) + { + } + + template <class T> + class + clone_impl: + public T, + public clone_base + { + public: + + explicit + clone_impl( T const & x ): + T(x) + { + copy_boost_exception(this,&x); + } + + ~clone_impl() throw() + { + } + + private: + + clone_base const * + clone() const + { + return new clone_impl(*this); + } + + void + rethrow() const + { + throw*this; + } + }; + } + + template <class T> + inline + exception_detail::clone_impl<T> + enable_current_exception( T const & x ) + { + return exception_detail::clone_impl<T>(x); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/get_error_info.hpp b/boost/exception/get_error_info.hpp new file mode 100644 index 0000000000..046f05aeef --- /dev/null +++ b/boost/exception/get_error_info.hpp @@ -0,0 +1,130 @@ +//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_1A590226753311DD9E4CCF6156D89593 +#define UUID_1A590226753311DD9E4CCF6156D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <boost/exception/exception.hpp> +#include <boost/exception/detail/error_info_impl.hpp> +#include <boost/exception/detail/type_info.hpp> +#include <boost/shared_ptr.hpp> + +namespace +boost + { + namespace + exception_detail + { + template <class ErrorInfo> + struct + get_info + { + static + typename ErrorInfo::value_type * + get( exception const & x ) + { + if( exception_detail::error_info_container * c=x.data_.get() ) + if( shared_ptr<exception_detail::error_info_base> eib = c->get(BOOST_EXCEPTION_STATIC_TYPEID(ErrorInfo)) ) + { +#ifndef BOOST_NO_RTTI + BOOST_ASSERT( 0!=dynamic_cast<ErrorInfo *>(eib.get()) ); +#endif + ErrorInfo * w = static_cast<ErrorInfo *>(eib.get()); + return &w->value(); + } + return 0; + } + }; + + template <> + struct + get_info<throw_function> + { + static + char const * * + get( exception const & x ) + { + return x.throw_function_ ? &x.throw_function_ : 0; + } + }; + + template <> + struct + get_info<throw_file> + { + static + char const * * + get( exception const & x ) + { + return x.throw_file_ ? &x.throw_file_ : 0; + } + }; + + template <> + struct + get_info<throw_line> + { + static + int * + get( exception const & x ) + { + return x.throw_line_!=-1 ? &x.throw_line_ : 0; + } + }; + + template <class T,class R> + struct + get_error_info_return_type + { + typedef R * type; + }; + + template <class T,class R> + struct + get_error_info_return_type<T const,R> + { + typedef R const * type; + }; + } + +#ifdef BOOST_NO_RTTI + template <class ErrorInfo> + inline + typename ErrorInfo::value_type const * + get_error_info( boost::exception const & x ) + { + return exception_detail::get_info<ErrorInfo>::get(x); + } + template <class ErrorInfo> + inline + typename ErrorInfo::value_type * + get_error_info( boost::exception & x ) + { + return exception_detail::get_info<ErrorInfo>::get(x); + } +#else + template <class ErrorInfo,class E> + inline + typename exception_detail::get_error_info_return_type<E,typename ErrorInfo::value_type>::type + get_error_info( E & some_exception ) + { + if( exception const * x = dynamic_cast<exception const *>(&some_exception) ) + return exception_detail::get_info<ErrorInfo>::get(*x); + else + return 0; + } +#endif + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/info.hpp b/boost/exception/info.hpp new file mode 100644 index 0000000000..5530746223 --- /dev/null +++ b/boost/exception/info.hpp @@ -0,0 +1,199 @@ +//Copyright (c) 2006-2010 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_8D22C4CA9CC811DCAA9133D256D89593 +#define UUID_8D22C4CA9CC811DCAA9133D256D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <boost/exception/exception.hpp> +#include <boost/exception/to_string_stub.hpp> +#include <boost/exception/detail/error_info_impl.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/config.hpp> +#include <map> + +namespace +boost + { + template <class Tag,class T> + inline + typename enable_if<has_to_string<T>,std::string>::type + to_string( error_info<Tag,T> const & x ) + { + return to_string(x.value()); + } + + template <class Tag,class T> + inline + error_info<Tag,T>:: + error_info( value_type const & value ): + value_(value) + { + } + + template <class Tag,class T> + inline + error_info<Tag,T>:: + ~error_info() throw() + { + } + + template <class Tag,class T> + inline + std::string + error_info<Tag,T>:: + tag_typeid_name() const + { + return tag_type_name<Tag>(); + } + + template <class Tag,class T> + inline + std::string + error_info<Tag,T>:: + value_as_string() const + { + return to_string_stub(*this); + } + + namespace + exception_detail + { + class + error_info_container_impl: + public error_info_container + { + public: + + error_info_container_impl(): + count_(0) + { + } + + ~error_info_container_impl() throw() + { + } + + void + set( shared_ptr<error_info_base> const & x, type_info_ const & typeid_ ) + { + BOOST_ASSERT(x); + info_[typeid_] = x; + diagnostic_info_str_.clear(); + } + + shared_ptr<error_info_base> + get( type_info_ const & ti ) const + { + error_info_map::const_iterator i=info_.find(ti); + if( info_.end()!=i ) + { + shared_ptr<error_info_base> const & p = i->second; +#ifndef BOOST_NO_RTTI + BOOST_ASSERT( BOOST_EXCEPTION_DYNAMIC_TYPEID(*p).type_==ti.type_ ); +#endif + return p; + } + return shared_ptr<error_info_base>(); + } + + char const * + diagnostic_information( char const * header ) const + { + if( header ) + { + std::ostringstream tmp; + tmp << header; + for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i ) + { + error_info_base const & x = *i->second; + tmp << '[' << x.tag_typeid_name() << "] = " << x.value_as_string() << '\n'; + } + tmp.str().swap(diagnostic_info_str_); + } + return diagnostic_info_str_.c_str(); + } + + private: + + friend class boost::exception; + + typedef std::map< type_info_, shared_ptr<error_info_base> > error_info_map; + error_info_map info_; + mutable std::string diagnostic_info_str_; + mutable int count_; + + error_info_container_impl( error_info_container_impl const & ); + error_info_container_impl & operator=( error_info_container const & ); + + void + add_ref() const + { + ++count_; + } + + bool + release() const + { + if( --count_ ) + return false; + else + { + delete this; + return true; + } + } + + refcount_ptr<error_info_container> + clone() const + { + refcount_ptr<error_info_container> p; + error_info_container_impl * c=new error_info_container_impl; + p.adopt(c); + c->info_ = info_; + return p; + } + }; + + template <class E,class Tag,class T> + inline + E const & + set_info( E const & x, error_info<Tag,T> const & v ) + { + typedef error_info<Tag,T> error_info_tag_t; + shared_ptr<error_info_tag_t> p( new error_info_tag_t(v) ); + exception_detail::error_info_container * c=x.data_.get(); + if( !c ) + x.data_.adopt(c=new exception_detail::error_info_container_impl); + c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t)); + return x; + } + + template <class T> + struct + derives_boost_exception + { + enum e { value = (sizeof(dispatch_boost_exception((T*)0))==sizeof(large_size)) }; + }; + } + + template <class E,class Tag,class T> + inline + typename enable_if<exception_detail::derives_boost_exception<E>,E const &>::type + operator<<( E const & x, error_info<Tag,T> const & v ) + { + return exception_detail::set_info(x,v); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/info_tuple.hpp b/boost/exception/info_tuple.hpp new file mode 100644 index 0000000000..34afe421b1 --- /dev/null +++ b/boost/exception/info_tuple.hpp @@ -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) + +#ifndef UUID_63EE924290FB11DC87BB856555D89593 +#define UUID_63EE924290FB11DC87BB856555D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <boost/exception/info.hpp> +#include <boost/tuple/tuple.hpp> + +namespace +boost + { + template < + class E, + class Tag1,class T1, + class Tag2,class T2 > + inline + E const & + operator<<( + E const & x, + tuple< + error_info<Tag1,T1>, + error_info<Tag2,T2> > const & v ) + { + return x << v.template get<0>() << v.template get<1>(); + } + + template < + class E, + class Tag1,class T1, + class Tag2,class T2, + class Tag3,class T3 > + inline + E const & + operator<<( + E const & x, + tuple< + error_info<Tag1,T1>, + error_info<Tag2,T2>, + error_info<Tag3,T3> > const & v ) + { + return x << v.template get<0>() << v.template get<1>() << v.template get<2>(); + } + + template < + class E, + class Tag1,class T1, + class Tag2,class T2, + class Tag3,class T3, + class Tag4,class T4 > + inline + E const & + operator<<( + E const & x, + tuple< + error_info<Tag1,T1>, + error_info<Tag2,T2>, + error_info<Tag3,T3>, + error_info<Tag4,T4> > const & v ) + { + return x << v.template get<0>() << v.template get<1>() << v.template get<2>() << v.template get<3>(); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/to_string.hpp b/boost/exception/to_string.hpp new file mode 100644 index 0000000000..59bf83d4c0 --- /dev/null +++ b/boost/exception/to_string.hpp @@ -0,0 +1,83 @@ +//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_7E48761AD92811DC9011477D56D89593 +#define UUID_7E48761AD92811DC9011477D56D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <boost/utility/enable_if.hpp> +#include <boost/exception/detail/is_output_streamable.hpp> +#include <sstream> + +namespace +boost + { + namespace + to_string_detail + { + template <class T> + typename disable_if<is_output_streamable<T>,char>::type to_string( T const & ); + + template <class,bool IsOutputStreamable> + struct has_to_string_impl; + + template <class T> + struct + has_to_string_impl<T,true> + { + enum e { value=1 }; + }; + + template <class T> + struct + has_to_string_impl<T,false> + { + static T const & f(); + enum e { value=1!=sizeof(to_string(f())) }; + }; + } + + template <class T> + inline + typename enable_if<is_output_streamable<T>,std::string>::type + to_string( T const & x ) + { + std::ostringstream out; + out << x; + return out.str(); + } + + template <class T> + struct + has_to_string + { + enum e { value=to_string_detail::has_to_string_impl<T,is_output_streamable<T>::value>::value }; + }; + + template <class T,class U> + inline + std::string + to_string( std::pair<T,U> const & x ) + { + return std::string("(") + to_string(x.first) + ',' + to_string(x.second) + ')'; + } + + inline + std::string + to_string( std::exception const & x ) + { + return x.what(); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/to_string_stub.hpp b/boost/exception/to_string_stub.hpp new file mode 100644 index 0000000000..e41d369775 --- /dev/null +++ b/boost/exception/to_string_stub.hpp @@ -0,0 +1,109 @@ +//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_E788439ED9F011DCB181F25B55D89593 +#define UUID_E788439ED9F011DCB181F25B55D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include <boost/exception/to_string.hpp> +#include <boost/exception/detail/object_hex_dump.hpp> +#include <boost/assert.hpp> + +namespace +boost + { + namespace + exception_detail + { + template <bool ToStringAvailable> + struct + to_string_dispatcher + { + template <class T,class Stub> + static + std::string + convert( T const & x, Stub ) + { + return to_string(x); + } + }; + + template <> + struct + to_string_dispatcher<false> + { + template <class T,class Stub> + static + std::string + convert( T const & x, Stub s ) + { + return s(x); + } + + template <class T> + static + std::string + convert( T const & x, std::string s ) + { + return s; + } + + template <class T> + static + std::string + convert( T const & x, char const * s ) + { + BOOST_ASSERT(s!=0); + return s; + } + }; + + namespace + to_string_dispatch + { + template <class T,class Stub> + inline + std::string + dispatch( T const & x, Stub s ) + { + return to_string_dispatcher<has_to_string<T>::value>::convert(x,s); + } + } + + template <class T> + inline + std::string + string_stub_dump( T const & x ) + { + return "[ " + exception_detail::object_hex_dump(x) + " ]"; + } + } + + template <class T> + inline + std::string + to_string_stub( T const & x ) + { + return exception_detail::to_string_dispatch::dispatch(x,&exception_detail::string_stub_dump<T>); + } + + template <class T,class Stub> + inline + std::string + to_string_stub( T const & x, Stub s ) + { + return exception_detail::to_string_dispatch::dispatch(x,s); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif |