Qualify continuable callbacks as r-value callable

This commit is contained in:
Denis Blank 2017-10-04 17:16:58 +02:00
parent 5c3ae8223a
commit 84ca172caa
5 changed files with 31 additions and 27 deletions

View File

@ -72,29 +72,29 @@ public:
/// Resolves the continuation with the given values /// Resolves the continuation with the given values
/// ///
/// \since version 2.0.0 /// \since version 2.0.0
void operator()(Args... args) { void operator()(Args... args) && {
data_(std::move(args)...); std::move(data_)(std::move(args)...);
} }
/// Resolves the continuation with the given exception /// Resolves the continuation with the given exception
/// ///
/// \since version 2.0.0 /// \since version 2.0.0
void operator()(detail::types::dispatch_error_tag tag, void operator()(detail::types::dispatch_error_tag tag,
detail::types::error_type exception) { detail::types::error_type exception) && {
data_(tag, std::move(exception)); std::move(data_)(tag, std::move(exception));
} }
/// Resolves the continuation with the given values /// Resolves the continuation with the given values
/// ///
/// \since version 2.0.0 /// \since version 2.0.0
void set_value(Args... args) { void set_value(Args... args) {
data_(std::move(args)...); std::move(data_)(std::move(args)...);
} }
/// Resolves the continuation with the given exception /// Resolves the continuation with the given exception
/// ///
/// \since version 2.0.0 /// \since version 2.0.0
void set_exception(detail::types::error_type exception) { void set_exception(detail::types::error_type exception) {
data_(detail::types::dispatch_error_tag{}, std::move(exception)); std::move(data_)(detail::types::dispatch_error_tag{}, std::move(exception));
} }
}; };
} // namespace cti } // namespace cti

View File

