#ifndef BOOST_REGISTER_EXCEPTION_PTR_HPP_INCLUDED #define BOOST_REGISTER_EXCEPTION_PTR_HPP_INCLUDED // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif //Copyright (c) 2007 Joshua Napoli //Distributed under the Boost Software License, Version 1.0. (See accompanying //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include #include #include namespace boost { namespace exception_detail { class exception_info { public: template static exception_info ctor() { return exception_info(new impl); } exception_info(const std::type_info& info) :impl_(new partial_impl(info)) {} bool operator< (const exception_info& other) const { return *impl_ < *other.impl_; } template exception_ptr copy(const T& t) const { return impl_->copy(dynamic_cast(&t)); } exception_ptr current() const { return impl_->current(); } void rethrow_slice() const { impl_->rethrow_slice(); } private: struct impl_base : noncopyable { virtual bool after(const std::type_info& other) const=0; virtual bool operator< (const impl_base& other) const=0; virtual exception_ptr copy(const void* p) const=0; virtual exception_ptr current() const=0; virtual void rethrow_slice() const=0; virtual ~impl_base() {} friend void intrusive_ptr_add_ref(impl_base * p) { //make atomic ++p->count; } friend void intrusive_ptr_release(impl_base * p) { //make atomic if(! --p->count) { delete p; } } impl_base() : count(0) {} long count; }; template struct impl : impl_base { virtual bool after(const std::type_info& other) const { return !!other.before(typeid(T)); //msvc type_info::before returns int } virtual bool operator< (const impl_base& other) const { return other.after(typeid(T)); } virtual exception_ptr copy(const void* p) const { return exception_ptr (new cloned_exception_impl(*static_cast(p))); } virtual exception_ptr current() const { try {throw;} catch(const T&t) {return exception_ptr(new cloned_exception_impl(t));} catch(...) {return 0;} } virtual void rethrow_slice() const { try {throw;} catch(const T& t) {throw t;} } virtual ~impl() {} }; struct partial_impl : impl_base { partial_impl(const std::type_info& info) : info_(info) {} virtual bool after(const std::type_info& other) const { return !!other.before(info_); //msvc type_info::before returns int } virtual bool operator< (const impl_base& other) const { return other.after(info_); } virtual exception_ptr copy(const void* p) const {BOOST_ASSERT(false);} virtual exception_ptr current() const {BOOST_ASSERT(false);} virtual void rethrow_slice() const {BOOST_ASSERT(false);} virtual ~partial_impl() {} const std::type_info& info_; }; exception_info(impl_base* impl) : impl_(impl) {} intrusive_ptr impl_; }; struct exception_registry_type { std::set exceptions_; exception_registry_type() { exceptions_.insert(exception_info::ctor()); exceptions_.insert(exception_info::ctor()); exceptions_.insert(exception_info::ctor()); exceptions_.insert(exception_info::ctor()); exceptions_.insert(exception_info::ctor()); exceptions_.insert(exception_info::ctor()); exceptions_.insert(exception_info::ctor()); exceptions_.insert(exception_info::ctor()); exceptions_.insert(exception_info::ctor()); exceptions_.insert(exception_info::ctor()); exceptions_.insert(exception_info::ctor()); } }; //add mutex inline std::set& exception_registry() { static exception_registry_type registry; return registry.exceptions_; } template inline void register_exception() { //add mutex exception_registry().insert(exception_info::ctor()); } } } #endif // #ifndef BOOST_REGISTER_EXCEPTION_PTR_HPP_INCLUDED