mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Expose finish() method in continuable_base which makes it possible
to materialize the continuable_base when using it as an expression template.
This commit is contained in:
parent
0657445466
commit
6969a9e392
@ -96,6 +96,11 @@ class continuable_base {
|
|||||||
friend class continuable_base;
|
friend class continuable_base;
|
||||||
friend struct detail::base::attorney;
|
friend struct detail::base::attorney;
|
||||||
|
|
||||||
|
// The materializer which is used when this continuable_base is an
|
||||||
|
// expression template such that is_connection_strategy<Annotation>::value
|
||||||
|
// holds for the Annotation.
|
||||||
|
using materializer = detail::connection::materializer<continuable_base>;
|
||||||
|
|
||||||
// The continuation type or intermediate result
|
// The continuation type or intermediate result
|
||||||
Data data_;
|
Data data_;
|
||||||
// The transferable state which represents the validity of the object
|
// The transferable state which represents the validity of the object
|
||||||
@ -126,7 +131,7 @@ public:
|
|||||||
/// the continuable by any object which is useful for type-erasure.
|
/// the continuable by any object which is useful for type-erasure.
|
||||||
template <typename OData, typename OAnnotation>
|
template <typename OData, typename OAnnotation>
|
||||||
continuable_base(continuable_base<OData, OAnnotation>&& other)
|
continuable_base(continuable_base<OData, OAnnotation>&& other)
|
||||||
: continuable_base(std::move(other).materialize().consume_data()) {
|
: continuable_base(std::move(other).finish().consume_data()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \cond false
|
/// \cond false
|
||||||
@ -241,7 +246,7 @@ public:
|
|||||||
E&& executor = detail::types::this_thread_executor_tag{}) && {
|
E&& executor = detail::types::this_thread_executor_tag{}) && {
|
||||||
return detail::base::chain_continuation<detail::base::handle_results::yes,
|
return detail::base::chain_continuation<detail::base::handle_results::yes,
|
||||||
detail::base::handle_errors::no>(
|
detail::base::handle_errors::no>(
|
||||||
std::move(*this).materialize(), std::forward<T>(callback),
|
std::move(*this).finish(), std::forward<T>(callback),
|
||||||
std::forward<E>(executor));
|
std::forward<E>(executor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +272,7 @@ public:
|
|||||||
template <typename OData, typename OAnnotation>
|
template <typename OData, typename OAnnotation>
|
||||||
auto then(continuable_base<OData, OAnnotation>&& continuation) && {
|
auto then(continuable_base<OData, OAnnotation>&& continuation) && {
|
||||||
return std::move(*this).then(
|
return std::move(*this).then(
|
||||||
detail::base::wrap_continuation(std::move(continuation).materialize()));
|
detail::base::wrap_continuation(std::move(continuation).finish()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Main method of the continuable_base to catch exceptions and error codes
|
/// Main method of the continuable_base to catch exceptions and error codes
|
||||||
@ -314,7 +319,7 @@ public:
|
|||||||
E&& executor = detail::types::this_thread_executor_tag{}) && {
|
E&& executor = detail::types::this_thread_executor_tag{}) && {
|
||||||
return detail::base::chain_continuation<detail::base::handle_results::no,
|
return detail::base::chain_continuation<detail::base::handle_results::no,
|
||||||
detail::base::handle_errors::plain>(
|
detail::base::handle_errors::plain>(
|
||||||
std::move(*this).materialize(), std::forward<T>(callback),
|
std::move(*this).finish(), std::forward<T>(callback),
|
||||||
std::forward<E>(executor));
|
std::forward<E>(executor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,7 +380,7 @@ public:
|
|||||||
E&& executor = detail::types::this_thread_executor_tag{}) && {
|
E&& executor = detail::types::this_thread_executor_tag{}) && {
|
||||||
return detail::base::chain_continuation<
|
return detail::base::chain_continuation<
|
||||||
detail::base::handle_results::yes,
|
detail::base::handle_results::yes,
|
||||||
detail::base::handle_errors::forward>(std::move(*this).materialize(),
|
detail::base::handle_errors::forward>(std::move(*this).finish(),
|
||||||
std::forward<T>(callback),
|
std::forward<T>(callback),
|
||||||
std::forward<E>(executor));
|
std::forward<E>(executor));
|
||||||
}
|
}
|
||||||
@ -390,7 +395,7 @@ public:
|
|||||||
/// \since 2.0.0
|
/// \since 2.0.0
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto apply(T&& transform) && {
|
auto apply(T&& transform) && {
|
||||||
return std::forward<T>(transform)(std::move(*this).materialize());
|
return std::forward<T>(transform)(std::move(*this).finish());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The pipe operator | is an alias for the continuable::then method.
|
/// The pipe operator | is an alias for the continuable::then method.
|
||||||
@ -585,6 +590,33 @@ public:
|
|||||||
return std::move(*this);
|
return std::move(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Materializes the continuation expression template and finishes
|
||||||
|
/// the current applied strategy.
|
||||||
|
///
|
||||||
|
/// This can be used in the case where we are chaining continuations lazily
|
||||||
|
/// through a strategy, for instance when applying operators for
|
||||||
|
/// expressing connections and then want to return a materialized
|
||||||
|
/// continuable_base which uses the strategy respectively.
|
||||||
|
/// ```cpp
|
||||||
|
/// auto do_both() {
|
||||||
|
/// return (wait(10s) || wait_key_pressed(KEY_SPACE)).finish();
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Without a call to finish() this would lead to
|
||||||
|
/// // an unintended evaluation strategy:
|
||||||
|
/// do_both() || wait(5s);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// \note When using a type erased continuable_base such as
|
||||||
|
/// `continuable<...>` this method doesn't need to be called
|
||||||
|
/// since the continuable_base is materialized automatically
|
||||||
|
/// on conversion.
|
||||||
|
///
|
||||||
|
/// \since 4.0.0
|
||||||
|
auto finish() && {
|
||||||
|
return materializer::apply(std::move(*this));
|
||||||
|
}
|
||||||
|
|
||||||
/// \cond false
|
/// \cond false
|
||||||
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||||
/// \endcond
|
/// \endcond
|
||||||
@ -667,7 +699,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \since 2.0.0
|
/// \since 2.0.0
|
||||||
auto operator co_await() && {
|
auto operator co_await() && {
|
||||||
return detail::awaiting::create_awaiter(std::move(*this).materialize());
|
return detail::awaiting::create_awaiter(std::move(*this).finish());
|
||||||
}
|
}
|
||||||
/// \cond false
|
/// \cond false
|
||||||
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||||
@ -678,11 +710,6 @@ private:
|
|||||||
ownership_.release();
|
ownership_.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto materialize() && {
|
|
||||||
return detail::connection::materializer<continuable_base>::apply(
|
|
||||||
std::move(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
Data&& consume_data() && {
|
Data&& consume_data() && {
|
||||||
assert_acquired();
|
assert_acquired();
|
||||||
release();
|
release();
|
||||||
|
|||||||
@ -83,7 +83,7 @@ auto normalize(Strategy /*strategy*/,
|
|||||||
|
|
||||||
// If the right continuation is a different strategy materialize it
|
// If the right continuation is a different strategy materialize it
|
||||||
// in order to keep the precedence in cases where: `c1 && (c2 || c3)`.
|
// in order to keep the precedence in cases where: `c1 && (c2 || c3)`.
|
||||||
return std::make_tuple(base::attorney::materialize(std::move(continuation)));
|
return std::make_tuple(std::move(continuation).finish());
|
||||||
}
|
}
|
||||||
/// - The continuable is inside the current strategy state:
|
/// - The continuable is inside the current strategy state:
|
||||||
/// -> return the data of the tuple
|
/// -> return the data of the tuple
|
||||||
@ -179,7 +179,7 @@ public:
|
|||||||
|
|
||||||
// Materialize every continuable
|
// Materialize every continuable
|
||||||
// TODO Actually we would just need to consume the data here
|
// TODO Actually we would just need to consume the data here
|
||||||
return base::attorney::materialize(std::forward<Continuable>(continuable));
|
return std::forward<Continuable>(continuable).finish();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -82,16 +82,11 @@ struct attorney {
|
|||||||
static auto
|
static auto
|
||||||
invoke_continuation(continuable_base<Data, Annotation>&& continuation,
|
invoke_continuation(continuable_base<Data, Annotation>&& continuation,
|
||||||
Callback&& callback) noexcept {
|
Callback&& callback) noexcept {
|
||||||
auto materialized = std::move(continuation).materialize();
|
auto materialized = std::move(continuation).finish();
|
||||||
materialized.release();
|
materialized.release();
|
||||||
return materialized.data_(std::forward<Callback>(callback));
|
return materialized.data_(std::forward<Callback>(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Data, typename Annotation>
|
|
||||||
static auto materialize(continuable_base<Data, Annotation>&& continuation) {
|
|
||||||
return std::move(continuation).materialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Data, typename Annotation>
|
template <typename Data, typename Annotation>
|
||||||
static Data&&
|
static Data&&
|
||||||
consume_data(continuable_base<Data, Annotation>&& continuation) {
|
consume_data(continuable_base<Data, Annotation>&& continuation) {
|
||||||
@ -167,8 +162,8 @@ template <typename Data, typename Annotation>
|
|||||||
constexpr auto
|
constexpr auto
|
||||||
invoker_of(traits::identity<continuable_base<Data, Annotation>>) {
|
invoker_of(traits::identity<continuable_base<Data, Annotation>>) {
|
||||||
/// Get the hint of the unwrapped returned continuable
|
/// Get the hint of the unwrapped returned continuable
|
||||||
using Type = decltype(attorney::materialize(
|
using Type =
|
||||||
std::declval<continuable_base<Data, Annotation>>()));
|
decltype(std::declval<continuable_base<Data, Annotation>>().finish());
|
||||||
|
|
||||||
auto constexpr const hint = hints::hint_of(traits::identify<Type>{});
|
auto constexpr const hint = hints::hint_of(traits::identify<Type>{});
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user