]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/exception/include/boost/exception/detail/exception_ptr.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / exception / include / boost / exception / detail / exception_ptr.hpp
1 //Copyright (c) 2006-2009 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_618474C2DE1511DEB74A388C56D89593
7 #define UUID_618474C2DE1511DEB74A388C56D89593
8 #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
9 #pragma GCC system_header
10 #endif
11 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
12 #pragma warning(push,1)
13 #endif
14
15 #include <boost/config.hpp>
16 #ifdef BOOST_NO_EXCEPTIONS
17 #error This header requires exception handling to be enabled.
18 #endif
19 #include <boost/exception/exception.hpp>
20 #include <boost/exception/info.hpp>
21 #include <boost/exception/diagnostic_information.hpp>
22 #include <boost/exception/detail/type_info.hpp>
23 #include <boost/exception/detail/clone_current_exception.hpp>
24 #ifndef BOOST_NO_RTTI
25 #include <boost/core/demangle.hpp>
26 #endif
27 #include <boost/shared_ptr.hpp>
28 #include <stdexcept>
29 #include <new>
30 #include <ios>
31 #include <stdlib.h>
32
33 namespace
34 boost
35 {
36 class exception_ptr;
37 BOOST_NORETURN void rethrow_exception( exception_ptr const & );
38 exception_ptr current_exception();
39
40 class
41 exception_ptr
42 {
43 typedef boost::shared_ptr<exception_detail::clone_base const> impl;
44 impl ptr_;
45 friend void rethrow_exception( exception_ptr const & );
46 typedef exception_detail::clone_base const * (impl::*unspecified_bool_type)() const;
47 public:
48 exception_ptr()
49 {
50 }
51 explicit
52 exception_ptr( impl const & ptr ):
53 ptr_(ptr)
54 {
55 }
56 bool
57 operator==( exception_ptr const & other ) const
58 {
59 return ptr_==other.ptr_;
60 }
61 bool
62 operator!=( exception_ptr const & other ) const
63 {
64 return ptr_!=other.ptr_;
65 }
66 operator unspecified_bool_type() const
67 {
68 return ptr_?&impl::get:0;
69 }
70 };
71
72 template <class T>
73 inline
74 exception_ptr
75 copy_exception( T const & e )
76 {
77 try
78 {
79 throw enable_current_exception(e);
80 }
81 catch(
82 ... )
83 {
84 return current_exception();
85 }
86 }
87
88 #ifndef BOOST_NO_RTTI
89 typedef error_info<struct tag_original_exception_type,std::type_info const *> original_exception_type;
90
91 inline
92 std::string
93 to_string( original_exception_type const & x )
94 {
95 return core::demangle(x.value()->name());
96 }
97 #endif
98
99 namespace
100 exception_detail
101 {
102 struct
103 bad_alloc_:
104 boost::exception,
105 std::bad_alloc
106 {
107 ~bad_alloc_() throw() { }
108 };
109
110 struct
111 bad_exception_:
112 boost::exception,
113 std::bad_exception
114 {
115 ~bad_exception_() throw() { }
116 };
117
118 template <class Exception>
119 exception_ptr
120 get_static_exception_object()
121 {
122 Exception ba;
123 exception_detail::clone_impl<Exception> c(ba);
124 #ifndef BOOST_EXCEPTION_DISABLE
125 c <<
126 throw_function(BOOST_CURRENT_FUNCTION) <<
127 throw_file(__FILE__) <<
128 throw_line(__LINE__);
129 #endif
130 static exception_ptr ep(shared_ptr<exception_detail::clone_base const>(new exception_detail::clone_impl<Exception>(c)));
131 return ep;
132 }
133
134 template <class Exception>
135 struct
136 exception_ptr_static_exception_object
137 {
138 static exception_ptr const e;
139 };
140
141 template <class Exception>
142 exception_ptr const
143 exception_ptr_static_exception_object<Exception>::
144 e = get_static_exception_object<Exception>();
145 }
146
147 #if defined(__GNUC__)
148 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
149 # pragma GCC visibility push (default)
150 # endif
151 #endif
152 class
153 unknown_exception:
154 public boost::exception,
155 public std::exception
156 {
157 public:
158
159 unknown_exception()
160 {
161 }
162
163 explicit
164 unknown_exception( std::exception const & e )
165 {
166 add_original_type(e);
167 }
168
169 explicit
170 unknown_exception( boost::exception const & e ):
171 boost::exception(e)
172 {
173 add_original_type(e);
174 }
175
176 ~unknown_exception() throw()
177 {
178 }
179
180 private:
181
182 template <class E>
183 void
184 add_original_type( E const & e )
185 {
186 #ifndef BOOST_NO_RTTI
187 (*this) << original_exception_type(&typeid(e));
188 #endif
189 }
190 };
191 #if defined(__GNUC__)
192 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
193 # pragma GCC visibility pop
194 # endif
195 #endif
196
197 namespace
198 exception_detail
199 {
200 template <class T>
201 class
202 current_exception_std_exception_wrapper:
203 public T,
204 public boost::exception
205 {
206 public:
207
208 explicit
209 current_exception_std_exception_wrapper( T const & e1 ):
210 T(e1)
211 {
212 add_original_type(e1);
213 }
214
215 current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ):
216 T(e1),
217 boost::exception(e2)
218 {
219 add_original_type(e1);
220 }
221
222 ~current_exception_std_exception_wrapper() throw()
223 {
224 }
225
226 private:
227
228 template <class E>
229 void
230 add_original_type( E const & e )
231 {
232 #ifndef BOOST_NO_RTTI
233 (*this) << original_exception_type(&typeid(e));
234 #endif
235 }
236 };
237
238 #ifdef BOOST_NO_RTTI
239 template <class T>
240 boost::exception const *
241 get_boost_exception( T const * )
242 {
243 try
244 {
245 throw;
246 }
247 catch(
248 boost::exception & x )
249 {
250 return &x;
251 }
252 catch(...)
253 {
254 return 0;
255 }
256 }
257 #else
258 template <class T>
259 boost::exception const *
260 get_boost_exception( T const * x )
261 {
262 return dynamic_cast<boost::exception const *>(x);
263 }
264 #endif
265
266 template <class T>
267 inline
268 exception_ptr
269 current_exception_std_exception( T const & e1 )
270 {
271 if( boost::exception const * e2 = get_boost_exception(&e1) )
272 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1,*e2));
273 else
274 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1));
275 }
276
277 inline
278 exception_ptr
279 current_exception_unknown_exception()
280 {
281 return boost::copy_exception(unknown_exception());
282 }
283
284 inline
285 exception_ptr
286 current_exception_unknown_boost_exception( boost::exception const & e )
287 {
288 return boost::copy_exception(unknown_exception(e));
289 }
290
291 inline
292 exception_ptr
293 current_exception_unknown_std_exception( std::exception const & e )
294 {
295 if( boost::exception const * be = get_boost_exception(&e) )
296 return current_exception_unknown_boost_exception(*be);
297 else
298 return boost::copy_exception(unknown_exception(e));
299 }
300
301 inline
302 exception_ptr
303 current_exception_impl()
304 {
305 exception_detail::clone_base const * e=0;
306 switch(
307 exception_detail::clone_current_exception(e) )
308 {
309 case exception_detail::clone_current_exception_result::
310 success:
311 {
312 BOOST_ASSERT(e!=0);
313 return exception_ptr(shared_ptr<exception_detail::clone_base const>(e));
314 }
315 case exception_detail::clone_current_exception_result::
316 bad_alloc:
317 {
318 BOOST_ASSERT(!e);
319 return exception_detail::exception_ptr_static_exception_object<bad_alloc_>::e;
320 }
321 case exception_detail::clone_current_exception_result::
322 bad_exception:
323 {
324 BOOST_ASSERT(!e);
325 return exception_detail::exception_ptr_static_exception_object<bad_exception_>::e;
326 }
327 default:
328 BOOST_ASSERT(0);
329 case exception_detail::clone_current_exception_result::
330 not_supported:
331 {
332 BOOST_ASSERT(!e);
333 try
334 {
335 throw;
336 }
337 catch(
338 exception_detail::clone_base & e )
339 {
340 return exception_ptr(shared_ptr<exception_detail::clone_base const>(e.clone()));
341 }
342 catch(
343 std::domain_error & e )
344 {
345 return exception_detail::current_exception_std_exception(e);
346 }
347 catch(
348 std::invalid_argument & e )
349 {
350 return exception_detail::current_exception_std_exception(e);
351 }
352 catch(
353 std::length_error & e )
354 {
355 return exception_detail::current_exception_std_exception(e);
356 }
357 catch(
358 std::out_of_range & e )
359 {
360 return exception_detail::current_exception_std_exception(e);
361 }
362 catch(
363 std::logic_error & e )
364 {
365 return exception_detail::current_exception_std_exception(e);
366 }
367 catch(
368 std::range_error & e )
369 {
370 return exception_detail::current_exception_std_exception(e);
371 }
372 catch(
373 std::overflow_error & e )
374 {
375 return exception_detail::current_exception_std_exception(e);
376 }
377 catch(
378 std::underflow_error & e )
379 {
380 return exception_detail::current_exception_std_exception(e);
381 }
382 catch(
383 std::ios_base::failure & e )
384 {
385 return exception_detail::current_exception_std_exception(e);
386 }
387 catch(
388 std::runtime_error & e )
389 {
390 return exception_detail::current_exception_std_exception(e);
391 }
392 catch(
393 std::bad_alloc & e )
394 {
395 return exception_detail::current_exception_std_exception(e);
396 }
397 #ifndef BOOST_NO_TYPEID
398 catch(
399 std::bad_cast & e )
400 {
401 return exception_detail::current_exception_std_exception(e);
402 }
403 catch(
404 std::bad_typeid & e )
405 {
406 return exception_detail::current_exception_std_exception(e);
407 }
408 #endif
409 catch(
410 std::bad_exception & e )
411 {
412 return exception_detail::current_exception_std_exception(e);
413 }
414 catch(
415 std::exception & e )
416 {
417 return exception_detail::current_exception_unknown_std_exception(e);
418 }
419 catch(
420 boost::exception & e )
421 {
422 return exception_detail::current_exception_unknown_boost_exception(e);
423 }
424 catch(
425 ... )
426 {
427 return exception_detail::current_exception_unknown_exception();
428 }
429 }
430 }
431 }
432 }
433
434 inline
435 exception_ptr
436 current_exception()
437 {
438 exception_ptr ret;
439 try
440 {
441 ret=exception_detail::current_exception_impl();
442 }
443 catch(
444 std::bad_alloc & )
445 {
446 ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_alloc_>::e;
447 }
448 catch(
449 ... )
450 {
451 ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_exception_>::e;
452 }
453 BOOST_ASSERT(ret);
454 return ret;
455 }
456
457 BOOST_NORETURN
458 inline
459 void
460 rethrow_exception( exception_ptr const & p )
461 {
462 BOOST_ASSERT(p);
463 p.ptr_->rethrow();
464 BOOST_ASSERT(0);
465 #if defined(UNDER_CE)
466 // some CE platforms don't define ::abort()
467 exit(-1);
468 #else
469 abort();
470 #endif
471 }
472
473 inline
474 std::string
475 diagnostic_information( exception_ptr const & p, bool verbose=true )
476 {
477 if( p )
478 try
479 {
480 rethrow_exception(p);
481 }
482 catch(
483 ... )
484 {
485 return current_exception_diagnostic_information(verbose);
486 }
487 return "<empty>";
488 }
489
490 inline
491 std::string
492 to_string( exception_ptr const & p )
493 {
494 std::string s='\n'+diagnostic_information(p);
495 std::string padding(" ");
496 std::string r;
497 bool f=false;
498 for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i )
499 {
500 if( f )
501 r+=padding;
502 char c=*i;
503 r+=c;
504 f=(c=='\n');
505 }
506 return r;
507 }
508 }
509
510 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
511 #pragma warning(pop)
512 #endif
513 #endif