fix doc example typo
[boost.git] / boost / exception_ptr.hpp
blob91dce257c07daef82770ee14fe8e40221f6d3d7d
1 //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
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)
6 #ifndef UUID_FA5836A2CADA11DC8CD47C8555D89593
7 #define UUID_FA5836A2CADA11DC8CD47C8555D89593
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>
16 #include <boost/exception/detail/type_info.hpp>
17 #include <boost/shared_ptr.hpp>
18 #include <stdexcept>
19 #include <new>
20 #include <ios>
22 namespace
23 boost
25 #ifndef BOOST_NO_RTTI
26 typedef error_info<struct tag_original_exception_type,std::type_info const *> original_exception_type;
28 inline
29 std::string
30 to_string( original_exception_type const & x )
32 return x.value()->name();
34 #endif
36 class exception_ptr;
37 exception_ptr current_exception();
38 void rethrow_exception( exception_ptr const & );
40 class
41 exception_ptr:
42 public exception_detail::exception_ptr_base
44 typedef bool exception_ptr::*unspecified_bool_type;
45 friend exception_ptr current_exception();
46 friend void rethrow_exception( exception_ptr const & );
48 shared_ptr<exception_detail::clone_base const> c_;
49 bool bad_alloc_;
51 struct
52 bad_alloc_tag
56 explicit
57 exception_ptr( bad_alloc_tag ):
58 bad_alloc_(true)
62 explicit
63 exception_ptr( shared_ptr<exception_detail::clone_base const> const & c ):
64 c_(c),
65 bad_alloc_(false)
67 BOOST_ASSERT(c);
70 void
71 _rethrow() const
73 BOOST_ASSERT(*this);
74 if( bad_alloc_ )
75 throw enable_current_exception(std::bad_alloc());
76 else
77 c_->rethrow();
80 bool
81 _empty() const
83 return !bad_alloc_ && !c_;
86 public:
88 exception_ptr():
89 bad_alloc_(false)
93 operator unspecified_bool_type() const
95 return _empty() ? 0 : &exception_ptr::bad_alloc_;
98 friend
99 bool
100 operator==( exception_ptr const & a, exception_ptr const & b )
102 return a.c_==b.c_ && a.bad_alloc_==b.bad_alloc_;
105 friend
106 bool
107 operator!=( exception_ptr const & a, exception_ptr const & b )
109 return !(a==b);
113 class
114 unknown_exception:
115 public exception,
116 public std::exception,
117 public exception_detail::clone_base
119 public:
121 unknown_exception()
125 explicit
126 unknown_exception( std::exception const & e )
128 add_original_type(e);
131 explicit
132 unknown_exception( boost::exception const & e ):
133 boost::exception(e)
135 add_original_type(e);
138 ~unknown_exception() throw()
142 private:
144 exception_detail::clone_base const *
145 clone() const
147 return new unknown_exception(*this);
150 void
151 rethrow() const
153 throw*this;
156 template <class E>
157 void
158 add_original_type( E const & e )
160 #ifndef BOOST_NO_RTTI
161 (*this) << original_exception_type(&typeid(e));
162 #endif
166 namespace
167 exception_detail
169 template <class T>
170 class
171 current_exception_std_exception_wrapper:
172 public T,
173 public boost::exception,
174 public clone_base
176 public:
178 explicit
179 current_exception_std_exception_wrapper( T const & e1 ):
180 T(e1)
182 add_original_type(e1);
185 current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ):
186 T(e1),
187 boost::exception(e2)
189 add_original_type(e1);
192 ~current_exception_std_exception_wrapper() throw()
196 private:
198 clone_base const *
199 clone() const
201 return new current_exception_std_exception_wrapper(*this);
204 void
205 rethrow() const
207 throw *this;
210 template <class E>
211 void
212 add_original_type( E const & e )
214 #ifndef BOOST_NO_RTTI
215 (*this) << original_exception_type(&typeid(e));
216 #endif
220 #ifdef BOOST_NO_RTTI
221 template <class T>
222 exception const *
223 get_boost_exception( T const * )
227 throw;
229 catch(
230 exception & x )
232 return &x;
234 catch(...)
236 return 0;
239 #else
240 template <class T>
241 exception const *
242 get_boost_exception( T const * x )
244 return dynamic_cast<exception const *>(x);
246 #endif
248 template <class T>
249 inline
250 shared_ptr<clone_base const>
251 current_exception_std_exception( T const & e1 )
253 if( boost::exception const * e2 = get_boost_exception(&e1) )
254 return shared_ptr<current_exception_std_exception_wrapper<T> const>(new current_exception_std_exception_wrapper<T>(e1,*e2));
255 else
256 return shared_ptr<current_exception_std_exception_wrapper<T> const>(new current_exception_std_exception_wrapper<T>(e1));
259 inline
260 shared_ptr<clone_base const>
261 current_exception_unknown_exception()
263 return shared_ptr<unknown_exception const>(new unknown_exception());
266 inline
267 shared_ptr<clone_base const>
268 current_exception_unknown_boost_exception( boost::exception const & e )
270 return shared_ptr<unknown_exception const>(new unknown_exception(e));
273 inline
274 shared_ptr<clone_base const>
275 current_exception_unknown_std_exception( std::exception const & e )
277 if( boost::exception const * be = get_boost_exception(&e) )
278 return current_exception_unknown_boost_exception(*be);
279 else
280 return shared_ptr<unknown_exception const>(new unknown_exception(e));
283 inline
284 shared_ptr<clone_base const>
285 current_exception_impl()
289 throw;
291 catch(
292 exception_detail::clone_base & e )
294 return shared_ptr<exception_detail::clone_base const>(e.clone());
296 catch(
297 std::domain_error & e )
299 return exception_detail::current_exception_std_exception(e);
301 catch(
302 std::invalid_argument & e )
304 return exception_detail::current_exception_std_exception(e);
306 catch(
307 std::length_error & e )
309 return exception_detail::current_exception_std_exception(e);
311 catch(
312 std::out_of_range & e )
314 return exception_detail::current_exception_std_exception(e);
316 catch(
317 std::logic_error & e )
319 return exception_detail::current_exception_std_exception(e);
321 catch(
322 std::range_error & e )
324 return exception_detail::current_exception_std_exception(e);
326 catch(
327 std::overflow_error & e )
329 return exception_detail::current_exception_std_exception(e);
331 catch(
332 std::underflow_error & e )
334 return exception_detail::current_exception_std_exception(e);
336 catch(
337 std::ios_base::failure & e )
339 return exception_detail::current_exception_std_exception(e);
341 catch(
342 std::runtime_error & e )
344 return exception_detail::current_exception_std_exception(e);
346 catch(
347 std::bad_alloc & e )
349 return exception_detail::current_exception_std_exception(e);
351 #ifndef BOOST_NO_TYPEID
352 catch(
353 std::bad_cast & e )
355 return exception_detail::current_exception_std_exception(e);
357 catch(
358 std::bad_typeid & e )
360 return exception_detail::current_exception_std_exception(e);
362 #endif
363 catch(
364 std::bad_exception & e )
366 return exception_detail::current_exception_std_exception(e);
368 catch(
369 std::exception & e )
371 return exception_detail::current_exception_unknown_std_exception(e);
373 catch(
374 boost::exception & e )
376 return exception_detail::current_exception_unknown_boost_exception(e);
378 catch(
379 ... )
381 return exception_detail::current_exception_unknown_exception();
386 inline
387 exception_ptr
388 current_exception()
392 return exception_ptr(exception_detail::current_exception_impl());
394 catch(
395 std::bad_alloc & )
398 catch(
399 ... )
403 return exception_ptr(exception_detail::current_exception_std_exception(std::bad_exception()));
405 catch(
406 std::bad_alloc & )
409 catch(
410 ... )
412 BOOST_ASSERT(0);
415 return exception_ptr(exception_ptr::bad_alloc_tag());
418 template <class T>
419 inline
420 exception_ptr
421 copy_exception( T const & e )
425 throw enable_current_exception(e);
427 catch(
428 ... )
430 return current_exception();
434 inline
435 void
436 rethrow_exception( exception_ptr const & p )
438 p._rethrow();
441 inline
442 std::string
443 to_string( exception_ptr const & p )
445 std::string s='\n'+diagnostic_information(p);
446 std::string padding(" ");
447 std::string r;
448 bool f=false;
449 for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i )
451 if( f )
452 r+=padding;
453 char c=*i;
454 r+=c;
455 f=(c=='\n');
457 return r;
461 #endif