mirror of
https://github.com/Naios/continuable.git
synced 2026-02-14 14:19:48 +08:00
Promisify all and any callbacks
This commit is contained in:
parent
40588e4e6e
commit
2dd1b9f361
@ -38,8 +38,10 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <continuable/continuable-promise-base.hpp>
|
||||||
#include <continuable/detail/api.hpp>
|
#include <continuable/detail/api.hpp>
|
||||||
#include <continuable/detail/base.hpp>
|
#include <continuable/detail/base.hpp>
|
||||||
|
#include <continuable/detail/hints.hpp>
|
||||||
#include <continuable/detail/traits.hpp>
|
#include <continuable/detail/traits.hpp>
|
||||||
#include <continuable/detail/types.hpp>
|
#include <continuable/detail/types.hpp>
|
||||||
|
|
||||||
@ -130,6 +132,26 @@ class all_result_submitter : public std::enable_shared_from_this<
|
|||||||
std::once_flag flag_;
|
std::once_flag flag_;
|
||||||
std::tuple<Args...> result_;
|
std::tuple<Args...> result_;
|
||||||
|
|
||||||
|
template <std::size_t From, std::size_t To>
|
||||||
|
struct partial_callback {
|
||||||
|
std::shared_ptr<all_result_submitter> me_;
|
||||||
|
|
||||||
|
template <typename... PartialArgs>
|
||||||
|
void operator()(PartialArgs&&... args) {
|
||||||
|
me_->resolve(traits::size_constant<From>{}, traits::size_constant<To>{},
|
||||||
|
std::forward<PartialArgs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... PartialArgs>
|
||||||
|
void set_value(PartialArgs&&... args) {
|
||||||
|
(*this)(std::forward<PartialArgs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_exception(types::error_type error) {
|
||||||
|
(*this)(types::dispatch_error_tag{}, std::move(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit all_result_submitter(T callback)
|
explicit all_result_submitter(T callback)
|
||||||
: callback_(std::move(callback)), left_(Submissions) {
|
: callback_(std::move(callback)), left_(Submissions) {
|
||||||
@ -139,13 +161,7 @@ public:
|
|||||||
template <std::size_t From, std::size_t To>
|
template <std::size_t From, std::size_t To>
|
||||||
auto create_callback(traits::size_constant<From> /*from*/,
|
auto create_callback(traits::size_constant<From> /*from*/,
|
||||||
traits::size_constant<To> /*to*/) {
|
traits::size_constant<To> /*to*/) {
|
||||||
|
return partial_callback<From, To>{this->shared_from_this()};
|
||||||
return [me = this->shared_from_this()](auto&&... args) {
|
|
||||||
// Resolve the and composition with the given arguments at the
|
|
||||||
// stored position
|
|
||||||
me->resolve(traits::size_constant<From>{}, traits::size_constant<To>{},
|
|
||||||
std::forward<decltype(args)>(args)...);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -195,9 +211,12 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Invokes the callback with the first arriving result
|
/// Invokes the callback with the first arriving result
|
||||||
template <typename T>
|
template <typename Signature, typename T>
|
||||||
class any_result_submitter
|
class any_result_submitter;
|
||||||
: public std::enable_shared_from_this<any_result_submitter<T>>,
|
template <typename... Args, typename T>
|
||||||
|
class any_result_submitter<hints::signature_hint_tag<Args...>, T>
|
||||||
|
: public std::enable_shared_from_this<
|
||||||
|
any_result_submitter<hints::signature_hint_tag<Args...>, T>>,
|
||||||
public util::non_movable {
|
public util::non_movable {
|
||||||
|
|
||||||
T callback_;
|
T callback_;
|
||||||
@ -209,16 +228,21 @@ public:
|
|||||||
|
|
||||||
/// Creates a submitter which submits it's result to the callback
|
/// Creates a submitter which submits it's result to the callback
|
||||||
auto create_callback() {
|
auto create_callback() {
|
||||||
return [me = this->shared_from_this()](auto&&... args) {
|
auto callback = [me = this->shared_from_this()](auto&&... args) {
|
||||||
me->invoke(std::forward<decltype(args)>(args)...);
|
me->invoke(std::forward<decltype(args)>(args)...);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return promise_base<std::decay_t<decltype(callback)>,
|
||||||
|
hints::signature_hint_tag<Args...>>(
|
||||||
|
std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Invokes the callback with the given arguments
|
// Invokes the callback with the given arguments
|
||||||
template <typename... Args>
|
template <typename... ActualArgs>
|
||||||
void invoke(Args&&... args) {
|
void invoke(ActualArgs&&... args) {
|
||||||
std::call_once(flag_, std::move(callback_), std::forward<Args>(args)...);
|
std::call_once(flag_, std::move(callback_),
|
||||||
|
std::forward<ActualArgs>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@ -355,10 +379,10 @@ auto finalize_composition(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a submitter that continues `any` chains
|
/// Creates a submitter that continues `any` chains
|
||||||
template <typename Callback>
|
template <typename Signature, typename Callback>
|
||||||
auto make_any_result_submitter(Callback&& callback) {
|
auto make_any_result_submitter(Signature&& /*signature*/, Callback&& callback) {
|
||||||
return std::make_shared<
|
return std::make_shared<detail::any_result_submitter<
|
||||||
detail::any_result_submitter<std::decay_t<decltype(callback)>>>(
|
std::decay_t<Signature>, std::decay_t<decltype(callback)>>>(
|
||||||
std::forward<decltype(callback)>(callback));
|
std::forward<decltype(callback)>(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,13 +433,15 @@ auto finalize_composition(
|
|||||||
base::hint_of(traits::identity_of(args))...);
|
base::hint_of(traits::identity_of(args))...);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
using Signature = decltype(signature);
|
||||||
|
|
||||||
return base::attorney::create(
|
return base::attorney::create(
|
||||||
[composition = std::move(composition)](auto&& callback) mutable {
|
[composition = std::move(composition)](auto&& callback) mutable {
|
||||||
|
|
||||||
// Create the submitter which calls the given callback once at the first
|
// Create the submitter which calls the given callback once at the first
|
||||||
// callback invocation.
|
// callback invocation.
|
||||||
auto submitter = make_any_result_submitter(
|
auto submitter = make_any_result_submitter(
|
||||||
std::forward<decltype(callback)>(callback));
|
Signature{}, std::forward<decltype(callback)>(callback));
|
||||||
|
|
||||||
traits::static_for_each_in(std::move(composition),
|
traits::static_for_each_in(std::move(composition),
|
||||||
[&](auto&& entry) mutable {
|
[&](auto&& entry) mutable {
|
||||||
|
|||||||
@ -89,11 +89,9 @@ auto to_hint(identity<Args...> hint) {
|
|||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
auto supplier_of(Args&&... args) {
|
auto supplier_of(Args&&... args) {
|
||||||
return [values = std::make_tuple(std::forward<Args>(args)...)](
|
return [values = std::make_tuple(std::forward<Args>(args)...)](
|
||||||
auto&& callback) mutable {
|
auto&& promise) mutable {
|
||||||
cti::detail::traits::unpack(std::move(values), [&](auto&&... passed) {
|
cti::detail::traits::unpack(std::move(values), [&](auto&&... passed) {
|
||||||
// ...
|
promise.set_value(std::forward<decltype(passed)>(passed)...);
|
||||||
std::forward<decltype(callback)>(callback)(
|
|
||||||
std::forward<decltype(passed)>(passed)...);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -104,8 +102,8 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
auto invoke(T&& type) {
|
auto invoke(T&& type) {
|
||||||
return this->make(identity<>{}, identity<void>{},
|
return this->make(identity<>{}, identity<void>{},
|
||||||
[type = std::forward<T>(type)](auto&& callback) mutable {
|
[type = std::forward<T>(type)](auto&& promise) mutable {
|
||||||
std::forward<decltype(callback)>(callback)();
|
promise.set_value();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,10 +118,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline auto empty_caller() {
|
inline auto empty_caller() {
|
||||||
return [](auto&& callback) {
|
return [](auto&& promise) { promise.set_value(); };
|
||||||
// ...
|
|
||||||
std::forward<decltype(callback)>(callback)();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto empty_continuable() {
|
inline auto empty_continuable() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user