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.
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>
26 typedef error_info
<struct tag_original_exception_type
,std::type_info
const *> original_exception_type
;
30 to_string( original_exception_type
const & x
)
32 return x
.value()->name();
37 exception_ptr
current_exception();
38 void rethrow_exception( exception_ptr
const & );
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_
;
57 exception_ptr( bad_alloc_tag
):
63 exception_ptr( shared_ptr
<exception_detail::clone_base
const> const & c
):
75 throw enable_current_exception(std::bad_alloc());
83 return !bad_alloc_
&& !c_
;
93 operator unspecified_bool_type() const
95 return _empty() ? 0 : &exception_ptr::bad_alloc_
;
100 operator==( exception_ptr
const & a
, exception_ptr
const & b
)
102 return a
.c_
==b
.c_
&& a
.bad_alloc_
==b
.bad_alloc_
;
107 operator!=( exception_ptr
const & a
, exception_ptr
const & b
)
116 public std::exception
,
117 public exception_detail::clone_base
126 unknown_exception( std::exception
const & e
)
128 add_original_type(e
);
132 unknown_exception( boost::exception
const & e
):
135 add_original_type(e
);
138 ~unknown_exception() throw()
144 exception_detail::clone_base
const *
147 return new unknown_exception(*this);
158 add_original_type( E
const & e
)
160 #ifndef BOOST_NO_RTTI
161 (*this) << original_exception_type(&typeid(e
));
171 current_exception_std_exception_wrapper
:
173 public boost::exception
,
179 current_exception_std_exception_wrapper( T
const & e1
):
182 add_original_type(e1
);
185 current_exception_std_exception_wrapper( T
const & e1
, boost::exception
const & e2
):
189 add_original_type(e1
);
192 ~current_exception_std_exception_wrapper() throw()
201 return new current_exception_std_exception_wrapper(*this);
212 add_original_type( E
const & e
)
214 #ifndef BOOST_NO_RTTI
215 (*this) << original_exception_type(&typeid(e
));
223 get_boost_exception( T
const * )
242 get_boost_exception( T
const * x
)
244 return dynamic_cast<exception
const *>(x
);
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
));
256 return shared_ptr
<current_exception_std_exception_wrapper
<T
> const>(new current_exception_std_exception_wrapper
<T
>(e1
));
260 shared_ptr
<clone_base
const>
261 current_exception_unknown_exception()
263 return shared_ptr
<unknown_exception
const>(new unknown_exception());
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
));
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
);
280 return shared_ptr
<unknown_exception
const>(new unknown_exception(e
));
284 shared_ptr
<clone_base
const>
285 current_exception_impl()
292 exception_detail::clone_base
& e
)
294 return shared_ptr
<exception_detail::clone_base
const>(e
.clone());
297 std::domain_error
& e
)
299 return exception_detail::current_exception_std_exception(e
);
302 std::invalid_argument
& e
)
304 return exception_detail::current_exception_std_exception(e
);
307 std::length_error
& e
)
309 return exception_detail::current_exception_std_exception(e
);
312 std::out_of_range
& e
)
314 return exception_detail::current_exception_std_exception(e
);
317 std::logic_error
& e
)
319 return exception_detail::current_exception_std_exception(e
);
322 std::range_error
& e
)
324 return exception_detail::current_exception_std_exception(e
);
327 std::overflow_error
& e
)
329 return exception_detail::current_exception_std_exception(e
);
332 std::underflow_error
& e
)
334 return exception_detail::current_exception_std_exception(e
);
337 std::ios_base::failure
& e
)
339 return exception_detail::current_exception_std_exception(e
);
342 std::runtime_error
& e
)
344 return exception_detail::current_exception_std_exception(e
);
349 return exception_detail::current_exception_std_exception(e
);
351 #ifndef BOOST_NO_TYPEID
355 return exception_detail::current_exception_std_exception(e
);
358 std::bad_typeid
& e
)
360 return exception_detail::current_exception_std_exception(e
);
364 std::bad_exception
& e
)
366 return exception_detail::current_exception_std_exception(e
);
371 return exception_detail::current_exception_unknown_std_exception(e
);
374 boost::exception
& e
)
376 return exception_detail::current_exception_unknown_boost_exception(e
);
381 return exception_detail::current_exception_unknown_exception();
392 return exception_ptr(exception_detail::current_exception_impl());
403 return exception_ptr(exception_detail::current_exception_std_exception(std::bad_exception()));
415 return exception_ptr(exception_ptr::bad_alloc_tag());
421 copy_exception( T
const & e
)
425 throw enable_current_exception(e
);
430 return current_exception();
436 rethrow_exception( exception_ptr
const & p
)
443 to_string( exception_ptr
const & p
)
445 std::string s
='\n'+diagnostic_information(p
);
446 std::string
padding(" ");
449 for( std::string::const_iterator i
=s
.begin(),e
=s
.end(); i
!=e
; ++i
)