//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_78CC85B2914F11DC8F47B48E55D89593 #define UUID_78CC85B2914F11DC8F47B48E55D89593 #include #include #include #include #include namespace boost { namespace exception_detail { class clone_base: public counted_base { public: virtual void rethrow() const=0; }; struct bad_alloc_impl: public clone_base, public std::bad_alloc { void add_ref() const { } void release() const { } void rethrow() const { throw *this; } }; template clone_base * make_clone( T const & ); template class clone_impl: public T, public cloning_base { public: explicit clone_impl( T const & x ): T(x) { if( boost::exception * be1=dynamic_cast(this) ) if( boost::exception const * be2=dynamic_cast(&x) ) *be1 = *be2; } private: clone_base const * clone() const { return make_clone(*this); } }; template class exception_clone: public T, public clone_base { public: explicit exception_clone( T const & x ): T(x), count_(0) { if( boost::exception * be1=dynamic_cast(this) ) if( boost::exception const * be2=dynamic_cast(&x) ) *be1 = *be2; } private: mutable detail::atomic_count count_; void add_ref() const { ++count_; } void release() const { if( !--count_ ) delete this; } void rethrow() const { throw clone_impl(*this); } }; template inline clone_base * make_clone( T const & x ) { try { return new exception_clone(x); } catch( std::bad_alloc & ) { static bad_alloc_impl bad_alloc; return &bad_alloc; } catch( ... ) { BOOST_ASSERT(0); return 0; } } } template inline exception_detail::clone_impl enable_current_exception( T const & x ) { return exception_detail::clone_impl(x); } } #endif