//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 #include #include #include #include #include typedef boost::error_info my_info; template 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 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(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 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(x); BOOST_TEST(t!=0 && *t!=0 && **t==typeid(T)); #endif } catch( T & ) { } catch( ... ) { BOOST_TEST(false); } } } template void test_throw_on_copy() { try { try { throw boost::enable_current_exception(may_throw_on_copy()); } catch( may_throw_on_copy & 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(e); BOOST_TEST(t!=0 && *t!=0 && **t==typeid(derives_std_exception)); #endif } catch( ... ) { BOOST_TEST(false); } } test_std_exception_what(); test_std_exception_what(); test_std_exception_what(); test_std_exception_what(); test_std_exception_what(); test_std_exception_what(); test_std_exception_what(); test_std_exception_what(); test_std_exception_what(); test_std_exception_what(); test_std_exception(); #ifndef BOOST_NO_TYPEID test_std_exception(); test_std_exception(); #endif test_std_exception(); test_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(x)); if( int const * p=boost::get_error_info(x) ) BOOST_TEST(*p==42); } catch( boost::unknown_exception & x ) { BOOST_TEST(boost::get_error_info(x)); if( int const * p=boost::get_error_info(x) ) BOOST_TEST(*p==42); #ifndef BOOST_NO_RTTI { std::type_info const * const * t=boost::get_error_info(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(x)); if( int const * p=boost::get_error_info(x) ) BOOST_TEST(*p==42); #ifndef BOOST_NO_RTTI std::type_info const * const * t=boost::get_error_info(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(x)); if( int const * p=boost::get_error_info(x) ) BOOST_TEST(*p==42); } catch( boost::unknown_exception & x ) { BOOST_TEST(boost::get_error_info(x)); if( int const * p=boost::get_error_info(x) ) BOOST_TEST(*p==42); #ifndef BOOST_NO_RTTI { std::type_info const * const * t=boost::get_error_info(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(x)); if( int const * p=boost::get_error_info(x) ) BOOST_TEST(*p==42); } catch( ... ) { BOOST_TEST(false); } } catch( ... ) { BOOST_TEST(false); } } test_throw_on_copy(); test_throw_on_copy(); 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(); }