123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598 |
- //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
- //Distributed under the Boost Software License, Version 1.0. (See accompanying
- //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #include <boost/exception_ptr.hpp>
- #include <boost/exception/get_error_info.hpp>
- #include <boost/exception/errinfo_nested_exception.hpp>
- #include <boost/detail/lightweight_test.hpp>
- #include <boost/detail/workaround.hpp>
- #include <string>
- typedef boost::error_info<struct my_tag,int> my_info;
- template <class T>
- struct
- may_throw_on_copy
- {
- may_throw_on_copy():
- throw_(false)
- {
- }
- may_throw_on_copy( may_throw_on_copy const & x ):
- throw_(x.throw_)
- {
- if( throw_ )
- throw T();
- }
- bool throw_;
- };
- struct
- derives_nothing
- {
- int & count;
- explicit
- derives_nothing( int & c ):
- count(c)
- {
- ++count;
- }
- derives_nothing( derives_nothing const & x ):
- count(x.count)
- {
- ++count;
- }
- ~derives_nothing()
- {
- --count;
- }
- };
- struct
- derives_std_exception:
- std::exception
- {
- };
- struct
- derives_std_boost_exception:
- std::exception,
- boost::exception
- {
- char const * const wh_;
- derives_std_boost_exception( char const * wh="derives_std_boost_exception" ):
- wh_(wh)
- {
- }
- char const * what() const BOOST_NOEXCEPT_OR_NOTHROW
- {
- return wh_;
- }
- };
- struct
- derives_boost_exception:
- boost::exception
- {
- };
- template <class T>
- void
- test_std_exception()
- {
- try
- {
- throw T();
- }
- catch(
- ... )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- T & )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- T & )
- {
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- boost::exception & x )
- {
- #ifndef BOOST_NO_RTTI
- std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(x);
- BOOST_TEST(t!=0 && *t!=0 && **t==typeid(T));
- std::string s=diagnostic_information(x);
- BOOST_TEST(!s.empty());
- #endif
- }
- catch(
- T & )
- {
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- }
- template <class T>
- void
- test_std_exception_what()
- {
- try
- {
- throw T("what");
- }
- catch(
- ... )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- T & x )
- {
- BOOST_TEST(std::string(x.what()).find("what")!=std::string::npos);
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- T & x )
- {
- BOOST_TEST(std::string(x.what()).find("what")!=std::string::npos);
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- boost::exception & x )
- {
- #ifndef BOOST_NO_RTTI
- std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(x);
- BOOST_TEST(t!=0 && *t!=0 && **t==typeid(T));
- #endif
- }
- catch(
- T & )
- {
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- }
- template <class Throw,class Catch>
- void
- test_throw_on_copy()
- {
- try
- {
- try
- {
- throw boost::enable_current_exception(may_throw_on_copy<Throw>());
- }
- catch(
- may_throw_on_copy<Throw> & x )
- {
- x.throw_=true;
- throw;
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- catch(
- ... )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- Catch & )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- boost::rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- Catch & )
- {
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- }
- int
- main()
- {
- BOOST_TEST( boost::exception_ptr()==boost::exception_ptr() );
- BOOST_TEST( !(boost::exception_ptr()!=boost::exception_ptr()) );
- BOOST_TEST( !boost::exception_ptr() );
- int count=0;
- try
- {
- throw boost::enable_current_exception(derives_nothing(count));
- }
- catch(
- ... )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- derives_nothing & )
- {
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- BOOST_TEST(count==0);
- try
- {
- throw boost::enable_current_exception(derives_std_exception());
- }
- catch(
- ... )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- derives_std_exception & )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- derives_std_exception & )
- {
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- try
- {
- throw derives_std_exception();
- }
- catch(
- ... )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- derives_std_exception & )
- {
- //Yay! Non-intrusive cloning supported!
- }
- catch(
- boost::unknown_exception & e )
- {
- #ifndef BOOST_NO_RTTI
- std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(e);
- BOOST_TEST(t!=0 && *t!=0 && **t==typeid(derives_std_exception));
- #endif
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- test_std_exception_what<std::domain_error>();
- test_std_exception_what<std::invalid_argument>();
- test_std_exception_what<std::length_error>();
- test_std_exception_what<std::out_of_range>();
- test_std_exception_what<std::logic_error>();
- test_std_exception_what<std::range_error>();
- test_std_exception_what<std::overflow_error>();
- test_std_exception_what<std::underflow_error>();
- test_std_exception_what<std::ios_base::failure>();
- test_std_exception_what<std::runtime_error>();
- test_std_exception<std::bad_alloc>();
- #ifndef BOOST_NO_TYPEID
- test_std_exception<std::bad_cast>();
- test_std_exception<std::bad_typeid>();
- #endif
- test_std_exception<std::bad_exception>();
- test_std_exception<std::exception>();
- try
- {
- throw derives_std_boost_exception() << my_info(42);
- }
- catch(
- ... )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- derives_std_boost_exception & x )
- {
- //Yay! Non-intrusive cloning supported!
- BOOST_TEST(boost::get_error_info<my_info>(x));
- if( int const * p=boost::get_error_info<my_info>(x) )
- BOOST_TEST(*p==42);
- }
- catch(
- boost::unknown_exception & x )
- {
- BOOST_TEST(boost::get_error_info<my_info>(x));
- if( int const * p=boost::get_error_info<my_info>(x) )
- BOOST_TEST(*p==42);
- #ifndef BOOST_NO_RTTI
- {
- std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(x);
- BOOST_TEST(t && *t && **t==typeid(derives_std_boost_exception));
- }
- #endif
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- boost::unknown_exception & x )
- {
- BOOST_TEST(boost::get_error_info<my_info>(x));
- if( int const * p=boost::get_error_info<my_info>(x) )
- BOOST_TEST(*p==42);
- #ifndef BOOST_NO_RTTI
- std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(x);
- BOOST_TEST(t && *t && **t==typeid(derives_std_boost_exception));
- #endif
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- try
- {
- throw derives_boost_exception() << my_info(42);
- }
- catch(
- ... )
- {
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- derives_boost_exception & x )
- {
- //Yay! Non-intrusive cloning supported!
- BOOST_TEST(boost::get_error_info<my_info>(x));
- if( int const * p=boost::get_error_info<my_info>(x) )
- BOOST_TEST(*p==42);
- }
- catch(
- boost::unknown_exception & x )
- {
- BOOST_TEST(boost::get_error_info<my_info>(x));
- if( int const * p=boost::get_error_info<my_info>(x) )
- BOOST_TEST(*p==42);
- #ifndef BOOST_NO_RTTI
- {
- std::type_info const * const * t=boost::get_error_info<boost::original_exception_type>(x);
- BOOST_TEST(t && *t && **t==typeid(derives_boost_exception));
- }
- #endif
- boost::exception_ptr p = boost::current_exception();
- BOOST_TEST(!(p==boost::exception_ptr()));
- BOOST_TEST(p!=boost::exception_ptr());
- BOOST_TEST(p);
- try
- {
- rethrow_exception(p);
- BOOST_TEST(false);
- }
- catch(
- boost::unknown_exception & x )
- {
- BOOST_TEST(boost::get_error_info<my_info>(x));
- if( int const * p=boost::get_error_info<my_info>(x) )
- BOOST_TEST(*p==42);
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- catch(
- ... )
- {
- BOOST_TEST(false);
- }
- }
- test_throw_on_copy<std::bad_alloc,std::bad_alloc>();
- test_throw_on_copy<int,std::bad_exception>();
- try
- {
- throw boost::enable_current_exception(derives_std_boost_exception("what1"));
- }
- catch(
- ... )
- {
- boost::exception_ptr p=boost::current_exception();
- {
- std::string s=diagnostic_information(p);
- BOOST_TEST(s.find("what1")!=s.npos);
- }
- try
- {
- throw boost::enable_current_exception(derives_std_boost_exception("what2") << boost::errinfo_nested_exception(p) );
- }
- catch(
- ... )
- {
- std::string s=boost::current_exception_diagnostic_information();
- BOOST_TEST(s.find("what1")!=s.npos);
- BOOST_TEST(s.find("what2")!=s.npos);
- }
- }
- BOOST_TEST(!diagnostic_information(boost::exception_ptr()).empty());
- return boost::report_errors();
- }
|