Fix an issue when connecting void continuables

This commit is contained in:
Denis Blank 2018-02-27 17:18:52 +01:00
parent 663779f083
commit a1ee771059
4 changed files with 49 additions and 15 deletions

View File

@ -800,15 +800,15 @@ constexpr auto make_ready_continuable(FirstResult&& first_result,
/// Returns a continuable with the parameterized result which instantly
/// resolves the promise with the given error type.
///
/// \tparam FirstArg The first result of the fake signature of the
/// returned continuable.
/// \tparam Rest The rest of the result of the fake signature of the
/// returned continuable.
/// \tparam Signature The fake signature of the returned continuable.
///
/// \since 3.0.0
template <typename Exception, typename FirstArg = void, typename... Rest>
/// \since 3.0.0
template <typename... Signature, typename Exception>
constexpr auto make_exceptional_continuable(Exception&& exception) {
return make_continuable<FirstArg, Rest...>( // ...
static_assert(sizeof...(Signature) > 0,
"Requires at least one type for the fake signature!");
return make_continuable<Signature...>( // ...
[exception = std::forward<Exception>(exception)](auto&& promise) mutable {
std::forward<decltype(promise)>(promise).set_exception(
std::move(exception));

View File

@ -77,10 +77,10 @@ auto when_all(Continuables&&... continuables) {
/// std::vector<cti::continuable<int>>{cti::make_ready_continuable(3),
/// cti::make_ready_continuable(4)},
/// std::make_tuple(std::make_tuple(cti::make_ready_continuable(5))))
/// .then([](int r0, int r1, int r2, std::vector<int> r34,
/// std::tuple<std::tuple<int>> r5) {
/// // ...
/// });
/// .then([](int r0, int r1, int r2, std::vector<int> r34,
/// std::tuple<std::tuple<int>> r5) {
/// // ...
/// });
/// ```
///
/// \see continuable_base::operator>> for details.

View File

@ -182,18 +182,33 @@ public:
// Continue the asynchronous sequential traversal
next();
})
.fail([me = this->shared_from_this()](types::error_type exception) {
// Abort the traversal when an error occurred
std::move(me->data_.callback)(types::dispatch_error_tag{},
std::move(exception));
})
.done();
}
void finalize(traits::identity<void>) {
std::move(data_.callback)();
}
template <typename T>
void operator()(async_traverse_complete_tag, T&& /*pack*/) {
// Remove void result guard tags
void finalize(traits::identity<T>) {
auto cleaned =
map_pack(remapping::unpack_result_guards{}, std::move(data_.result));
// Call the final callback with the cleaned result
traits::unpack(std::move(cleaned), std::move(data_.callback));
}
template <typename T>
void operator()(async_traverse_complete_tag, T&& /*pack*/) {
// Guard the final result against void
using result_t = decltype(
map_pack(remapping::unpack_result_guards{}, std::move(data_.result)));
finalize(traits::identity<result_t>{});
}
};
} // namespace seq

View File

@ -143,11 +143,30 @@ int main(int, char**) {
util::unused(o2);
});
cti::when_seq()
cti::when_seq(cti::make_ready_continuable()) // ...
.then([] {
// ...
})
});
cti::when_seq() // ...
.then([] {
// ...
});
cti::when_seq(cti::make_exceptional_continuable<void>(std::error_condition{}))
.fail([](auto) {
// ...
});
/*composition::apply_composition(
composition::composition_strategy_all_tag{},
cti::make_ready_continuable(0, 1), 2, //< See this plain value
std::vector<cti::continuable<int>>{cti::make_ready_continuable(3),
cti::make_ready_continuable(4)},
std::make_tuple(std::make_tuple(cti::make_ready_continuable(5))))
.then([](int r0, int r1, int r2, std::vector<int> r34,
std::tuple<std::tuple<int>> r5) {
// ...
util::unused(r0, r1, r2, r34, r5);
});*/
}