// Copyright 2018-2022 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 #ifdef BOOST_LEAF_NO_EXCEPTIONS #include int main() { std::cout << "Unit test not applicable." << std::endl; return 0; } #else #ifdef BOOST_LEAF_TEST_SINGLE_HEADER # include "leaf.hpp" #else # include # include # include # include #endif #include "lightweight_test.hpp" namespace leaf = boost::leaf; struct info { int value; }; struct abstract_base_exception { virtual ~abstract_base_exception() { } virtual int get_val() const = 0; }; struct my_exception: std::exception, abstract_base_exception { int val;; explicit my_exception(int v): val{v} { } int get_val() const { return val; } }; int get_val( abstract_base_exception const & ex ) { return ex.get_val(); } int get_val( my_exception const & ex ) { return ex.val; } int get_val( leaf::catch_ const & ex ) { return ex.matched.get_val(); } int get_val( leaf::catch_ const & ex ) { return ex.matched.val; } template int test( F && f ) { return leaf::try_catch( [&]() -> int { f(); return 0; }, []( Ex ex, leaf::match_value, leaf::e_source_location ) { BOOST_TEST_EQ(get_val(ex), 42); return 20; }, []( Ex ex, leaf::match_value, info ) { BOOST_TEST_EQ(get_val(ex), 42); return 21; }, []( Ex ex, leaf::e_source_location ) { BOOST_TEST_EQ(get_val(ex), 42); return 22; }, []( Ex ex ) { BOOST_TEST_EQ(get_val(ex), 42); return 23; }, []( leaf::match_value, leaf::e_source_location ) { return 40; }, []( leaf::match_value, info ) { return 41; }, []( leaf::e_source_location ) { return 42; }, [] { return 43; } ); } int main() { BOOST_TEST_EQ(20, test>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test>([]{ leaf::throw_exception(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test>([]{ my_exception exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(21, test>([]{ my_exception const exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(22, test>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(23, test>([]{ leaf::throw_exception(my_exception(42)); })); BOOST_TEST_EQ(23, test>([]{ my_exception exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(23, test>([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(20, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test([]{ leaf::throw_exception(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test([]{ my_exception exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(22, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(23, test([]{ leaf::throw_exception(my_exception(42)); })); BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(40, test([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); })); BOOST_TEST_EQ(41, test([]{ leaf::throw_exception(info{42}); })); BOOST_TEST_EQ(41, test([]{ info inf{42}; leaf::throw_exception(inf); })); BOOST_TEST_EQ(41, test([]{ info const inf{42}; leaf::throw_exception(inf); })); BOOST_TEST_EQ(42, test([]{ BOOST_LEAF_THROW_EXCEPTION(); })); BOOST_TEST_EQ(43, test([]{ leaf::throw_exception(); })); BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(20, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test([]{ leaf::throw_exception(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test([]{ my_exception exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(22, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(23, test([]{ leaf::throw_exception(my_exception(42)); })); BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(40, test([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); })); BOOST_TEST_EQ(41, test([]{ leaf::throw_exception(info{42}); })); BOOST_TEST_EQ(41, test([]{ info inf{42}; leaf::throw_exception(inf); })); BOOST_TEST_EQ(41, test([]{ info const inf{42}; leaf::throw_exception(inf); })); BOOST_TEST_EQ(42, test([]{ BOOST_LEAF_THROW_EXCEPTION(); })); BOOST_TEST_EQ(43, test([]{ leaf::throw_exception(); })); BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(20, test>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test>([]{ leaf::throw_exception(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test>([]{ my_exception exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(21, test>([]{ my_exception const exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(22, test>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(23, test>([]{ leaf::throw_exception(my_exception(42)); })); BOOST_TEST_EQ(23, test>([]{ my_exception exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(23, test>([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(20, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test([]{ leaf::throw_exception(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test([]{ my_exception exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(22, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(23, test([]{ leaf::throw_exception(my_exception(42)); })); BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(40, test([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); })); BOOST_TEST_EQ(41, test([]{ leaf::throw_exception(info{42}); })); BOOST_TEST_EQ(41, test([]{ info inf{42}; leaf::throw_exception(inf); })); BOOST_TEST_EQ(41, test([]{ info const inf{42}; leaf::throw_exception(inf); })); BOOST_TEST_EQ(42, test([]{ BOOST_LEAF_THROW_EXCEPTION(); })); BOOST_TEST_EQ(43, test([]{ leaf::throw_exception(); })); BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); { char const * wh = 0; leaf::try_catch( [] { throw std::runtime_error("Test"); }, [&]( std::exception const & ex ) { wh = ex.what(); } ); BOOST_TEST(wh!=0 || !strcmp(wh,"Test")); } { int const id = leaf::leaf_detail::current_id(); BOOST_TEST_EQ( 21, test( [] { auto load = leaf::on_error(info{42}); throw my_exception(42); } ) ); BOOST_TEST_NE(id, leaf::leaf_detail::current_id()); } { int const id = leaf::leaf_detail::current_id(); BOOST_TEST_EQ( 21, test( [] { auto load = leaf::on_error(info{42}); throw my_exception(42); } ) ); BOOST_TEST_NE(id, leaf::leaf_detail::current_id()); } { BOOST_TEST_EQ( 23, test( [] { int const id = leaf::leaf_detail::current_id(); try { leaf::try_catch( [] { throw my_exception(42); } ); } catch(...) { BOOST_TEST_EQ(id, leaf::leaf_detail::current_id()); throw; } } ) ); } { BOOST_TEST_EQ( 23, test( [] { int const id = leaf::leaf_detail::current_id(); try { leaf::try_catch( [] { throw my_exception(42); } ); } catch(...) { BOOST_TEST_EQ(id, leaf::leaf_detail::current_id()); throw; } } ) ); } { leaf::try_catch( [] { leaf::throw_exception( info{42} ); }, []( info x ) { BOOST_TEST_EQ(x.value, 42); } ); int r = leaf::try_catch( []() -> int { throw std::exception(); }, []( info ) { return -1; }, [] { return 1; } ); BOOST_TEST_EQ(r, 1); } return boost::report_errors(); } #endif