]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/exception/info.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / exception / info.hpp
1 //Copyright (c) 2006-2010 Emil Dotchevski and Reverge Studios, Inc.
2
3 //Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef UUID_8D22C4CA9CC811DCAA9133D256D89593
7 #define UUID_8D22C4CA9CC811DCAA9133D256D89593
8
9 #include <boost/config.hpp>
10 #include <boost/exception/exception.hpp>
11 #include <boost/exception/to_string_stub.hpp>
12 #include <boost/exception/detail/error_info_impl.hpp>
13 #include <boost/exception/detail/shared_ptr.hpp>
14 #include <map>
15
16 #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
17 #pragma GCC system_header
18 #endif
19 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
20 #pragma warning(push,1)
21 #endif
22
23 namespace
24 boost
25 {
26 template <class Tag,class T>
27 inline
28 std::string
29 error_info_name( error_info<Tag,T> const & x )
30 {
31 return tag_type_name<Tag>();
32 }
33
34 template <class Tag,class T>
35 inline
36 std::string
37 to_string( error_info<Tag,T> const & x )
38 {
39 return '[' + error_info_name(x) + "] = " + to_string_stub(x.value()) + '\n';
40 }
41
42 template <class Tag,class T>
43 inline
44 std::string
45 error_info<Tag,T>::
46 name_value_string() const
47 {
48 return to_string_stub(*this);
49 }
50
51 namespace
52 exception_detail
53 {
54 class
55 error_info_container_impl:
56 public error_info_container
57 {
58 public:
59
60 error_info_container_impl():
61 count_(0)
62 {
63 }
64
65 ~error_info_container_impl() throw()
66 {
67 }
68
69 void
70 set( shared_ptr<error_info_base> const & x, type_info_ const & typeid_ )
71 {
72 BOOST_ASSERT(x);
73 info_[typeid_] = x;
74 diagnostic_info_str_.clear();
75 }
76
77 shared_ptr<error_info_base>
78 get( type_info_ const & ti ) const
79 {
80 error_info_map::const_iterator i=info_.find(ti);
81 if( info_.end()!=i )
82 {
83 shared_ptr<error_info_base> const & p = i->second;
84 #ifndef BOOST_NO_RTTI
85 BOOST_ASSERT( *BOOST_EXCEPTION_DYNAMIC_TYPEID(*p).type_==*ti.type_ );
86 #endif
87 return p;
88 }
89 return shared_ptr<error_info_base>();
90 }
91
92 char const *
93 diagnostic_information( char const * header ) const
94 {
95 if( header )
96 {
97 std::ostringstream tmp;
98 tmp << header;
99 for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i )
100 {
101 error_info_base const & x = *i->second;
102 tmp << x.name_value_string();
103 }
104 tmp.str().swap(diagnostic_info_str_);
105 }
106 return diagnostic_info_str_.c_str();
107 }
108
109 private:
110
111 friend class boost::exception;
112
113 typedef std::map< type_info_, shared_ptr<error_info_base> > error_info_map;
114 error_info_map info_;
115 mutable std::string diagnostic_info_str_;
116 mutable int count_;
117
118 error_info_container_impl( error_info_container_impl const & );
119 error_info_container_impl & operator=( error_info_container const & );
120
121 void
122 add_ref() const
123 {
124 ++count_;
125 }
126
127 bool
128 release() const
129 {
130 if( --count_ )
131 return false;
132 else
133 {
134 delete this;
135 return true;
136 }
137 }
138
139 refcount_ptr<error_info_container>
140 clone() const
141 {
142 refcount_ptr<error_info_container> p;
143 error_info_container_impl * c=new error_info_container_impl;
144 p.adopt(c);
145 for( error_info_map::const_iterator i=info_.begin(),e=info_.end(); i!=e; ++i )
146 {
147 shared_ptr<error_info_base> cp(i->second->clone());
148 c->info_.insert(std::make_pair(i->first,cp));
149 }
150 return p;
151 }
152 };
153
154 template <class E,class Tag,class T>
155 inline
156 E const &
157 set_info( E const & x, error_info<Tag,T> const & v )
158 {
159 typedef error_info<Tag,T> error_info_tag_t;
160 shared_ptr<error_info_tag_t> p( new error_info_tag_t(v) );
161 exception_detail::error_info_container * c=x.data_.get();
162 if( !c )
163 x.data_.adopt(c=new exception_detail::error_info_container_impl);
164 c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t));
165 return x;
166 }
167
168 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
169 template <class E,class Tag,class T>
170 E const & set_info( E const &, error_info<Tag,T> && );
171 template <class T>
172 struct set_info_rv;
173 template <class Tag,class T>
174 struct
175 set_info_rv<error_info<Tag,T> >
176 {
177 template <class E,class Tag1,class T1>
178 friend E const & set_info( E const &, error_info<Tag1,T1> && );
179 template <class E>
180 static
181 E const &
182 set( E const & x, error_info<Tag,T> && v )
183 {
184 typedef error_info<Tag,T> error_info_tag_t;
185 shared_ptr<error_info_tag_t> p( new error_info_tag_t(std::move(v)) );
186 exception_detail::error_info_container * c=x.data_.get();
187 if( !c )
188 x.data_.adopt(c=new exception_detail::error_info_container_impl);
189 c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t));
190 return x;
191 }
192 };
193 template <>
194 struct
195 set_info_rv<throw_function>
196 {
197 template <class E,class Tag1,class T1>
198 friend E const & set_info( E const &, error_info<Tag1,T1> && );
199 template <class E>
200 static
201 E const &
202 set( E const & x, throw_function && y )
203 {
204 x.throw_function_=y.v_;
205 return x;
206 }
207 };
208 template <>
209 struct
210 set_info_rv<throw_file>
211 {
212 template <class E,class Tag1,class T1>
213 friend E const & set_info( E const &, error_info<Tag1,T1> && );
214 template <class E>
215 static
216 E const &
217 set( E const & x, throw_file && y )
218 {
219 x.throw_file_=y.v_;
220 return x;
221 }
222 };
223 template <>
224 struct
225 set_info_rv<throw_line>
226 {
227 template <class E,class Tag1,class T1>
228 friend E const & set_info( E const &, error_info<Tag1,T1> && );
229 template <class E>
230 static
231 E const &
232 set( E const & x, throw_line && y )
233 {
234 x.throw_line_=y.v_;
235 return x;
236 }
237 };
238 template <class E,class Tag,class T>
239 inline
240 E const &
241 set_info( E const & x, error_info<Tag,T> && v )
242 {
243 return set_info_rv<error_info<Tag,T> >::template set<E>(x,std::move(v));
244 }
245 #endif
246
247 template <class T>
248 struct
249 derives_boost_exception
250 {
251 enum e { value = (sizeof(dispatch_boost_exception((T*)0))==sizeof(large_size)) };
252 };
253 }
254
255 template <class E,class Tag,class T>
256 inline
257 typename enable_if<exception_detail::derives_boost_exception<E>,E const &>::type
258 operator<<( E const & x, error_info<Tag,T> const & v )
259 {
260 return exception_detail::set_info(x,v);
261 }
262
263 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
264 template <class E,class Tag,class T>
265 inline
266 typename enable_if<exception_detail::derives_boost_exception<E>,E const &>::type
267 operator<<( E const & x, error_info<Tag,T> && v )
268 {
269 return exception_detail::set_info(x,std::move(v));
270 }
271 #endif
272 }
273
274 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
275 #pragma warning(pop)
276 #endif
277 #endif