From b88ecf904058820f86feffe7086fe3bf7ba92068 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Tue, 8 Dec 2020 18:28:00 -0800 Subject: [PATCH] Fixing Issue # 18 --- include/boost/leaf.hpp | 4 +- include/boost/leaf/handle_errors.hpp | 4 +- test/handle_all_test.cpp | 203 +++++++++++++++++++++++++++ 3 files changed, 207 insertions(+), 4 deletions(-) diff --git a/include/boost/leaf.hpp b/include/boost/leaf.hpp index b56aa08..4f28e58 100644 --- a/include/boost/leaf.hpp +++ b/include/boost/leaf.hpp @@ -3790,7 +3790,7 @@ namespace boost { namespace leaf { context_type_from_handlers ctx; auto active_context = activate_context(ctx); if( auto r = std::forward(try_block)() ) - return r.value(); + return std::move(r).value(); else { error_id id = r.error(); @@ -3896,7 +3896,7 @@ namespace boost { namespace leaf { return std::forward(try_block)(); }, std::forward(h)...) ) - return r.value(); + return std::move(r).value(); else { error_id id = r.error(); diff --git a/include/boost/leaf/handle_errors.hpp b/include/boost/leaf/handle_errors.hpp index 4c2bb3f..249076d 100644 --- a/include/boost/leaf/handle_errors.hpp +++ b/include/boost/leaf/handle_errors.hpp @@ -676,7 +676,7 @@ namespace boost { namespace leaf { context_type_from_handlers ctx; auto active_context = activate_context(ctx); if( auto r = std::forward(try_block)() ) - return r.value(); + return std::move(r).value(); else { error_id id = r.error(); @@ -782,7 +782,7 @@ namespace boost { namespace leaf { return std::forward(try_block)(); }, std::forward(h)...) ) - return r.value(); + return std::move(r).value(); else { error_id id = r.error(); diff --git a/test/handle_all_test.cpp b/test/handle_all_test.cpp index 885801e..ec00ff4 100644 --- a/test/handle_all_test.cpp +++ b/test/handle_all_test.cpp @@ -46,6 +46,14 @@ leaf::result f_errc_wrapped( Errc ec ) return leaf::new_error(e_std_error_code{make_error_code(ec)}, info<1>{1}, info<2>{2}, info<3>{3}); } +struct move_only +{ + move_only( move_only const & ) = delete; + move_only( move_only && ) = default; + move_only( int value ): value(value) { } + int value; +}; + int main() { // void, try_handle_all (success) @@ -473,5 +481,200 @@ int main() BOOST_TEST_EQ(r, 2); } + ////////////////////////////////////// + + // move_only, try_handle_all (success) + { + move_only r = leaf::try_handle_all( + []() -> leaf::result + { + BOOST_LEAF_AUTO(answer, f(my_error_code::ok)); + return answer; + }, + [] + { + return 1; + } ); + BOOST_TEST_EQ(r.value, 42); + } + + // move_only, try_handle_all (failure) + { + move_only r = leaf::try_handle_all( + []() -> leaf::result + { + BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); + return answer; + }, + []( my_error_code ec, info<1> const & x, info<2> y ) + { + BOOST_TEST(ec==my_error_code::error1); + BOOST_TEST_EQ(x.value, 1); + BOOST_TEST_EQ(y.value, 2); + return 1; + }, + [] + { + return 2; + } ); + BOOST_TEST_EQ(r.value, 1); + } + + // move_only, try_handle_all (failure), match cond_x (single enum value) + { + move_only r = leaf::try_handle_all( + []() -> leaf::result + { + BOOST_LEAF_AUTO(answer, f_errc(errc_a::a0)); + return answer; + }, + []( leaf::match, cond_x::x11> ) + { + return 1; + }, + []( leaf::match, cond_x::x00> ec, info<1> const & x, info<2> y ) + { + BOOST_TEST_EQ(ec.matched, make_error_code(errc_a::a0)); + BOOST_TEST_EQ(x.value, 1); + BOOST_TEST_EQ(y.value, 2); + return 2; + }, + [] + { + return 3; + } ); + BOOST_TEST_EQ(r.value, 2); + } + + // move_only, try_handle_all (failure), match cond_x (wrapped std::error_code) + { + move_only r = leaf::try_handle_all( + []() -> leaf::result + { + BOOST_LEAF_AUTO(answer, f_errc_wrapped(errc_a::a0)); + return answer; + }, + []( leaf::match, cond_x::x11> ) + { + return 1; + }, + []( leaf::match_value, cond_x::x00> ec, info<1> const & x, info<2> y ) + { + BOOST_TEST_EQ(ec.matched.value, make_error_code(errc_a::a0)); + BOOST_TEST_EQ(x.value, 1); + BOOST_TEST_EQ(y.value, 2); + return 2; + }, + [] + { + return 3; + } ); + BOOST_TEST_EQ(r.value, 2); + } + + // move_only, try_handle_all (failure), match enum (single enum value) + { + move_only r = leaf::try_handle_all( + []() -> leaf::result + { + BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); + return answer; + }, + []( leaf::match ) + { + return 1; + }, + []( leaf::match ec, info<1> const & x, info<2> y ) + { + BOOST_TEST(ec.matched==my_error_code::error1); + BOOST_TEST_EQ(x.value, 1); + BOOST_TEST_EQ(y.value, 2); + return 2; + }, + [] + { + return 3; + } ); + BOOST_TEST_EQ(r.value, 2); + } + + // move_only, try_handle_all (failure), match enum (multiple enum values) + { + move_only r = leaf::try_handle_all( + []() -> leaf::result + { + BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); + return answer; + }, + []( leaf::match ) + { + return 1; + }, + []( leaf::match ec, info<1> const & x, info<2> y ) + { + BOOST_TEST(ec.matched==my_error_code::error1); + BOOST_TEST_EQ(x.value, 1); + BOOST_TEST_EQ(y.value, 2); + return 2; + }, + [] + { + return 3; + } ); + BOOST_TEST_EQ(r.value, 2); + } + + // move_only, try_handle_all (failure), match value (single value) + { + move_only r = leaf::try_handle_all( + []() -> leaf::result + { + BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); + return answer; + }, + []( leaf::match_value ) + { + return 1; + }, + []( leaf::match_value ec, info<1> const & x, info<2> y ) + { + BOOST_TEST(ec.matched.value==my_error_code::error1); + BOOST_TEST_EQ(x.value, 1); + BOOST_TEST_EQ(y.value, 2); + return 2; + }, + [] + { + return 3; + } ); + BOOST_TEST_EQ(r.value, 2); + } + + // move_only, try_handle_all (failure), match value (multiple values) + { + move_only r = leaf::try_handle_all( + []() -> leaf::result + { + BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); + return answer; + }, + []( leaf::match_value ) + { + return 1; + }, + []( leaf::match_value ec, info<1> const & x, info<2> y ) + { + BOOST_TEST(ec.matched.value==my_error_code::error1); + BOOST_TEST_EQ(x.value, 1); + BOOST_TEST_EQ(y.value, 2); + return 2; + }, + [] + { + return 3; + } ); + BOOST_TEST_EQ(r.value, 2); + } + return boost::report_errors(); }