mirror of
https://github.com/Naios/continuable.git
synced 2026-02-09 11:16:40 +08:00
Add invoker for the result class and specialized ones
This commit is contained in:
parent
ffa3b9ee1b
commit
07c8ed0cf9
@ -182,6 +182,15 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_result : std::false_type {};
|
||||||
|
template <typename... T>
|
||||||
|
struct is_result<result<T...>> : std::true_type {};
|
||||||
|
template <>
|
||||||
|
struct is_result<empty_result> : std::true_type {};
|
||||||
|
template <>
|
||||||
|
struct is_result<exceptional_result> : std::true_type {};
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
constexpr auto make_result(T&&... values) {
|
constexpr auto make_result(T&&... values) {
|
||||||
return result<detail::traits::unrefcv_t<T>...>(std::forward<T>(values)...);
|
return result<detail::traits::unrefcv_t<T>...>(std::forward<T>(values)...);
|
||||||
|
|||||||
@ -159,9 +159,9 @@ constexpr auto make_invoker(T&& invoke, hints::signature_hint_tag<Args...>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// - continuable<?...> -> result(next_callback);
|
/// - continuable<?...> -> result(next_callback);
|
||||||
template <typename Data, typename Annotation>
|
template <typename Hint, typename Data, typename Annotation>
|
||||||
constexpr auto
|
constexpr auto
|
||||||
invoker_of(traits::identity<continuable_base<Data, Annotation>>) {
|
invoker_of(Hint, traits::identity<continuable_base<Data, Annotation>>) {
|
||||||
/// Get the hint of the unwrapped returned continuable
|
/// Get the hint of the unwrapped returned continuable
|
||||||
using Type =
|
using Type =
|
||||||
decltype(std::declval<continuable_base<Data, Annotation>>().finish());
|
decltype(std::declval<continuable_base<Data, Annotation>>().finish());
|
||||||
@ -184,8 +184,8 @@ invoker_of(traits::identity<continuable_base<Data, Annotation>>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// - ? -> next_callback(?)
|
/// - ? -> next_callback(?)
|
||||||
template <typename T>
|
template <typename Hint, typename T>
|
||||||
constexpr auto invoker_of(traits::identity<T>) {
|
constexpr auto invoker_of(Hint, traits::identity<T>) {
|
||||||
return make_invoker(
|
return make_invoker(
|
||||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
CONTINUABLE_BLOCK_TRY_BEGIN
|
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
@ -201,7 +201,8 @@ constexpr auto invoker_of(traits::identity<T>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// - void -> next_callback()
|
/// - void -> next_callback()
|
||||||
inline auto invoker_of(traits::identity<void>) {
|
template <typename Hint>
|
||||||
|
auto invoker_of(Hint, traits::identity<void>) {
|
||||||
return make_invoker(
|
return make_invoker(
|
||||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
CONTINUABLE_BLOCK_TRY_BEGIN
|
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
@ -214,6 +215,51 @@ inline auto invoker_of(traits::identity<void>) {
|
|||||||
traits::identity<>{});
|
traits::identity<>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// - empty_result -> <cancel>
|
||||||
|
template <typename Hint>
|
||||||
|
auto invoker_of(Hint, traits::identity<empty_result>) {
|
||||||
|
return make_invoker(
|
||||||
|
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
|
/*CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
|
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
||||||
|
std::forward<decltype(args)>(args)...);
|
||||||
|
invoke_no_except(
|
||||||
|
std::forward<decltype(next_callback)>(next_callback));
|
||||||
|
CONTINUABLE_BLOCK_TRY_END*/
|
||||||
|
},
|
||||||
|
Hint{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// - exceptional_result -> Hint
|
||||||
|
template <typename Hint>
|
||||||
|
auto invoker_of(Hint, traits::identity<exceptional_result>) {
|
||||||
|
return make_invoker(
|
||||||
|
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
|
/*CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
|
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
||||||
|
std::forward<decltype(args)>(args)...);
|
||||||
|
invoke_no_except(
|
||||||
|
std::forward<decltype(next_callback)>(next_callback));
|
||||||
|
CONTINUABLE_BLOCK_TRY_END*/
|
||||||
|
},
|
||||||
|
Hint{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// - result<Args...> -> Args...
|
||||||
|
template <typename Hint, typename... Args>
|
||||||
|
auto invoker_of(Hint, traits::identity<result<Args...>>) {
|
||||||
|
return make_invoker(
|
||||||
|
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
|
/*CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
|
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
||||||
|
std::forward<decltype(args)>(args)...);
|
||||||
|
invoke_no_except(
|
||||||
|
std::forward<decltype(next_callback)>(next_callback));
|
||||||
|
CONTINUABLE_BLOCK_TRY_END*/
|
||||||
|
},
|
||||||
|
traits::identity<Args...>{});
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a sequenced invoker which is able to invoke
|
/// Returns a sequenced invoker which is able to invoke
|
||||||
/// objects where std::get is applicable.
|
/// objects where std::get is applicable.
|
||||||
inline auto sequenced_unpack_invoker() {
|
inline auto sequenced_unpack_invoker() {
|
||||||
@ -240,15 +286,15 @@ inline auto sequenced_unpack_invoker() {
|
|||||||
} // namespace decoration
|
} // namespace decoration
|
||||||
|
|
||||||
// - std::pair<?, ?> -> next_callback(?, ?)
|
// - std::pair<?, ?> -> next_callback(?, ?)
|
||||||
template <typename First, typename Second>
|
template <typename Hint, typename First, typename Second>
|
||||||
constexpr auto invoker_of(traits::identity<std::pair<First, Second>>) {
|
constexpr auto invoker_of(Hint, traits::identity<std::pair<First, Second>>) {
|
||||||
return make_invoker(sequenced_unpack_invoker(),
|
return make_invoker(sequenced_unpack_invoker(),
|
||||||
traits::identity<First, Second>{});
|
traits::identity<First, Second>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
// - std::tuple<?...> -> next_callback(?...)
|
// - std::tuple<?...> -> next_callback(?...)
|
||||||
template <typename... Args>
|
template <typename Hint, typename... Args>
|
||||||
constexpr auto invoker_of(traits::identity<std::tuple<Args...>>) {
|
constexpr auto invoker_of(Hint, traits::identity<std::tuple<Args...>>) {
|
||||||
return make_invoker(sequenced_unpack_invoker(), traits::identity<Args...>{});
|
return make_invoker(sequenced_unpack_invoker(), traits::identity<Args...>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +373,9 @@ struct result_handler_base<handle_results::yes, Base,
|
|||||||
std::move(static_cast<Base*>(this)->callback_), std::move(args)...))>{};
|
std::move(static_cast<Base*>(this)->callback_), std::move(args)...))>{};
|
||||||
|
|
||||||
// Pick the correct invoker that handles decorating of the result
|
// Pick the correct invoker that handles decorating of the result
|
||||||
auto invoker = decoration::invoker_of(result);
|
auto invoker =
|
||||||
|
decoration::invoker_of(hints::signature_hint_tag<Args...>{}, //
|
||||||
|
result);
|
||||||
|
|
||||||
// Invoke the callback
|
// Invoke the callback
|
||||||
packed_dispatch(std::move(static_cast<Base*>(this)->executor_),
|
packed_dispatch(std::move(static_cast<Base*>(this)->executor_),
|
||||||
@ -493,13 +541,15 @@ template <typename T, typename... Args>
|
|||||||
constexpr auto
|
constexpr auto
|
||||||
next_hint_of(std::integral_constant<handle_results, handle_results::yes>,
|
next_hint_of(std::integral_constant<handle_results, handle_results::yes>,
|
||||||
traits::identity<T> /*callback*/,
|
traits::identity<T> /*callback*/,
|
||||||
hints::signature_hint_tag<Args...> /*current*/) {
|
hints::signature_hint_tag<Args...> current) {
|
||||||
// Partial Invoke the given callback
|
// Partial Invoke the given callback
|
||||||
using Result = decltype(
|
using Result = decltype(
|
||||||
util::partial_invoke(std::declval<T>(), std::declval<Args>()...));
|
util::partial_invoke(std::declval<T>(), std::declval<Args>()...));
|
||||||
|
|
||||||
// Return the hint of thr given invoker
|
// Return the hint of thr given invoker
|
||||||
return decltype(decoration::invoker_of(traits::identify<Result>{}).hint()){};
|
return decltype(decoration::invoker_of(current, //
|
||||||
|
traits::identify<Result>{})
|
||||||
|
.hint()){};
|
||||||
}
|
}
|
||||||
/// Don't progress the hint when we don't continue
|
/// Don't progress the hint when we don't continue
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user