mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Implement continuable_base<...>::as
* Can convert continuables to other compatible signatures
This commit is contained in:
parent
30f0dca27f
commit
7a10363dce
@ -404,6 +404,24 @@ public:
|
||||
std::forward<E>(executor));
|
||||
}
|
||||
|
||||
/// Returns a continuable_base which will have its signature converted
|
||||
/// to the given Args.
|
||||
///
|
||||
/// A signature can only be converted if it can be partially applied
|
||||
/// from the previous one as shown below:
|
||||
/// ```cpp
|
||||
/// continuable<long> c = make_ready_continuable(0, 1, 2).as<long>();
|
||||
/// ```
|
||||
///
|
||||
/// \returns Returns a continuable_base with an asynchronous return type
|
||||
/// matching the given Args.
|
||||
///
|
||||
/// \since 4.0.0
|
||||
template <typename... Args>
|
||||
auto as() && {
|
||||
return std::move(*this).then(detail::base::convert_to<Args...>{});
|
||||
}
|
||||
|
||||
/// A method which allows to apply this continuable to the given callable.
|
||||
///
|
||||
/// \param transform A transform which shall accept this continuable
|
||||
|
||||
@ -473,8 +473,10 @@ void on_executor(Executor&& executor, Invoker&& invoker, Args&&... args) {
|
||||
|
||||
// Create a worker object which when invoked calls the callback with the
|
||||
// the returned arguments.
|
||||
auto work = [invoker = std::forward<Invoker>(invoker),
|
||||
args = std::make_tuple(std::forward<Args>(args)...)]() mutable {
|
||||
auto work = [
|
||||
invoker = std::forward<Invoker>(invoker),
|
||||
args = std::make_tuple(std::forward<Args>(args)...)
|
||||
]() mutable {
|
||||
traits::unpack(
|
||||
[&](auto&&... captured_args) {
|
||||
// Just use the packed dispatch method which dispatches the work on
|
||||
@ -915,6 +917,25 @@ auto wrap_continuation(Continuation&& continuation) {
|
||||
return supplier_callback<std::decay_t<Continuation>>(
|
||||
std::forward<Continuation>(continuation));
|
||||
}
|
||||
|
||||
/// Callback which converts its input to the given set of arguments
|
||||
template <typename... Args>
|
||||
struct convert_to {
|
||||
std::tuple<Args...> operator()(Args... args) {
|
||||
return std::make_tuple(std::move(args)...);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct convert_to<T> {
|
||||
T operator()(T arg) noexcept {
|
||||
return std::move(arg);
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct convert_to<> {
|
||||
void operator()() noexcept {
|
||||
}
|
||||
};
|
||||
} // namespace base
|
||||
} // namespace detail
|
||||
} // namespace cti
|
||||
|
||||
@ -60,3 +60,27 @@ TYPED_TEST(single_dimension_tests, are_continuing_chainable) {
|
||||
|
||||
ASSERT_ASYNC_TYPES(std::move(chain), tag1);
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_converted_chainable_0) {
|
||||
auto chain =
|
||||
this->supply().then([&] { return this->supply(tag1{}).template as<>(); });
|
||||
|
||||
ASSERT_ASYNC_COMPLETION(std::move(chain).then([](auto&&... args) {
|
||||
ASSERT_EQ(sizeof...(args), 0U); //
|
||||
}));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_converted_chainable_1) {
|
||||
auto chain = this->supply().then(
|
||||
[&] { return this->supply(float(0)).template as<double>(); });
|
||||
|
||||
ASSERT_ASYNC_TYPES(std::move(chain), double);
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_converted_chainable_2) {
|
||||
auto chain = this->supply().then([&] {
|
||||
return this->supply(int(0), float(0)).template as<long, double>();
|
||||
});
|
||||
|
||||
ASSERT_ASYNC_TYPES(std::move(chain), long, double);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user