@ -54,8 +54,8 @@ template <template <typename...> class CallbackWrapper,
struct continuable_trait { struct continuable_trait {
/// The promise type which is used to resolve continuations /// The promise type which is used to resolve continuations
using promise = promise_base< using promise = promise_base<
CallbackWrapper<void(Args...), void(detail::types::dispatch_error_tag, CallbackWrapper<void(Args...)&&, void(detail::types::dispatch_error_tag,
detail::types::error_type)>, detail::types::error_type) &&>,
detail::hints::signature_hint_tag<Args...>>; detail::hints::signature_hint_tag<Args...>>;
/// The continuable type for the given parameters. /// The continuable type for the given parameters.

View File

@ -234,10 +234,14 @@ inline auto sequenced_unpack_invoker() {
util::partial_invoke(std::forward<decltype(callback)>(callback), util::partial_invoke(std::forward<decltype(callback)>(callback),
std::forward<decltype(args)>(args)...); std::forward<decltype(args)>(args)...);
// Workaround for MSVC not capturing the reference correctly inside
// the lambda.
using Next = decltype(next_callback);
traits::unpack(std::move(result), [&](auto&&... types) { traits::unpack(std::move(result), [&](auto&&... types) {
/// TODO Add inplace resolution here /// TODO Add inplace resolution here
std::forward<decltype(next_callback)>(next_callback)( std::forward<Next>(next_callback)(
std::forward<decltype(types)>(types)...); std::forward<decltype(types)>(types)...);
}); });
CONTINUABLE_BLOCK_TRY_END CONTINUABLE_BLOCK_TRY_END
@ -312,7 +316,7 @@ struct result_handler_base;
template <typename Base, typename... Args> template <typename Base, typename... Args>
struct result_handler_base<handle_results::no, Base, struct result_handler_base<handle_results::no, Base,
hints::signature_hint_tag<Args...>> { hints::signature_hint_tag<Args...>> {
void operator()(Args... args) { void operator()(Args... args) && {
// Forward the arguments to the next callback // Forward the arguments to the next callback
std::move(static_cast<Base*>(this)->next_callback_)(std::move(args)...); std::move(static_cast<Base*>(this)->next_callback_)(std::move(args)...);
} }
@ -321,7 +325,7 @@ template <typename Base, typename... Args>
struct result_handler_base<handle_results::yes, Base, struct result_handler_base<handle_results::yes, Base,
hints::signature_hint_tag<Args...>> { hints::signature_hint_tag<Args...>> {
/// The operator which is called when the result was provided /// The operator which is called when the result was provided
void operator()(Args... args) { void operator()(Args... args) && {
// In order to retrieve the correct decorator we must know what the // In order to retrieve the correct decorator we must know what the
// result type is. // result type is.
auto result = traits::identity_of<decltype(util::partial_invoke( auto result = traits::identity_of<decltype(util::partial_invoke(
@ -356,7 +360,7 @@ inline auto make_error_invoker(
template <handle_errors HandleErrors /* = plain or forward*/, typename Base> template <handle_errors HandleErrors /* = plain or forward*/, typename Base>
struct error_handler_base { struct error_handler_base {
void operator()(types::dispatch_error_tag, types::error_type error) { void operator()(types::dispatch_error_tag, types::error_type error) && {
// Just invoke the error handler, cancel the calling hierarchy after // Just invoke the error handler, cancel the calling hierarchy after
auto invoker = make_error_invoker( auto invoker = make_error_invoker(
std::integral_constant<handle_errors, HandleErrors>{}); std::integral_constant<handle_errors, HandleErrors>{});
@ -370,7 +374,7 @@ struct error_handler_base {
template <typename Base> template <typename Base>
struct error_handler_base<handle_errors::no, Base> { struct error_handler_base<handle_errors::no, Base> {
/// The operator which is called when an error occurred /// The operator which is called when an error occurred
void operator()(types::dispatch_error_tag tag, types::error_type error) { void operator()(types::dispatch_error_tag tag, types::error_type error) && {
// Forward the error to the next callback // Forward the error to the next callback
std::move(static_cast<Base*>(this)->next_callback_)(tag, std::move(error)); std::move(static_cast<Base*>(this)->next_callback_)(tag, std::move(error));
} }
@ -425,12 +429,12 @@ struct callback_base<hints::signature_hint_tag<Args...>, HandleResults,
/// Resolves the continuation with the given values /// Resolves the continuation with the given values
void set_value(Args... args) { void set_value(Args... args) {
(*this)(std::move(args)...); std::move (*this)(std::move(args)...);
} }
/// Resolves the continuation with the given error variable. /// Resolves the continuation with the given error variable.
void set_exception(types::error_type error) { void set_exception(types::error_type error) {
(*this)(types::dispatch_error_tag{}, std::move(error)); std::move (*this)(types::dispatch_error_tag{}, std::move(error));
} }
}; };
@ -450,7 +454,7 @@ auto make_callback(Callback&& callback, Executor&& executor,
/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095 /// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095
struct final_callback { struct final_callback {
template <typename... Args> template <typename... Args>
void operator()(Args... /*args*/) { void operator()(Args... /*args*/) && {
} }
template <typename... Args> template <typename... Args>

View File

@ -181,18 +181,18 @@ class all_result_submitter : public std::enable_shared_from_this<
std::shared_ptr<all_result_submitter> me_; std::shared_ptr<all_result_submitter> me_;
template <typename... PartialArgs> template <typename... PartialArgs>
void operator()(PartialArgs&&... args) { void operator()(PartialArgs&&... args) && {
me_->resolve(traits::size_constant<From>{}, traits::size_constant<To>{}, me_->resolve(traits::size_constant<From>{}, traits::size_constant<To>{},
std::forward<PartialArgs>(args)...); std::forward<PartialArgs>(args)...);
} }
template <typename... PartialArgs> template <typename... PartialArgs>
void set_value(PartialArgs&&... args) { void set_value(PartialArgs&&... args) {
(*this)(std::forward<PartialArgs>(args)...); std::move (*this)(std::forward<PartialArgs>(args)...);
} }
void set_exception(types::error_type error) { void set_exception(types::error_type error) {
(*this)(types::dispatch_error_tag{}, std::move(error)); std::move (*this)(types::dispatch_error_tag{}, std::move(error));
} }
}; };
@ -222,17 +222,17 @@ class any_result_submitter
std::shared_ptr<any_result_submitter> me_; std::shared_ptr<any_result_submitter> me_;
template <typename... PartialArgs> template <typename... PartialArgs>
void operator()(PartialArgs&&... args) { void operator()(PartialArgs&&... args) && {
me_->invoke(std::forward<decltype(args)>(args)...); me_->invoke(std::forward<decltype(args)>(args)...);
} }
template <typename... PartialArgs> template <typename... PartialArgs>
void set_value(PartialArgs&&... args) { void set_value(PartialArgs&&... args) {
(*this)(std::forward<PartialArgs>(args)...); std::move (*this)(std::forward<PartialArgs>(args)...);
} }
void set_exception(types::error_type error) { void set_exception(types::error_type error) {
(*this)(types::dispatch_error_tag{}, std::move(error)); std::move (*this)(types::dispatch_error_tag{}, std::move(error));
} }
}; };

View File

@ -29,7 +29,7 @@ static cti::continuable<std::string> http_request(std::string url) {
return [url = std::move(url)](cti::promise<std::string> promise) { return [url = std::move(url)](cti::promise<std::string> promise) {
if (false) { if (false) {
promise.set_value(""); promise.set_value("");
promise(""); std::forward<decltype(promise)>(promise)("");
} }
promise.set_exception(std::error_condition{}); promise.set_exception(std::error_condition{});
}; };
@ -41,7 +41,7 @@ static auto http_request2(std::string url) {
[url = std::move(url)](auto&& promise) { [url = std::move(url)](auto&& promise) {
if (false) { if (false) {
promise.set_value(""); promise.set_value("");
promise(""); std::forward<decltype(promise)>(promise)("");
} }
promise.set_exception(std::error_condition{}); promise.set_exception(std::error_condition{});
}); });
@ -51,17 +51,17 @@ static cti::continuable<std::string> http_request3(std::string url) {
return [url = std::move(url)](auto&& promise) { return [url = std::move(url)](auto&& promise) {
if (false) { if (false) {
promise.set_value(""); promise.set_value("");
promise(""); std::forward<decltype(promise)>(promise)("");
} }
promise.set_exception(std::error_condition{}); promise.set_exception(std::error_condition{});
}; };
} }
struct my_callable { struct my_callable {
void operator()(std::string) { void operator()(std::string) && {
// ... // ...
} }
void operator()(cti::dispatch_error_tag, cti::error_type) { void operator()(cti::dispatch_error_tag, cti::error_type) && {
// ... // ...
} }
}; };