diff --git a/include/continuable/continuable-base.hpp b/include/continuable/continuable-base.hpp index ba318b8..6a7f906 100644 --- a/include/continuable/continuable-base.hpp +++ b/include/continuable/continuable-base.hpp @@ -434,6 +434,21 @@ public: std::forward(executor)); } + /// Returns a continuable_base which continues its invocation through the + /// given executor. + /// + /// \returns Returns a continuable_base of the same type. + /// + /// \since 4.2.0 + template + auto via(E&& executor) && { + return std::move(*this).next( + [](auto&&... args) { + return make_result(std::forward(args)...); + }, + std::forward(executor)); + } + /// Returns a continuable_base which will have its signature converted /// to the given Args. /// diff --git a/test/unit-test/multi/test-continuable-base-executors.cpp b/test/unit-test/multi/test-continuable-base-executors.cpp index 446edf7..ed9e286 100644 --- a/test/unit-test/multi/test-continuable-base-executors.cpp +++ b/test/unit-test/multi/test-continuable-base-executors.cpp @@ -47,6 +47,26 @@ TYPED_TEST(single_dimension_tests, are_executor_dispatchable) { ASSERT_ASYNC_COMPLETION(std::move(chain)); } +TYPED_TEST(single_dimension_tests, are_executor_dispatchable_via) { + bool invoked = false; + auto executor = [&](auto&& work) { + // We can move the worker object + auto local = std::forward(work); + ASSERT_FALSE(invoked); + // We can invoke the worker object + std::move(local)(); + }; + + auto chain = this->supply().via(executor).then([&] { + ASSERT_FALSE(invoked); + invoked = true; + }); + + ASSERT_ASYNC_COMPLETION(std::move(chain)); + + ASSERT_TRUE(invoked); +} + TYPED_TEST(single_dimension_tests, are_executor_exception_resolveable) { auto executor = [&](auto&& work) { std::forward(work).set_exception(supply_test_exception());