//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 struct throws_on_copy; struct non_printable { }; struct user_data { int & count; explicit user_data( int & count ): count(count) { ++count; } user_data( user_data const & x ): count(x.count) { ++count; } ~user_data() { --count; } }; #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) struct tag_test_1 {}; struct tag_test_2 {}; struct tag_test_3 {}; struct tag_test_4 {}; struct tag_test_5 {}; struct tag_test_6 {}; struct tag_user_data {}; #endif typedef boost::error_info test_1; typedef boost::error_info test_2; typedef boost::error_info test_3; typedef boost::error_info test_4; typedef boost::error_info test_5; typedef boost::error_info test_6; typedef boost::error_info test_7; struct test_exception: boost::exception { }; struct throws_on_copy { throws_on_copy() { } throws_on_copy( throws_on_copy const & ) { throw test_exception(); } }; void basic_test() { try { test_exception x; x << test_1(1) << test_2(2u) << test_3(3.14159f); throw x; } catch( test_exception & x ) { ++*boost::get_error_info(x); ++*boost::get_error_info(x); ++*boost::get_error_info(x); BOOST_TEST(*boost::get_error_info(x)==2); BOOST_TEST(*boost::get_error_info(x)==3u); BOOST_TEST(*boost::get_error_info(x)==4.14159f); BOOST_TEST(!boost::get_error_info(x)); } try { test_exception x; x << test_1(1) << test_2(2u) << test_3(3.14159f); throw x; } catch( test_exception const & x ) { BOOST_TEST(*boost::get_error_info(x)==1); BOOST_TEST(*boost::get_error_info(x)==2u); BOOST_TEST(*boost::get_error_info(x)==3.14159f); BOOST_TEST(!boost::get_error_info(x)); } } void exception_safety_test() { test_exception x; try { x << test_4(throws_on_copy()); BOOST_TEST(false); } catch( test_exception & ) { BOOST_TEST(!boost::get_error_info(x)); } } void throw_empty() { throw test_exception(); } void throw_test_1( char const * value ) { throw test_exception() << test_5(std::string(value)); } void throw_test_2() { throw test_exception() << test_6(non_printable()); } void throw_catch_add_file_name( char const * name ) { try { throw_empty(); BOOST_TEST(false); } catch( boost::exception & x ) { x << test_5(std::string(name)); throw; } } void test_empty() { try { throw_empty(); BOOST_TEST(false); } catch( boost::exception & x ) { #ifndef BOOST_NO_RTTI BOOST_TEST( dynamic_cast(&x) ); #endif BOOST_TEST( !boost::get_error_info(x) ); } catch( ... ) { BOOST_TEST(false); } try { throw_empty(); BOOST_TEST(false); } catch( test_exception & x ) { #ifndef BOOST_NO_RTTI BOOST_TEST( dynamic_cast(&x)!=0 ); #endif } catch( ... ) { BOOST_TEST(false); } } void test_basic_throw_catch() { try { throw_test_1("test"); BOOST_ASSERT(false); } catch( boost::exception & x ) { BOOST_TEST(*boost::get_error_info(x)==std::string("test")); } catch( ... ) { BOOST_TEST(false); } try { throw_test_2(); BOOST_ASSERT(false); } catch( boost::exception & x ) { BOOST_TEST(boost::get_error_info(x)); } catch( ... ) { BOOST_TEST(false); } } void test_catch_add_info() { try { throw_catch_add_file_name("test"); BOOST_TEST(false); } catch( boost::exception & x ) { BOOST_TEST(*boost::get_error_info(x)==std::string("test")); } catch( ... ) { BOOST_TEST(false); } } void test_add_tuple() { typedef boost::tuple test_12; typedef boost::tuple test_123; typedef boost::tuple test_1235; try { throw test_exception() << test_12(42,42u); } catch( test_exception & x ) { BOOST_TEST( *boost::get_error_info(x)==42 ); BOOST_TEST( *boost::get_error_info(x)==42u ); } catch( ... ) { BOOST_TEST(false); } try { throw test_exception() << test_123(42,42u,42.0f); } catch( test_exception & x ) { BOOST_TEST( *boost::get_error_info(x)==42 ); BOOST_TEST( *boost::get_error_info(x)==42u ); BOOST_TEST( *boost::get_error_info(x)==42.0f ); } catch( ... ) { BOOST_TEST(false); } try { throw test_exception() << test_1235(42,42u,42.0f,std::string("42")); } catch( test_exception & x ) { BOOST_TEST( *boost::get_error_info(x)==42 ); BOOST_TEST( *boost::get_error_info(x)==42u ); BOOST_TEST( *boost::get_error_info(x)==42.0f ); BOOST_TEST( *boost::get_error_info(x)=="42" ); } catch( ... ) { BOOST_TEST(false); } } void test_lifetime() { int count=0; try { throw test_exception() << test_7(user_data(count)); BOOST_TEST(false); } catch( boost::exception & x ) { BOOST_TEST(count==1); BOOST_TEST( boost::get_error_info(x) ); } catch( ... ) { BOOST_TEST(false); } BOOST_TEST(!count); } bool is_const( int const * ) { return true; } bool is_const( int * ) { return false; } void test_const() { test_exception e; boost::exception const & c(e); boost::exception & m(e); BOOST_TEST(is_const(boost::get_error_info(c))); BOOST_TEST(!is_const(boost::get_error_info(m))); } int main() { basic_test(); exception_safety_test(); test_empty(); test_basic_throw_catch(); test_catch_add_info(); test_add_tuple(); test_lifetime(); test_const(); return boost::report_errors(); }