/Src/Dependencies/Boost/boost/exception/info.hpp

http://hadesmem.googlecode.com/ · C++ Header · 199 lines · 171 code · 25 blank · 3 comment · 8 complexity · 8201d51b57601ca31167dec331ce8da9 MD5 · raw file

  1. //Copyright (c) 2006-2010 Emil Dotchevski and Reverge Studios, Inc.
  2. //Distributed under the Boost Software License, Version 1.0. (See accompanying
  3. //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #ifndef UUID_8D22C4CA9CC811DCAA9133D256D89593
  5. #define UUID_8D22C4CA9CC811DCAA9133D256D89593
  6. #if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
  7. #pragma GCC system_header
  8. #endif
  9. #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
  10. #pragma warning(push,1)
  11. #endif
  12. #include <boost/exception/exception.hpp>
  13. #include <boost/exception/to_string_stub.hpp>
  14. #include <boost/exception/detail/error_info_impl.hpp>
  15. #include <boost/shared_ptr.hpp>
  16. #include <boost/config.hpp>
  17. #include <map>
  18. namespace
  19. boost
  20. {
  21. template <class Tag,class T>
  22. inline
  23. typename enable_if<has_to_string<T>,std::string>::type
  24. to_string( error_info<Tag,T> const & x )
  25. {
  26. return to_string(x.value());
  27. }
  28. template <class Tag,class T>
  29. inline
  30. error_info<Tag,T>::
  31. error_info( value_type const & value ):
  32. value_(value)
  33. {
  34. }
  35. template <class Tag,class T>
  36. inline
  37. error_info<Tag,T>::
  38. ~error_info() throw()
  39. {
  40. }
  41. template <class Tag,class T>
  42. inline
  43. std::string
  44. error_info<Tag,T>::
  45. tag_typeid_name() const
  46. {
  47. return tag_type_name<Tag>();
  48. }
  49. template <class Tag,class T>
  50. inline
  51. std::string
  52. error_info<Tag,T>::
  53. value_as_string() const
  54. {
  55. return to_string_stub(*this);
  56. }
  57. namespace
  58. exception_detail
  59. {
  60. class
  61. error_info_container_impl:
  62. public error_info_container
  63. {
  64. public:
  65. error_info_container_impl():
  66. count_(0)
  67. {
  68. }
  69. ~error_info_container_impl() throw()
  70. {
  71. }
  72. void
  73. set( shared_ptr<error_info_base> const & x, type_info_ const & typeid_ )
  74. {
  75. BOOST_ASSERT(x);
  76. info_[typeid_] = x;
  77. diagnostic_info_str_.clear();
  78. }
  79. shared_ptr<error_info_base>
  80. get( type_info_ const & ti ) const
  81. {
  82. error_info_map::const_iterator i=info_.find(ti);
  83. if( info_.end()!=i )
  84. {
  85. shared_ptr<error_info_base> const & p = i->second;
  86. #ifndef BOOST_NO_RTTI
  87. BOOST_ASSERT( BOOST_EXCEPTION_DYNAMIC_TYPEID(*p).type_==ti.type_ );
  88. #endif
  89. return p;
  90. }
  91. return shared_ptr<error_info_base>();
  92. }
  93. char const *
  94. diagnostic_information( char const * header ) const
  95. {
  96. if( header )
  97. {
  98. std::ostringstream tmp;
  99. tmp << header;
  100. for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i )
  101. {
  102. error_info_base const & x = *i->second;
  103. tmp << '[' << x.tag_typeid_name() << "] = " << x.value_as_string() << '\n';
  104. }
  105. tmp.str().swap(diagnostic_info_str_);
  106. }
  107. return diagnostic_info_str_.c_str();
  108. }
  109. private:
  110. friend class boost::exception;
  111. typedef std::map< type_info_, shared_ptr<error_info_base> > error_info_map;
  112. error_info_map info_;
  113. mutable std::string diagnostic_info_str_;
  114. mutable int count_;
  115. error_info_container_impl( error_info_container_impl const & );
  116. error_info_container_impl & operator=( error_info_container const & );
  117. void
  118. add_ref() const
  119. {
  120. ++count_;
  121. }
  122. bool
  123. release() const
  124. {
  125. if( --count_ )
  126. return false;
  127. else
  128. {
  129. delete this;
  130. return true;
  131. }
  132. }
  133. refcount_ptr<error_info_container>
  134. clone() const
  135. {
  136. refcount_ptr<error_info_container> p;
  137. error_info_container_impl * c=new error_info_container_impl;
  138. p.adopt(c);
  139. c->info_ = info_;
  140. return p;
  141. }
  142. };
  143. template <class E,class Tag,class T>
  144. inline
  145. E const &
  146. set_info( E const & x, error_info<Tag,T> const & v )
  147. {
  148. typedef error_info<Tag,T> error_info_tag_t;
  149. shared_ptr<error_info_tag_t> p( new error_info_tag_t(v) );
  150. exception_detail::error_info_container * c=x.data_.get();
  151. if( !c )
  152. x.data_.adopt(c=new exception_detail::error_info_container_impl);
  153. c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t));
  154. return x;
  155. }
  156. template <class T>
  157. struct
  158. derives_boost_exception
  159. {
  160. enum e { value = (sizeof(dispatch_boost_exception((T*)0))==sizeof(large_size)) };
  161. };
  162. }
  163. template <class E,class Tag,class T>
  164. inline
  165. typename enable_if<exception_detail::derives_boost_exception<E>,E const &>::type
  166. operator<<( E const & x, error_info<Tag,T> const & v )
  167. {
  168. return exception_detail::set_info(x,v);
  169. }
  170. }
  171. #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
  172. #pragma warning(pop)
  173. #endif
  174. #endif