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 #include <boost/config.hpp>
8 #if defined( BOOST_NO_EXCEPTIONS )
9 # error This program requires exception handling.
12 #include <boost/exception_ptr.hpp>
13 #include <boost/exception/get_error_info.hpp>
14 #include <boost/exception/errinfo_nested_exception.hpp>
15 #include <boost/detail/lightweight_test.hpp>
16 #include <boost/detail/workaround.hpp>
20 typedef boost::error_info
<struct my_tag
,int> my_info
;
31 may_throw_on_copy( may_throw_on_copy
const & x
):
47 derives_nothing( int & c
):
53 derives_nothing( derives_nothing
const & x
):
66 derives_std_exception
:
72 derives_std_boost_exception
:
76 char const * const wh_
;
78 derives_std_boost_exception( char const * wh
="derives_std_boost_exception" ):
83 char const * what() const BOOST_NOEXCEPT_OR_NOTHROW
90 derives_boost_exception
:
106 boost::exception_ptr p
= boost::current_exception();
107 BOOST_TEST(!(p
==boost::exception_ptr()));
108 BOOST_TEST(p
!=boost::exception_ptr());
112 rethrow_exception(p
);
118 boost::exception_ptr p
= boost::current_exception();
119 BOOST_TEST(!(p
==boost::exception_ptr()));
120 BOOST_TEST(p
!=boost::exception_ptr());
124 rethrow_exception(p
);
144 rethrow_exception(p
);
148 boost::exception
& x
)
150 #ifndef BOOST_NO_RTTI
151 std::type_info
const * const * t
=boost::get_error_info
<boost::original_exception_type
>(x
);
152 BOOST_TEST(t
!=0 && *t
!=0 && **t
==typeid(T
));
153 std::string s
=diagnostic_information(x
);
154 BOOST_TEST(!s
.empty());
171 test_std_exception_what()
180 boost::exception_ptr p
= boost::current_exception();
181 BOOST_TEST(!(p
==boost::exception_ptr()));
182 BOOST_TEST(p
!=boost::exception_ptr());
186 rethrow_exception(p
);
192 BOOST_TEST(std::string(x
.what()).find("what")!=std::string::npos
);
193 boost::exception_ptr p
= boost::current_exception();
194 BOOST_TEST(!(p
==boost::exception_ptr()));
195 BOOST_TEST(p
!=boost::exception_ptr());
199 rethrow_exception(p
);
205 BOOST_TEST(std::string(x
.what()).find("what")!=std::string::npos
);
220 rethrow_exception(p
);
224 boost::exception
& x
)
226 #ifndef BOOST_NO_RTTI
227 std::type_info
const * const * t
=boost::get_error_info
<boost::original_exception_type
>(x
);
228 BOOST_TEST(t
!=0 && *t
!=0 && **t
==typeid(T
));
243 template <class Throw
,class Catch
>
251 throw boost::enable_current_exception(may_throw_on_copy
<Throw
>());
254 may_throw_on_copy
<Throw
> & x
)
268 boost::exception_ptr p
= boost::current_exception();
269 BOOST_TEST(!(p
==boost::exception_ptr()));
270 BOOST_TEST(p
!=boost::exception_ptr());
274 rethrow_exception(p
);
280 boost::exception_ptr p
= boost::current_exception();
281 BOOST_TEST(!(p
==boost::exception_ptr()));
282 BOOST_TEST(p
!=boost::exception_ptr());
286 boost::rethrow_exception(p
);
310 BOOST_TEST( boost::exception_ptr()==boost::exception_ptr() );
311 BOOST_TEST( !(boost::exception_ptr()!=boost::exception_ptr()) );
312 BOOST_TEST( !boost::exception_ptr() );
317 throw boost::enable_current_exception(derives_nothing(count
));
322 boost::exception_ptr p
= boost::current_exception();
323 BOOST_TEST(!(p
==boost::exception_ptr()));
324 BOOST_TEST(p
!=boost::exception_ptr());
328 rethrow_exception(p
);
341 BOOST_TEST(count
==0);
345 throw boost::enable_current_exception(derives_std_exception());
350 boost::exception_ptr p
= boost::current_exception();
351 BOOST_TEST(!(p
==boost::exception_ptr()));
352 BOOST_TEST(p
!=boost::exception_ptr());
356 rethrow_exception(p
);
360 derives_std_exception
& )
362 boost::exception_ptr p
= boost::current_exception();
363 BOOST_TEST(!(p
==boost::exception_ptr()));
364 BOOST_TEST(p
!=boost::exception_ptr());
368 rethrow_exception(p
);
372 derives_std_exception
& )
390 throw derives_std_exception();
395 boost::exception_ptr p
= boost::current_exception();
396 BOOST_TEST(!(p
==boost::exception_ptr()));
397 BOOST_TEST(p
!=boost::exception_ptr());
401 rethrow_exception(p
);
405 derives_std_exception
& )
407 //Yay! Non-intrusive cloning supported!
410 boost::unknown_exception
& e
)
412 #ifndef BOOST_NO_RTTI
413 std::type_info
const * const * t
=boost::get_error_info
<boost::original_exception_type
>(e
);
414 BOOST_TEST(t
!=0 && *t
!=0 && **t
==typeid(derives_std_exception
));
424 test_std_exception_what
<std::domain_error
>();
425 test_std_exception_what
<std::invalid_argument
>();
426 test_std_exception_what
<std::length_error
>();
427 test_std_exception_what
<std::out_of_range
>();
428 test_std_exception_what
<std::logic_error
>();
429 test_std_exception_what
<std::range_error
>();
430 test_std_exception_what
<std::overflow_error
>();
431 test_std_exception_what
<std::underflow_error
>();
432 #if !defined(_GLIBCXX_USE_CXX11_ABI) || !_GLIBCXX_USE_CXX11_ABI
433 test_std_exception_what
<std::ios_base::failure
>();
435 test_std_exception_what
<std::runtime_error
>();
436 test_std_exception
<std::bad_alloc
>();
437 #ifndef BOOST_NO_TYPEID
438 test_std_exception
<std::bad_cast
>();
439 test_std_exception
<std::bad_typeid
>();
441 test_std_exception
<std::bad_exception
>();
442 test_std_exception
<std::exception
>();
446 throw derives_std_boost_exception() << my_info(42);
451 boost::exception_ptr p
= boost::current_exception();
452 BOOST_TEST(!(p
==boost::exception_ptr()));
453 BOOST_TEST(p
!=boost::exception_ptr());
457 rethrow_exception(p
);
461 derives_std_boost_exception
& x
)
463 //Yay! Non-intrusive cloning supported!
464 BOOST_TEST(boost::get_error_info
<my_info
>(x
));
465 if( int const * p
=boost::get_error_info
<my_info
>(x
) )
469 boost::unknown_exception
& x
)
471 BOOST_TEST(boost::get_error_info
<my_info
>(x
));
472 if( int const * p
=boost::get_error_info
<my_info
>(x
) )
474 #ifndef BOOST_NO_RTTI
476 std::type_info
const * const * t
=boost::get_error_info
<boost::original_exception_type
>(x
);
477 BOOST_TEST(t
&& *t
&& **t
==typeid(derives_std_boost_exception
));
480 boost::exception_ptr p
= boost::current_exception();
481 BOOST_TEST(!(p
==boost::exception_ptr()));
482 BOOST_TEST(p
!=boost::exception_ptr());
486 rethrow_exception(p
);
490 boost::unknown_exception
& x
)
492 BOOST_TEST(boost::get_error_info
<my_info
>(x
));
493 if( int const * p
=boost::get_error_info
<my_info
>(x
) )
495 #ifndef BOOST_NO_RTTI
496 std::type_info
const * const * t
=boost::get_error_info
<boost::original_exception_type
>(x
);
497 BOOST_TEST(t
&& *t
&& **t
==typeid(derives_std_boost_exception
));
515 throw derives_boost_exception() << my_info(42);
520 boost::exception_ptr p
= boost::current_exception();
521 BOOST_TEST(!(p
==boost::exception_ptr()));
522 BOOST_TEST(p
!=boost::exception_ptr());
526 rethrow_exception(p
);
530 derives_boost_exception
& x
)
532 //Yay! Non-intrusive cloning supported!
533 BOOST_TEST(boost::get_error_info
<my_info
>(x
));
534 if( int const * p
=boost::get_error_info
<my_info
>(x
) )
538 boost::unknown_exception
& x
)
540 BOOST_TEST(boost::get_error_info
<my_info
>(x
));
541 if( int const * p
=boost::get_error_info
<my_info
>(x
) )
543 #ifndef BOOST_NO_RTTI
545 std::type_info
const * const * t
=boost::get_error_info
<boost::original_exception_type
>(x
);
546 BOOST_TEST(t
&& *t
&& **t
==typeid(derives_boost_exception
));
549 boost::exception_ptr p
= boost::current_exception();
550 BOOST_TEST(!(p
==boost::exception_ptr()));
551 BOOST_TEST(p
!=boost::exception_ptr());
555 rethrow_exception(p
);
559 boost::unknown_exception
& x
)
561 BOOST_TEST(boost::get_error_info
<my_info
>(x
));
562 if( int const * p
=boost::get_error_info
<my_info
>(x
) )
578 test_throw_on_copy
<std::bad_alloc
,std::bad_alloc
>();
579 test_throw_on_copy
<int,std::bad_exception
>();
583 throw boost::enable_current_exception(derives_std_boost_exception("what1"));
588 boost::exception_ptr p
=boost::current_exception();
590 std::string s
=diagnostic_information(p
);
591 BOOST_TEST(s
.find("what1")!=s
.npos
);
595 throw boost::enable_current_exception(derives_std_boost_exception("what2") << boost::errinfo_nested_exception(p
) );
600 std::string s
=boost::current_exception_diagnostic_information();
601 BOOST_TEST(s
.find("what1")!=s
.npos
);
602 BOOST_TEST(s
.find("what2")!=s
.npos
);
605 BOOST_TEST(!diagnostic_information(boost::exception_ptr()).empty());
606 return boost::report_errors();