// Copyright (c) 2018-2020 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 #include #include #include #include "lightweight_test.hpp" namespace leaf = boost::leaf; template struct info { int value; }; struct my_exception: std::exception { int value; my_exception(): value(0) { } my_exception(int v): value(v) { } }; int main() { { leaf::result r = leaf::try_handle_some( []() -> leaf::result { return 42; }, [] { return 1; } ); BOOST_TEST(r); BOOST_TEST_EQ(r.value(), 42); } { leaf::result r = leaf::try_handle_some( []() -> leaf::result { throw leaf::exception( my_exception(), info<1>{1} ); }, []( my_exception const &, info<1> const & x ) { BOOST_TEST_EQ(x.value, 1); return 42; } ); BOOST_TEST(r); BOOST_TEST_EQ(r.value(), 42); } { leaf::result r = leaf::try_handle_some( []() -> leaf::result { return leaf::new_error( info<1>{1} ); }, []( info<1> const & x ) { BOOST_TEST_EQ(x.value, 1); return -42; } ); BOOST_TEST(r); BOOST_TEST_EQ(r.value(), -42); } { auto error_handlers = std::make_tuple( []( my_exception const &, info<1> const & x ) -> leaf::result { BOOST_TEST_EQ(x.value, 1); return 42; }, []( info<1> const & x ) -> leaf::result { BOOST_TEST_EQ(x.value, 1); return -42; } ); { leaf::result r = leaf::try_handle_some( []() -> leaf::result { return 42; }, error_handlers ); BOOST_TEST(r); BOOST_TEST_EQ(r.value(), 42); } { leaf::result r = leaf::try_handle_some( []() -> leaf::result { throw leaf::exception( my_exception(), info<1>{1} ); }, error_handlers ); BOOST_TEST(r); BOOST_TEST_EQ(r.value(), 42); } { leaf::result r = leaf::try_handle_some( []() -> leaf::result { return leaf::new_error( info<1>{1} ); }, error_handlers ); BOOST_TEST(r); BOOST_TEST_EQ(r.value(), -42); } } { int r = leaf::try_handle_all( []() -> leaf::result { return 42; }, [] { return 1; } ); BOOST_TEST_EQ(r, 42); } { int r = leaf::try_handle_all( []() -> leaf::result { throw leaf::exception( my_exception(), info<1>{1} ); }, []( my_exception const &, info<1> const & x ) { BOOST_TEST_EQ(x.value, 1); return 42; }, [] { return 1; } ); BOOST_TEST_EQ(r, 42); } { int r = leaf::try_handle_all( []() -> leaf::result { return leaf::new_error( info<1>{1} ); }, []( info<1> const & x ) { BOOST_TEST_EQ(x.value, 1); return 42; }, [] { return 1; } ); BOOST_TEST_EQ(r, 42); } { auto error_handlers = std::make_tuple( []( my_exception const &, info<1> const & x ) { BOOST_TEST_EQ(x.value, 1); return 42; }, []( info<1> const & x ) { BOOST_TEST_EQ(x.value, 1); return -42; }, [] { return 1; } ); { int r = leaf::try_handle_all( []() -> leaf::result { return 42; }, error_handlers ); BOOST_TEST_EQ(r, 42); } { int r = leaf::try_handle_all( []() -> leaf::result { throw leaf::exception( my_exception(), info<1>{1} ); }, error_handlers ); BOOST_TEST_EQ(r, 42); } { int r = leaf::try_handle_all( []() -> leaf::result { return leaf::new_error( info<1>{1} ); }, error_handlers ); BOOST_TEST_EQ(r, -42); } } { int r = leaf::try_handle_all( []() -> leaf::result { return leaf::try_handle_all( []() -> leaf::result { return leaf::new_error( info<1>{1} ); }, []( info<1> const & ) -> int { BOOST_LEAF_THROW_EXCEPTION(my_exception()); }, []( leaf::catch_<> ) { return 1; }, [] { return 2; } ); }, []( leaf::catch_<> ) { return 3; }, [] { return 4; } ); BOOST_TEST_EQ(r, 3); } { auto error_handlers = std::make_tuple( []( info<1> const & ) -> int { BOOST_LEAF_THROW_EXCEPTION(my_exception()); }, []( leaf::catch_<> ) { return 1; }, [] { return 2; } ); int r = leaf::try_handle_all( [&]() -> leaf::result { return leaf::try_handle_all( [&]() -> leaf::result { return leaf::new_error( info<1>{1} ); }, error_handlers ); }, []( leaf::catch_<> ) { return 3; }, [] { return 4; } ); BOOST_TEST_EQ(r, 3); } { int r = leaf::try_handle_all( []() -> leaf::result { return leaf::try_handle_some( []() -> leaf::result { return leaf::new_error( info<1>{1} ); }, []( info<1> const & ) -> int { BOOST_LEAF_THROW_EXCEPTION(my_exception()); }, []( leaf::catch_<> ) { return 1; } ); }, []( leaf::catch_<> ) { return 3; }, [] { return 4; } ); BOOST_TEST_EQ(r, 3); } { auto error_handlers = std::make_tuple( []( info<1> const & ) -> leaf::result { BOOST_LEAF_THROW_EXCEPTION(my_exception()); }, []( leaf::catch_<> ) -> leaf::result { return 1; } ); int r = leaf::try_handle_all( [&]() -> leaf::result { return leaf::try_handle_some( [&]() -> leaf::result { return leaf::new_error( info<1>{1} ); }, error_handlers ); }, []( leaf::catch_<> ) { return 3; }, [] { return 4; } ); BOOST_TEST_EQ(r, 3); } ////////////////////////////////////// // match_value<> with exceptions, try_handle_some { leaf::result r = leaf::try_handle_some( []() -> leaf::result { throw leaf::exception( my_exception(42) ); }, []( leaf::match_value m ) { return m.matched.value; } ); BOOST_TEST(r); BOOST_TEST_EQ(r.value(), 42); } { leaf::result r = leaf::try_handle_some( []() -> leaf::result { throw my_exception(42); }, []( leaf::match_value m ) { return m.matched.value; } ); BOOST_TEST(r); BOOST_TEST_EQ(r.value(), 42); } { leaf::result r = leaf::try_handle_some( []() -> leaf::result { throw leaf::exception( my_exception(42) ); }, []( leaf::match_value m ) { return m.matched.value; }, []( leaf::error_info const & unmatched ) { return unmatched.error(); } ); BOOST_TEST(!r); } { leaf::result r = leaf::try_handle_some( []() -> leaf::result { throw my_exception(42); }, []( leaf::match_value m ) { return m.matched.value; }, []( leaf::error_info const & unmatched ) { return unmatched.error(); } ); BOOST_TEST(!r); } // match_value<> with exceptions, try_handle_all { int r = leaf::try_handle_all( []() -> leaf::result { throw leaf::exception( my_exception(42) ); }, []( leaf::match_value m ) { return m.matched.value; }, [] { return -1; } ); BOOST_TEST_EQ(r, 42); } { int r = leaf::try_handle_all( []() -> leaf::result { throw my_exception(42); }, []( leaf::match_value m ) { return m.matched.value; }, [] { return -1; } ); BOOST_TEST_EQ(r, 42); } { int r = leaf::try_handle_all( []() -> leaf::result { throw leaf::exception( my_exception(42) ); }, []( leaf::match_value m ) { return m.matched.value; }, [] { return -1; } ); BOOST_TEST_EQ(r, -1); } { int r = leaf::try_handle_all( []() -> leaf::result { throw my_exception(42); }, []( leaf::match_value m ) { return m.matched.value; }, [] { return -1; } ); BOOST_TEST_EQ(r, -1); } return boost::report_errors(); } #endif