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));
|
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.
|
/// A method which allows to apply this continuable to the given callable.
|
||||||
///
|
///
|
||||||
/// \param transform A transform which shall accept this continuable
|
/// \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
|
// Create a worker object which when invoked calls the callback with the
|
||||||
// the returned arguments.
|
// the returned arguments.
|
||||||
auto work = [invoker = std::forward<Invoker>(invoker),
|
auto work = [
|
||||||
args = std::make_tuple(std::forward<Args>(args)...)]() mutable {
|
invoker = std::forward<Invoker>(invoker),
|
||||||
|
args = std::make_tuple(std::forward<Args>(args)...)
|
||||||
|
]() mutable {
|
||||||
traits::unpack(
|
traits::unpack(
|
||||||
[&](auto&&... captured_args) {
|
[&](auto&&... captured_args) {
|
||||||
// Just use the packed dispatch method which dispatches the work on
|
// 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>>(
|
return supplier_callback<std::decay_t<Continuation>>(
|
||||||
std::forward<Continuation>(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 base
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace cti
|
} // namespace cti
|
||||||
|
|||||||
@ -60,3 +60,27 @@ TYPED_TEST(single_dimension_tests, are_continuing_chainable) {
|
|||||||
|
|
||||||
ASSERT_ASYNC_TYPES(std::move(chain), tag1);
|
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