mirror of
https://github.com/Naios/continuable.git
synced 2026-02-16 23:29:48 +08:00
Started to implement combined path callables
This commit is contained in:
parent
7dcd18c964
commit
52cf1ab929
@ -65,6 +65,11 @@ public:
|
|||||||
void operator()(Args... args) {
|
void operator()(Args... args) {
|
||||||
data_(std::move(args)...);
|
data_(std::move(args)...);
|
||||||
}
|
}
|
||||||
|
/// Resolves the continuation with the given exception
|
||||||
|
void operator()(detail::types::dispatch_error_tag tag,
|
||||||
|
detail::types::error_type exception) {
|
||||||
|
data_(tag, std::move(exception));
|
||||||
|
}
|
||||||
|
|
||||||
/// Resolves the continuation with the given values
|
/// Resolves the continuation with the given values
|
||||||
void set_value(Args... args) {
|
void set_value(Args... args) {
|
||||||
|
|||||||
@ -259,6 +259,39 @@ void packed_dispatch(Executor&& executor, Invoker&& invoker, Args&&... args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace callbacks {
|
namespace callbacks {
|
||||||
|
template <typename Base>
|
||||||
|
struct error_handler_base {
|
||||||
|
void operator()(types::dispatch_error_tag, types::error_type error) {
|
||||||
|
// Just invoke the error handler, cancel the calling hierarchy after
|
||||||
|
auto invoker = [](typename Base::CallbackT&& callback,
|
||||||
|
types::error_type&& error) {
|
||||||
|
std::move(callback)(std::move(error));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoke the error handler
|
||||||
|
packed_dispatch(
|
||||||
|
std::move(static_cast<Base*>(this)->executor_), std::move(invoker),
|
||||||
|
std::move(static_cast<Base*>(this)->callback_), std::move(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Base, typename = void>
|
||||||
|
struct result_callback_error_base {
|
||||||
|
/// The operator which is called when an error occurred
|
||||||
|
void operator()(types::dispatch_error_tag tag, types::error_type error) {
|
||||||
|
// Forward the error to the next callback
|
||||||
|
std::move(static_cast<Base*>(this)->next_callback_)(tag, std::move(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename Base>
|
||||||
|
struct result_callback_error_base<
|
||||||
|
Base, std::enable_if_t<util::is_invokable<
|
||||||
|
typename Base::Callback,
|
||||||
|
std::tuple<types::dispatch_error_tag, types::error_type>>::value>>
|
||||||
|
: error_handler_base<Base> {
|
||||||
|
using error_handler_base<Base>::operator();
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Hint, typename Callback, typename Executor,
|
template <typename Hint, typename Callback, typename Executor,
|
||||||
typename NextCallback>
|
typename NextCallback>
|
||||||
struct result_callback;
|
struct result_callback;
|
||||||
@ -266,11 +299,23 @@ struct result_callback;
|
|||||||
template <typename... Args, typename Callback, typename Executor,
|
template <typename... Args, typename Callback, typename Executor,
|
||||||
typename NextCallback>
|
typename NextCallback>
|
||||||
struct result_callback<hints::signature_hint_tag<Args...>, Callback, Executor,
|
struct result_callback<hints::signature_hint_tag<Args...>, Callback, Executor,
|
||||||
NextCallback> {
|
NextCallback>
|
||||||
|
: result_callback_error_base<
|
||||||
|
result_callback<hints::signature_hint_tag<Args...>, Callback,
|
||||||
|
Executor, NextCallback>> {
|
||||||
|
|
||||||
|
using CallbackT = Callback;
|
||||||
|
|
||||||
Callback callback_;
|
Callback callback_;
|
||||||
Executor executor_;
|
Executor executor_;
|
||||||
NextCallback next_callback_;
|
NextCallback next_callback_;
|
||||||
|
|
||||||
|
explicit result_callback(Callback callback, Executor executor,
|
||||||
|
NextCallback next_callback)
|
||||||
|
: callback_(std::move(callback)), executor_(std::move(executor)),
|
||||||
|
next_callback_(std::move(next_callback)) {
|
||||||
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
@ -287,11 +332,7 @@ struct result_callback<hints::signature_hint_tag<Args...>, Callback, Executor,
|
|||||||
std::move(args)...);
|
std::move(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The operator which is called when an error occurred
|
using result_callback_error_base<result_callback>::operator();
|
||||||
void operator()(types::dispatch_error_tag tag, types::error_type error) {
|
|
||||||
// Forward the error to the next callback
|
|
||||||
std::move(next_callback_)(tag, std::move(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolves the continuation with the given values
|
/// Resolves the continuation with the given values
|
||||||
void set_value(Args... args) {
|
void set_value(Args... args) {
|
||||||
@ -311,29 +352,29 @@ struct error_callback;
|
|||||||
template <typename... Args, typename Callback, typename Executor,
|
template <typename... Args, typename Callback, typename Executor,
|
||||||
typename NextCallback>
|
typename NextCallback>
|
||||||
struct error_callback<hints::signature_hint_tag<Args...>, Callback, Executor,
|
struct error_callback<hints::signature_hint_tag<Args...>, Callback, Executor,
|
||||||
NextCallback> {
|
NextCallback>
|
||||||
|
: error_handler_base<error_callback<hints::signature_hint_tag<Args...>,
|
||||||
|
Callback, Executor, NextCallback>> {
|
||||||
|
|
||||||
|
using CallbackT = Callback;
|
||||||
|
|
||||||
Callback callback_;
|
Callback callback_;
|
||||||
Executor executor_;
|
Executor executor_;
|
||||||
NextCallback next_callback_;
|
NextCallback next_callback_;
|
||||||
|
|
||||||
|
explicit error_callback(Callback callback, Executor executor,
|
||||||
|
NextCallback next_callback)
|
||||||
|
: callback_(std::move(callback)), executor_(std::move(executor)),
|
||||||
|
next_callback_(std::move(next_callback)) {
|
||||||
|
}
|
||||||
|
|
||||||
/// 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) {
|
||||||
// Forward the arguments to the next callback
|
// Forward the arguments to the next callback
|
||||||
std::move(next_callback_)(std::move(args)...);
|
std::move(next_callback_)(std::move(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The operator which is called when an error occurred
|
using error_handler_base<error_callback>::operator();
|
||||||
void operator()(types::dispatch_error_tag /*tag*/, types::error_type error) {
|
|
||||||
|
|
||||||
// Just invoke the error handler, cancel the calling hierarchy after
|
|
||||||
auto invoker = [](Callback&& callback, types::error_type&& error) {
|
|
||||||
std::move(callback)(std::move(error));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Invoke the error handler
|
|
||||||
packed_dispatch(std::move(executor_), std::move(invoker),
|
|
||||||
std::move(callback_), std::move(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolves the continuation with the given values
|
/// Resolves the continuation with the given values
|
||||||
void set_value(Args... args) {
|
void set_value(Args... args) {
|
||||||
|
|||||||
@ -34,7 +34,9 @@
|
|||||||
#include <future>
|
#include <future>
|
||||||
|
|
||||||
#include <continuable/detail/api.hpp>
|
#include <continuable/detail/api.hpp>
|
||||||
|
#include <continuable/detail/features.hpp>
|
||||||
#include <continuable/detail/hints.hpp>
|
#include <continuable/detail/hints.hpp>
|
||||||
|
#include <continuable/detail/types.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@ -90,6 +92,14 @@ public:
|
|||||||
void operator()(Args... args) {
|
void operator()(Args... args) {
|
||||||
this->resolve(promise_, std::move(args)...);
|
this->resolve(promise_, std::move(args)...);
|
||||||
}
|
}
|
||||||
|
#if !defined(CONTINUABLE_WITH_CUSTOM_ERROR_TYPE) && \
|
||||||
|
!defined(CONTINUABLE_WITH_NO_EXCEPTIONS)
|
||||||
|
/// Resolves the promise through the exception
|
||||||
|
void operator()(types::dispatch_error_tag, types::error_type error) {
|
||||||
|
promise_.set_exception(error);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Returns the future from the promise
|
/// Returns the future from the promise
|
||||||
auto get_future() {
|
auto get_future() {
|
||||||
return promise_.get_future();
|
return promise_.get_future();
|
||||||
|
|||||||
@ -73,10 +73,10 @@ struct is_invokable_impl<
|
|||||||
/// arguments inside lambda closures.
|
/// arguments inside lambda closures.
|
||||||
///
|
///
|
||||||
/// ```cpp
|
/// ```cpp
|
||||||
/// traits::is_invokable_t<object, std::tuple<Args...>>
|
/// traits::is_invokable<object, std::tuple<Args...>>
|
||||||
/// ```
|
/// ```
|
||||||
template <typename T, typename Args>
|
template <typename T, typename Args>
|
||||||
using is_invokable_t = typename detail::is_invokable_impl<T, Args>::type;
|
using is_invokable = typename detail::is_invokable_impl<T, Args>::type;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
/// Forwards every element in the tuple except the last one
|
/// Forwards every element in the tuple except the last one
|
||||||
@ -124,7 +124,7 @@ auto partial_invoke_impl(std::false_type, T&& callable,
|
|||||||
auto next = forward_except_last(std::move(args));
|
auto next = forward_except_last(std::move(args));
|
||||||
|
|
||||||
// Test whether we are able to call the function with the given tuple
|
// Test whether we are able to call the function with the given tuple
|
||||||
is_invokable_t<decltype(callable), decltype(next)> is_invokable;
|
is_invokable<decltype(callable), decltype(next)> is_invokable;
|
||||||
|
|
||||||
return partial_invoke_impl(is_invokable, std::forward<T>(callable),
|
return partial_invoke_impl(is_invokable, std::forward<T>(callable),
|
||||||
std::move(next));
|
std::move(next));
|
||||||
@ -157,7 +157,7 @@ auto partial_invoke_impl_shortcut(std::false_type failed, T&& callable,
|
|||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
auto partial_invoke(T&& callable, Args&&... args) {
|
auto partial_invoke(T&& callable, Args&&... args) {
|
||||||
// Test whether we are able to call the function with the given arguments.
|
// Test whether we are able to call the function with the given arguments.
|
||||||
is_invokable_t<decltype(callable), std::tuple<Args...>> is_invokable;
|
is_invokable<decltype(callable), std::tuple<Args...>> is_invokable;
|
||||||
|
|
||||||
// The implementation is done in a shortcut way so there are less
|
// The implementation is done in a shortcut way so there are less
|
||||||
// type instantiations needed to call the callable with its full signature.
|
// type instantiations needed to call the callable with its full signature.
|
||||||
|
|||||||
@ -57,7 +57,18 @@ static cti::continuable<std::string> http_request3(std::string url) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct my_callable {
|
||||||
|
void operator()(std::string) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
void operator()(cti::dispatch_error_tag, cti::error_type) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
int main(int, char**) {
|
int main(int, char**) {
|
||||||
|
http_request("github.com").then(my_callable{});
|
||||||
|
|
||||||
http_request("github.com")
|
http_request("github.com")
|
||||||
.then([](std::string) {
|
.then([](std::string) {
|
||||||
// ...
|
// ...
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user