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 {
|
inline auto exception_invoker_of(traits::identity<void>) noexcept {
|
||||||
return [](auto&& callback, auto&& next_callback, auto&&... args) {
|
return [](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
CONTINUABLE_BLOCK_TRY_BEGIN
|
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
util::invoke(std::forward<decltype(callback)>(callback),
|
||||||
std::forward<decltype(args)>(args)...);
|
std::forward<decltype(args)>(args)...);
|
||||||
|
|
||||||
// The legacy behaviour is not to proceed the chain
|
// 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>
|
/*template <typename... Args>
|
||||||
auto exception_invoker_of(Other other) noexcept {
|
auto exception_invoker_of(traits::identity<result<Args...>> id) noexcept {
|
||||||
return invoker_of(other);
|
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
|
#undef CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
@ -587,16 +659,25 @@ next_hint_of(std::integral_constant<handle_results, handle_results::no>,
|
|||||||
return current;
|
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
|
/// Removes the exception_arg_t from the arguments passed to the given callable
|
||||||
template <typename Callable>
|
template <typename Callable>
|
||||||
auto strip_exception_arg(Callable&& callable) {
|
auto strip_exception_arg(Callable&& callable) {
|
||||||
return [callable = std::forward<Callable>(callable)] //
|
using proxy = detail::exception_stripper_proxy<traits::unrefcv_t<Callable>>;
|
||||||
(exception_arg_t, auto&&... args) mutable
|
return proxy{std::forward<Callable>(callable)};
|
||||||
-> decltype(util::invoke(std::declval<Callable>(), //
|
|
||||||
std::declval<decltype(args)>()...)) {
|
|
||||||
return util::invoke(std::move(callable), //
|
|
||||||
std::forward<decltype(args)>(args)...);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Chains a callback together with a continuation and returns a continuation:
|
/// 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);
|
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 <std::size_t Keep>
|
||||||
template <typename T, typename... Args>
|
struct invocation_env {
|
||||||
auto partial_invoke_impl(std::true_type, T&& callable,
|
/// 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) {
|
std::tuple<Args...> args) {
|
||||||
return traits::unpack(std::forward<T>(callable), std::move(args));
|
return traits::unpack(std::forward<T>(callable), std::move(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We were unable to call the callable with the arguments in the tuple.
|
/// We were unable to call the callable with the arguments in the tuple.
|
||||||
/// Remove the last argument from the tuple and try it again.
|
/// Remove the last argument from the tuple and try it again.
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
auto partial_invoke_impl(std::false_type, T&& callable,
|
static auto partial_invoke_impl(std::false_type, T&& callable,
|
||||||
std::tuple<Args...> args) {
|
std::tuple<Args...> args) {
|
||||||
|
|
||||||
// If you are encountering this assertion you tried to attach a callback
|
// 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) { /*...*/ })
|
// std::move(c).then([](std::vector<int> v) { /*...*/ })
|
||||||
// ```
|
// ```
|
||||||
static_assert(
|
static_assert(
|
||||||
sizeof...(Args) > 0,
|
sizeof...(Args) > Keep,
|
||||||
"There is no way to call the given object with these arguments!");
|
"There is no way to call the given object with these arguments!");
|
||||||
|
|
||||||
// Remove the last argument from the tuple
|
// 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),
|
return partial_invoke_impl(is_invokable, std::forward<T>(callable),
|
||||||
std::move(next));
|
std::move(next));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shortcut - we can call the callable directly
|
/// Shortcut - we can call the callable directly
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
auto partial_invoke_impl_shortcut(std::true_type, T&& callable,
|
static auto partial_invoke_impl_shortcut(std::true_type, T&& callable,
|
||||||
Args&&... args) {
|
Args&&... args) {
|
||||||
return std::forward<T>(callable)(std::forward<Args>(args)...);
|
return std::forward<T>(callable)(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Failed shortcut - we were unable to invoke the callable with the
|
/// Failed shortcut - we were unable to invoke the callable with the
|
||||||
/// original arguments.
|
/// original arguments.
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
auto partial_invoke_impl_shortcut(std::false_type failed, T&& callable,
|
static auto partial_invoke_impl_shortcut(std::false_type failed, T&& callable,
|
||||||
Args&&... args) {
|
Args&&... args) {
|
||||||
|
|
||||||
// Our shortcut failed, convert the arguments into a forwarding tuple
|
// Our shortcut failed, convert the arguments into a forwarding tuple
|
||||||
return partial_invoke_impl(
|
return partial_invoke_impl(
|
||||||
failed, std::forward<T>(callable),
|
failed, std::forward<T>(callable),
|
||||||
std::forward_as_tuple(std::forward<Args>(args)...));
|
std::forward_as_tuple(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
/// Partially invokes the given callable with the given arguments.
|
/// 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
|
// 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.
|
||||||
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)...);
|
is_invokable, std::forward<T>(callable), std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user