info.hpp
Go to the documentation of this file.
00001 //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
00002 
00003 //Distributed under the Boost Software License, Version 1.0. (See accompanying
00004 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00005 
00006 #ifndef UUID_8D22C4CA9CC811DCAA9133D256D89593
00007 #define UUID_8D22C4CA9CC811DCAA9133D256D89593
00008 
00009 #include <boost/exception/exception.hpp>
00010 #include <boost/exception/to_string_stub.hpp>
00011 #include <boost/exception/detail/error_info_impl.hpp>
00012 #include <boost/shared_ptr.hpp>
00013 #include <map>
00014 
00015 namespace
00016 boost
00017     {
00018     template <class Tag,class T>
00019     inline
00020     typename enable_if<has_to_string<T>,std::string>::type
00021     to_string( error_info<Tag,T> const & x )
00022         {
00023         return to_string(x.value());
00024         }
00025 
00026     template <class Tag,class T>
00027     inline
00028     error_info<Tag,T>::
00029     error_info( value_type const & value ):
00030         value_(value)
00031         {
00032         }
00033 
00034     template <class Tag,class T>
00035     inline
00036     error_info<Tag,T>::
00037     ~error_info() throw()
00038         {
00039         }
00040 
00041     template <class Tag,class T>
00042     inline
00043     char const *
00044     error_info<Tag,T>::
00045     tag_typeid_name() const
00046         {
00047         return tag_type_name<Tag>();
00048         }
00049 
00050     template <class Tag,class T>
00051     inline
00052     std::string
00053     error_info<Tag,T>::
00054     value_as_string() const
00055         {
00056         return to_string_stub(*this);
00057         }
00058 
00059     namespace
00060     exception_detail
00061         {
00062         class
00063         error_info_container_impl:
00064             public error_info_container
00065             {
00066             public:
00067 
00068             error_info_container_impl():
00069                 count_(0)
00070                 {
00071                 }
00072 
00073             ~error_info_container_impl() throw()
00074                 {
00075                 }
00076 
00077             void
00078             set( shared_ptr<error_info_base const> const & x, type_info_ const & typeid_ )
00079                 {
00080                 BOOST_ASSERT(x);
00081                 info_[typeid_] = x;
00082                 diagnostic_info_str_.clear();
00083                 }
00084 
00085             shared_ptr<error_info_base const>
00086             get( type_info_ const & ti ) const
00087                 {
00088                 error_info_map::const_iterator i=info_.find(ti);
00089                 if( info_.end()!=i )
00090                     {
00091                     shared_ptr<error_info_base const> const & p = i->second;
00092 #ifndef BOOST_NO_RTTI
00093                     BOOST_ASSERT( BOOST_EXCEPTION_DYNAMIC_TYPEID(*p)==ti );
00094 #endif
00095                     return p;
00096                     }
00097                 return shared_ptr<error_info_base const>();
00098                 }
00099 
00100             char const *
00101             diagnostic_information() const
00102                 {
00103                 if( diagnostic_info_str_.empty() )
00104                     {
00105                     std::ostringstream tmp;
00106                     for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i )
00107                         {
00108                         shared_ptr<error_info_base const> const & x = i->second;
00109                         tmp << '[' << x->tag_typeid_name() << "] = " << x->value_as_string() << std::endl;
00110                         }
00111                     tmp.str().swap(diagnostic_info_str_);
00112                     }
00113                 return diagnostic_info_str_.c_str();
00114                 }
00115 
00116             private:
00117 
00118             friend class boost::exception;
00119 
00120             typedef std::map< type_info_, shared_ptr<error_info_base const> > error_info_map;
00121             error_info_map info_;
00122             mutable std::string diagnostic_info_str_;
00123             mutable int count_;
00124 
00125             void
00126             add_ref() const
00127                 {
00128                 ++count_;
00129                 }
00130 
00131             void
00132             release() const
00133                 {
00134                 if( !--count_ )
00135                     delete this;
00136                 }
00137             };
00138         }
00139 
00140     template <class E,class Tag,class T>
00141     inline
00142     E const &
00143     operator<<( E const & x, error_info<Tag,T> const & v )
00144         {
00145         typedef error_info<Tag,T> error_info_tag_t;
00146         shared_ptr<error_info_tag_t> p( new error_info_tag_t(v) );
00147         exception_detail::error_info_container * c;
00148         if( !(c=x.data_.get()) )
00149             x.data_.adopt(c=new exception_detail::error_info_container_impl);
00150         c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t));
00151         return x;
00152         }
00153     }
00154 
00155 #endif


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29