Chris@16: //Copyright (c) 2006-2010 Emil Dotchevski and Reverge Studios, Inc. Chris@16: Chris@16: //Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef UUID_8D22C4CA9CC811DCAA9133D256D89593 Chris@16: #define UUID_8D22C4CA9CC811DCAA9133D256D89593 Chris@16: #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) Chris@16: #pragma GCC system_header Chris@16: #endif Chris@16: #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) Chris@16: #pragma warning(push,1) Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace Chris@16: boost Chris@16: { Chris@16: template Chris@16: inline Chris@16: std::string Chris@16: error_info_name( error_info const & x ) Chris@16: { Chris@16: return tag_type_name(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: std::string Chris@16: to_string( error_info const & x ) Chris@16: { Chris@16: return '[' + error_info_name(x) + "] = " + to_string_stub(x.value()) + '\n'; Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: error_info:: Chris@16: error_info( value_type const & value ): Chris@16: value_(value) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: error_info:: Chris@16: ~error_info() throw() Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: std::string Chris@16: error_info:: Chris@16: name_value_string() const Chris@16: { Chris@16: return to_string_stub(*this); Chris@16: } Chris@16: Chris@16: namespace Chris@16: exception_detail Chris@16: { Chris@16: class Chris@16: error_info_container_impl: Chris@16: public error_info_container Chris@16: { Chris@16: public: Chris@16: Chris@16: error_info_container_impl(): Chris@16: count_(0) Chris@16: { Chris@16: } Chris@16: Chris@16: ~error_info_container_impl() throw() Chris@16: { Chris@16: } Chris@16: Chris@16: void Chris@16: set( shared_ptr const & x, type_info_ const & typeid_ ) Chris@16: { Chris@16: BOOST_ASSERT(x); Chris@16: info_[typeid_] = x; Chris@16: diagnostic_info_str_.clear(); Chris@16: } Chris@16: Chris@16: shared_ptr Chris@16: get( type_info_ const & ti ) const Chris@16: { Chris@16: error_info_map::const_iterator i=info_.find(ti); Chris@16: if( info_.end()!=i ) Chris@16: { Chris@16: shared_ptr const & p = i->second; Chris@16: #ifndef BOOST_NO_RTTI Chris@16: BOOST_ASSERT( *BOOST_EXCEPTION_DYNAMIC_TYPEID(*p).type_==*ti.type_ ); Chris@16: #endif Chris@16: return p; Chris@16: } Chris@16: return shared_ptr(); Chris@16: } Chris@16: Chris@16: char const * Chris@16: diagnostic_information( char const * header ) const Chris@16: { Chris@16: if( header ) Chris@16: { Chris@16: std::ostringstream tmp; Chris@16: tmp << header; Chris@16: for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i ) Chris@16: { Chris@16: error_info_base const & x = *i->second; Chris@16: tmp << x.name_value_string(); Chris@16: } Chris@16: tmp.str().swap(diagnostic_info_str_); Chris@16: } Chris@16: return diagnostic_info_str_.c_str(); Chris@16: } Chris@16: Chris@16: private: Chris@16: Chris@16: friend class boost::exception; Chris@16: Chris@16: typedef std::map< type_info_, shared_ptr > error_info_map; Chris@16: error_info_map info_; Chris@16: mutable std::string diagnostic_info_str_; Chris@16: mutable int count_; Chris@16: Chris@16: error_info_container_impl( error_info_container_impl const & ); Chris@16: error_info_container_impl & operator=( error_info_container const & ); Chris@16: Chris@16: void Chris@16: add_ref() const Chris@16: { Chris@16: ++count_; Chris@16: } Chris@16: Chris@16: bool Chris@16: release() const Chris@16: { Chris@16: if( --count_ ) Chris@16: return false; Chris@16: else Chris@16: { Chris@16: delete this; Chris@16: return true; Chris@16: } Chris@16: } Chris@16: Chris@16: refcount_ptr Chris@16: clone() const Chris@16: { Chris@16: refcount_ptr p; Chris@16: error_info_container_impl * c=new error_info_container_impl; Chris@16: p.adopt(c); Chris@16: c->info_ = info_; Chris@16: return p; Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: inline Chris@16: E const & Chris@16: set_info( E const & x, error_info const & v ) Chris@16: { Chris@16: typedef error_info error_info_tag_t; Chris@16: shared_ptr p( new error_info_tag_t(v) ); Chris@16: exception_detail::error_info_container * c=x.data_.get(); Chris@16: if( !c ) Chris@16: x.data_.adopt(c=new exception_detail::error_info_container_impl); Chris@16: c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t)); Chris@16: return x; Chris@16: } Chris@16: Chris@16: template Chris@16: struct Chris@16: derives_boost_exception Chris@16: { Chris@16: enum e { value = (sizeof(dispatch_boost_exception((T*)0))==sizeof(large_size)) }; Chris@16: }; Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: typename enable_if,E const &>::type Chris@16: operator<<( E const & x, error_info const & v ) Chris@16: { Chris@16: return exception_detail::set_info(x,v); Chris@16: } Chris@16: } Chris@16: Chris@16: #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: #endif