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