info.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //Copyright (c) 2006-2009 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. #include <boost/exception/exception.hpp>
  7. #include <boost/exception/to_string_stub.hpp>
  8. #include <boost/exception/detail/error_info_impl.hpp>
  9. #include <boost/shared_ptr.hpp>
  10. #include <map>
  11. namespace
  12. boost
  13. {
  14. template <class Tag,class T>
  15. inline
  16. typename enable_if<has_to_string<T>,std::string>::type
  17. to_string( error_info<Tag,T> const & x )
  18. {
  19. return to_string(x.value());
  20. }
  21. template <class Tag,class T>
  22. inline
  23. error_info<Tag,T>::
  24. error_info( value_type const & value ):
  25. value_(value)
  26. {
  27. }
  28. template <class Tag,class T>
  29. inline
  30. error_info<Tag,T>::
  31. ~error_info() throw()
  32. {
  33. }
  34. template <class Tag,class T>
  35. inline
  36. char const *
  37. error_info<Tag,T>::
  38. tag_typeid_name() const
  39. {
  40. return tag_type_name<Tag>();
  41. }
  42. template <class Tag,class T>
  43. inline
  44. std::string
  45. error_info<Tag,T>::
  46. value_as_string() const
  47. {
  48. return to_string_stub(*this);
  49. }
  50. namespace
  51. exception_detail
  52. {
  53. class
  54. error_info_container_impl:
  55. public error_info_container
  56. {
  57. public:
  58. error_info_container_impl():
  59. count_(0)
  60. {
  61. }
  62. ~error_info_container_impl() throw()
  63. {
  64. }
  65. void
  66. set( shared_ptr<error_info_base const> const & x, type_info_ const & typeid_ )
  67. {
  68. BOOST_ASSERT(x);
  69. info_[typeid_] = x;
  70. diagnostic_info_str_.clear();
  71. }
  72. shared_ptr<error_info_base const>
  73. get( type_info_ const & ti ) const
  74. {
  75. error_info_map::const_iterator i=info_.find(ti);
  76. if( info_.end()!=i )
  77. {
  78. shared_ptr<error_info_base const> const & p = i->second;
  79. #ifndef BOOST_NO_RTTI
  80. BOOST_ASSERT( BOOST_EXCEPTION_DYNAMIC_TYPEID(*p)==ti );
  81. #endif
  82. return p;
  83. }
  84. return shared_ptr<error_info_base const>();
  85. }
  86. char const *
  87. diagnostic_information() const
  88. {
  89. if( diagnostic_info_str_.empty() )
  90. {
  91. std::ostringstream tmp;
  92. for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i )
  93. {
  94. shared_ptr<error_info_base const> const & x = i->second;
  95. tmp << '[' << x->tag_typeid_name() << "] = " << x->value_as_string() << '\n';
  96. }
  97. tmp.str().swap(diagnostic_info_str_);
  98. }
  99. return diagnostic_info_str_.c_str();
  100. }
  101. private:
  102. friend class boost::exception;
  103. typedef std::map< type_info_, shared_ptr<error_info_base const> > error_info_map;
  104. error_info_map info_;
  105. mutable std::string diagnostic_info_str_;
  106. mutable int count_;
  107. void
  108. add_ref() const
  109. {
  110. ++count_;
  111. }
  112. void
  113. release() const
  114. {
  115. if( !--count_ )
  116. delete this;
  117. }
  118. };
  119. }
  120. template <class E,class Tag,class T>
  121. inline
  122. E const &
  123. operator<<( E const & x, error_info<Tag,T> const & v )
  124. {
  125. typedef error_info<Tag,T> error_info_tag_t;
  126. shared_ptr<error_info_tag_t> p( new error_info_tag_t(v) );
  127. exception_detail::error_info_container * c;
  128. if( !(c=x.data_.get()) )
  129. x.data_.adopt(c=new exception_detail::error_info_container_impl);
  130. c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t));
  131. return x;
  132. }
  133. }
  134. #endif