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