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