mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Fix the build
This commit is contained in:
parent
f1f9d61952
commit
bb7112eec2
@ -326,7 +326,7 @@ constexpr auto invoker_of(traits::identity<std::tuple<Args...>>) {
|
||||
inline auto exception_invoker_of(traits::identity<void>) noexcept {
|
||||
return [](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
||||
util::invoke(std::forward<decltype(callback)>(callback),
|
||||
std::forward<decltype(args)>(args)...);
|
||||
|
||||
// The legacy behaviour is not to proceed the chain
|
||||
@ -336,9 +336,81 @@ inline auto exception_invoker_of(traits::identity<void>) noexcept {
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Other>
|
||||
auto exception_invoker_of(Other other) noexcept {
|
||||
return invoker_of(other);
|
||||
/*template <typename... Args>
|
||||
auto exception_invoker_of(traits::identity<result<Args...>> id) noexcept {
|
||||
return invoker_of(id);
|
||||
}*/
|
||||
|
||||
/// - empty_result -> <cancel>
|
||||
inline auto exception_invoker_of(traits::identity<empty_result>) {
|
||||
return make_invoker(
|
||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||
(void)next_callback;
|
||||
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||
empty_result result =
|
||||
util::invoke(std::forward<decltype(callback)>(callback),
|
||||
std::forward<decltype(args)>(args)...);
|
||||
|
||||
// Don't invoke anything here since returning an empty result
|
||||
// cancels the asynchronous chain effectively.
|
||||
(void)result;
|
||||
CONTINUABLE_BLOCK_TRY_END
|
||||
},
|
||||
traits::identity<>{});
|
||||
}
|
||||
|
||||
/// - exceptional_result -> <throw>
|
||||
inline auto exception_invoker_of(traits::identity<exceptional_result>) {
|
||||
return make_invoker(
|
||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||
util::unused(callback, next_callback, args...);
|
||||
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||
exceptional_result result =
|
||||
util::invoke(std::forward<decltype(callback)>(callback),
|
||||
std::forward<decltype(args)>(args)...);
|
||||
|
||||
// Forward the exception to the next available handler
|
||||
invoke_no_except(std::forward<decltype(next_callback)>(next_callback),
|
||||
exception_arg_t{},
|
||||
std::move(result).get_exception());
|
||||
CONTINUABLE_BLOCK_TRY_END
|
||||
},
|
||||
traits::identity<>{});
|
||||
}
|
||||
|
||||
/// - result<?...> -> next_callback(?...)
|
||||
template <typename... Args>
|
||||
auto exception_invoker_of(traits::identity<result<Args...>>) {
|
||||
return make_invoker(
|
||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||
result<Args...> result =
|
||||
util::invoke(std::forward<decltype(callback)>(callback),
|
||||
std::forward<decltype(args)>(args)...);
|
||||
if (result.is_value()) {
|
||||
// Workaround for MSVC not capturing the reference
|
||||
// correctly inside the lambda.
|
||||
using Next = decltype(next_callback);
|
||||
|
||||
result_trait<Args...>::visit(
|
||||
std::move(result), //
|
||||
[&](auto&&... values) {
|
||||
invoke_no_except(std::forward<Next>(next_callback),
|
||||
std::forward<decltype(values)>(values)...);
|
||||
});
|
||||
|
||||
} else if (result.is_exception()) {
|
||||
// Forward the exception to the next available handler
|
||||
invoke_no_except(
|
||||
std::forward<decltype(next_callback)>(next_callback),
|
||||
exception_arg_t{}, std::move(result).get_exception());
|
||||
}
|
||||
|
||||
// Otherwise the result is empty and we are cancelling our
|
||||
// asynchronous chain.
|
||||
CONTINUABLE_BLOCK_TRY_END
|
||||
},
|
||||
traits::identity<Args...>{});
|
||||
}
|
||||
|
||||
#undef CONTINUABLE_BLOCK_TRY_BEGIN
|
||||
@ -587,16 +659,25 @@ next_hint_of(std::integral_constant<handle_results, handle_results::no>,
|
||||
return current;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename Callable>
|
||||
struct exception_stripper_proxy {
|
||||
Callable callable_;
|
||||
template <typename... Args>
|
||||
auto operator()(exception_arg_t, Args&&... args)
|
||||
-> decltype(util::invoke(std::declval<Callable>(), //
|
||||
std::declval<Args>()...)) {
|
||||
return util::invoke(std::move(callable_), //
|
||||
std::forward<decltype(args)>(args)...);
|
||||
};
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/// Removes the exception_arg_t from the arguments passed to the given callable
|
||||
template <typename Callable>
|
||||
auto strip_exception_arg(Callable&& callable) {
|
||||
return [callable = std::forward<Callable>(callable)] //
|
||||
(exception_arg_t, auto&&... args) mutable
|
||||
-> decltype(util::invoke(std::declval<Callable>(), //
|
||||
std::declval<decltype(args)>()...)) {
|
||||
return util::invoke(std::move(callable), //
|
||||
std::forward<decltype(args)>(args)...);
|
||||
};
|
||||
using proxy = detail::exception_stripper_proxy<traits::unrefcv_t<Callable>>;
|
||||
return proxy{std::forward<Callable>(callable)};
|
||||
}
|
||||
|
||||
/// Chains a callback together with a continuation and returns a continuation:
|
||||
|
||||
@ -64,17 +64,19 @@ auto forward_except_last(T&& sequenceable) {
|
||||
return forward_except_last_impl(std::forward<T>(sequenceable), sequence);
|
||||
}
|
||||
|
||||
/// We are able to call the callable with the arguments given in the tuple
|
||||
template <typename T, typename... Args>
|
||||
auto partial_invoke_impl(std::true_type, T&& callable,
|
||||
template <std::size_t Keep>
|
||||
struct invocation_env {
|
||||
/// We are able to call the callable with the arguments given in the tuple
|
||||
template <typename T, typename... Args>
|
||||
static auto partial_invoke_impl(std::true_type, T&& callable,
|
||||
std::tuple<Args...> args) {
|
||||
return traits::unpack(std::forward<T>(callable), std::move(args));
|
||||
}
|
||||
}
|
||||
|
||||
/// We were unable to call the callable with the arguments in the tuple.
|
||||
/// Remove the last argument from the tuple and try it again.
|
||||
template <typename T, typename... Args>
|
||||
auto partial_invoke_impl(std::false_type, T&& callable,
|
||||
/// We were unable to call the callable with the arguments in the tuple.
|
||||
/// Remove the last argument from the tuple and try it again.
|
||||
template <typename T, typename... Args>
|
||||
static auto partial_invoke_impl(std::false_type, T&& callable,
|
||||
std::tuple<Args...> args) {
|
||||
|
||||
// If you are encountering this assertion you tried to attach a callback
|
||||
@ -85,7 +87,7 @@ auto partial_invoke_impl(std::false_type, T&& callable,
|
||||
// std::move(c).then([](std::vector<int> v) { /*...*/ })
|
||||
// ```
|
||||
static_assert(
|
||||
sizeof...(Args) > 0,
|
||||
sizeof...(Args) > Keep,
|
||||
"There is no way to call the given object with these arguments!");
|
||||
|
||||
// Remove the last argument from the tuple
|
||||
@ -97,26 +99,27 @@ auto partial_invoke_impl(std::false_type, T&& callable,
|
||||
|
||||
return partial_invoke_impl(is_invokable, std::forward<T>(callable),
|
||||
std::move(next));
|
||||
}
|
||||
}
|
||||
|
||||
/// Shortcut - we can call the callable directly
|
||||
template <typename T, typename... Args>
|
||||
auto partial_invoke_impl_shortcut(std::true_type, T&& callable,
|
||||
/// Shortcut - we can call the callable directly
|
||||
template <typename T, typename... Args>
|
||||
static auto partial_invoke_impl_shortcut(std::true_type, T&& callable,
|
||||
Args&&... args) {
|
||||
return std::forward<T>(callable)(std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
/// Failed shortcut - we were unable to invoke the callable with the
|
||||
/// original arguments.
|
||||
template <typename T, typename... Args>
|
||||
auto partial_invoke_impl_shortcut(std::false_type failed, T&& callable,
|
||||
/// Failed shortcut - we were unable to invoke the callable with the
|
||||
/// original arguments.
|
||||
template <typename T, typename... Args>
|
||||
static auto partial_invoke_impl_shortcut(std::false_type failed, T&& callable,
|
||||
Args&&... args) {
|
||||
|
||||
// Our shortcut failed, convert the arguments into a forwarding tuple
|
||||
return partial_invoke_impl(
|
||||
failed, std::forward<T>(callable),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/// Partially invokes the given callable with the given arguments.
|
||||
@ -131,7 +134,8 @@ template <typename T, typename... Args>
|
||||
|
||||
// The implementation is done in a shortcut way so there are less
|
||||
// type instantiations needed to call the callable with its full signature.
|
||||
return detail::partial_invoke_impl_shortcut(
|
||||
using env = detail::invocation_env<0U>;
|
||||
return env::partial_invoke_impl_shortcut(
|
||||
is_invokable, std::forward<T>(callable), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user