diff --git a/include/continuable/continuable-result.hpp b/include/continuable/continuable-result.hpp index 33c0387..330ab53 100644 --- a/include/continuable/continuable-result.hpp +++ b/include/continuable/continuable-result.hpp @@ -277,7 +277,18 @@ decltype(auto) get(result&& result) { return detail::result_trait::template get(std::move(result)); } -/// Creates a present result from the given values +/// Creates a present result from the given values. +/// +/// This could be used to pass the result of the next handler to the same +/// asynchronous path it came from as shown below: +/// ```cpp +/// make_ready_continuable().next([&](auto&&... args) { +/// result<> captured = make_result(std::forward(args)...); +/// return shutdown().then([captured = std::move(captured)]() mutable { +/// return std::move(captured); +/// }); +/// }); +/// ``` /// /// \since 4.0.0 template (values)...); } + +/// Creates an exceptional_result from the given exception. +/// +/// \copydetails make_result +/// +/// \since 4.0.0 +inline exceptional_result make_result(exception_arg_t, exception_t exception) { + // NOLINTNEXTLINE(hicpp-move-const-arg, performance-move-const-arg) + return exceptional_result{std::move(exception)}; +} /// \} } // namespace cti diff --git a/test/unit-test/single/test-continuable-result.cpp b/test/unit-test/single/test-continuable-result.cpp index c53d320..a9752bb 100644 --- a/test/unit-test/single/test-continuable-result.cpp +++ b/test/unit-test/single/test-continuable-result.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -253,6 +254,26 @@ TYPED_TEST(result_all_tests, is_assignable_from_empty_helper) { EXPECT_TRUE(e.is_empty()); } +TYPED_TEST(result_all_tests, can_make_from_multipath_args) { + { + TypeParam e = make_result(this->supply(CANARY)); + + EXPECT_TRUE(bool(e)); + EXPECT_EQ(this->get(*e), CANARY); + EXPECT_TRUE(e.is_value()); + EXPECT_FALSE(e.is_exception()); + } + + { + TypeParam e = make_result(cti::exception_arg_t{}, // + supply_test_exception()); + + EXPECT_FALSE(bool(e)); + EXPECT_FALSE(e.is_value()); + EXPECT_TRUE(e.is_empty()); + } +} + // This regression test shows a memory leak which happens when using the // result class move constructed from another result object. TEST(result_single_test, test_leak_regression) {