mirror of
https://github.com/Naios/continuable.git
synced 2025-12-08 01:36:46 +08:00
Lift connection logic up from all and any to a unified function
This commit is contained in:
parent
fb4a34b328
commit
b3a4a3d359
@ -608,8 +608,7 @@ private:
|
||||
OAnnotation>::value>* = nullptr>
|
||||
static auto
|
||||
materializeImpl(continuable_base<OData, OAnnotation>&& continuable) {
|
||||
using finalizer = detail::composition::composition_finalizer<OAnnotation>;
|
||||
return finalizer::finalize(std::move(continuable));
|
||||
return detail::composition::finalize_composition(std::move(continuable));
|
||||
}
|
||||
|
||||
Data&& consume_data() && {
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <continuable/continuable-traverse.hpp>
|
||||
#include <continuable/detail/base.hpp>
|
||||
#include <continuable/detail/traits.hpp>
|
||||
#include <continuable/detail/types.hpp>
|
||||
@ -126,11 +127,46 @@ auto connect(Strategy strategy, continuable_base<LData, LAnnotation>&& left,
|
||||
return base::attorney::create(std::move(data), strategy, ownership_);
|
||||
}
|
||||
|
||||
/// All strategies should specialize this class in order to provide
|
||||
/// a finalize static method.
|
||||
/// All strategies should specialize this class in order to provide:
|
||||
/// - A finalize static method that creates the callable object which
|
||||
/// is invoked with the callback to call when the composition is finished.
|
||||
/// - A static method hint that returns the new signature hint.
|
||||
template <typename Strategy>
|
||||
struct composition_finalizer;
|
||||
|
||||
struct aggregate_ownership {
|
||||
util::ownership& ownership_;
|
||||
|
||||
template <typename Continuable,
|
||||
std::enable_if_t<base::is_continuable<
|
||||
std::decay_t<Continuable>>::value>* = nullptr>
|
||||
auto operator()(Continuable const& continuable) noexcept {
|
||||
util::ownership other = base::attorney::ownership_of(continuable);
|
||||
/*if (!other.is_default())*/ { ownership_ |= other; }
|
||||
}
|
||||
};
|
||||
|
||||
// Merges the ownership of all continuables involved into the strategy
|
||||
/*if (ownership.is_acquired() || !ownership.is_frozen()) {
|
||||
traverse_pack(aggregate_ownership{ownership}, composition);
|
||||
}*/
|
||||
|
||||
/// Finalizes the any logic of a given composition
|
||||
template <typename Data, typename Strategy>
|
||||
auto finalize_composition(continuable_base<Data, Strategy>&& continuation) {
|
||||
using finalizer = composition_finalizer<Strategy>;
|
||||
|
||||
util::ownership ownership = base::attorney::ownership_of(continuation);
|
||||
auto composition = base::attorney::consume_data(std::move(continuation));
|
||||
|
||||
// Retrieve the new signature hint
|
||||
constexpr auto const signature =
|
||||
finalizer::template hint<decltype(composition)>();
|
||||
|
||||
// Return a new continuable which
|
||||
return base::attorney::create(finalizer::finalize(std::move(composition)),
|
||||
signature, std::move(ownership));
|
||||
}
|
||||
} // namespace composition
|
||||
} // namespace detail
|
||||
} // namespace cti
|
||||
|
||||
@ -172,59 +172,55 @@ struct entry_merger {
|
||||
/// Finalizes the all logic of a given composition
|
||||
template <>
|
||||
struct composition_finalizer<composition_strategy_all_tag> {
|
||||
template <typename Composition>
|
||||
static constexpr auto hint() {
|
||||
return decltype(
|
||||
traits::unpack(std::declval<Composition>(), all::entry_merger{})){};
|
||||
}
|
||||
|
||||
/// Finalizes the all logic of a given composition
|
||||
template <typename Continuable>
|
||||
static auto finalize(Continuable&& continuation) {
|
||||
template <typename Composition>
|
||||
static auto finalize(Composition&& composition) {
|
||||
return [composition = std::forward<Composition>(composition)](
|
||||
auto&& callback) mutable {
|
||||
|
||||
auto ownership_ = base::attorney::ownership_of(continuation);
|
||||
// We mark the current 2-dimensional position through a pair:
|
||||
// std::pair<size_constant<?>, size_constant<?>>
|
||||
// ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
|
||||
// Continuation pos Result pos
|
||||
constexpr auto const begin = std::make_pair(
|
||||
traits::size_constant_of<0>(), traits::size_constant_of<0>());
|
||||
constexpr auto const pack = traits::identify<decltype(composition)>{};
|
||||
constexpr auto const end = traits::pack_size_of(pack);
|
||||
auto const condition = [=](auto pos) { return pos.first < end; };
|
||||
|
||||
auto composition =
|
||||
base::attorney::consume_data(std::forward<Continuable>(continuation));
|
||||
constexpr auto const signature = hint<Composition>();
|
||||
|
||||
// Merge all signature hints together
|
||||
constexpr auto const signature =
|
||||
traits::unpack(composition, all::entry_merger{});
|
||||
// Create the result submitter which caches all results and invokes
|
||||
// the final callback upon completion.
|
||||
auto submitter = all::make_all_result_submitter(
|
||||
std::forward<decltype(callback)>(callback), end, signature);
|
||||
|
||||
return base::attorney::create(
|
||||
[ signature,
|
||||
composition = std::move(composition) ](auto&& callback) mutable {
|
||||
// We mark the current 2-dimensional position through a pair:
|
||||
// std::pair<size_constant<?>, size_constant<?>>
|
||||
// ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
|
||||
// Continuation pos Result pos
|
||||
constexpr auto const begin = std::make_pair(
|
||||
traits::size_constant_of<0>(), traits::size_constant_of<0>());
|
||||
constexpr auto const pack = traits::identify<decltype(composition)>{};
|
||||
constexpr auto const end = traits::pack_size_of(pack);
|
||||
auto const condition = [=](auto pos) { return pos.first < end; };
|
||||
// Invoke every continuation with it's callback of the submitter
|
||||
traits::static_while(begin, condition, [&](auto current) mutable {
|
||||
auto entry =
|
||||
std::move(std::get<decltype(current.first)::value>(composition));
|
||||
|
||||
// Create the result submitter which caches all results and invokes
|
||||
// the final callback upon completion.
|
||||
auto submitter = all::make_all_result_submitter(
|
||||
std::forward<decltype(callback)>(callback), end, signature);
|
||||
// This is the length of the arguments of the current continuable
|
||||
constexpr auto const arg_size =
|
||||
traits::pack_size_of(hints::hint_of(traits::identity_of(entry)));
|
||||
|
||||
// Invoke every continuation with it's callback of the submitter
|
||||
traits::static_while(begin, condition, [&](auto current) mutable {
|
||||
auto entry = std::move(
|
||||
std::get<decltype(current.first)::value>(composition));
|
||||
// The next position in the result tuple
|
||||
constexpr auto const next = current.second + arg_size;
|
||||
|
||||
// This is the length of the arguments of the current continuable
|
||||
constexpr auto const arg_size = traits::pack_size_of(
|
||||
hints::hint_of(traits::identity_of(entry)));
|
||||
// Invoke the continuation with the associated submission callback
|
||||
base::attorney::invoke_continuation(
|
||||
std::move(entry), submitter->create_callback(current.second, next));
|
||||
|
||||
// The next position in the result tuple
|
||||
constexpr auto const next = current.second + arg_size;
|
||||
|
||||
// Invoke the continuation with the associated submission callback
|
||||
base::attorney::invoke_continuation(
|
||||
std::move(entry),
|
||||
submitter->create_callback(current.second, next));
|
||||
|
||||
return std::make_pair(current.first + traits::size_constant_of<1>(),
|
||||
next);
|
||||
});
|
||||
},
|
||||
signature, std::move(ownership_));
|
||||
return std::make_pair(current.first + traits::size_constant_of<1>(),
|
||||
next);
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace composition
|
||||
|
||||
@ -153,35 +153,30 @@ private:
|
||||
/// Finalizes the any logic of a given composition
|
||||
template <>
|
||||
struct composition_finalizer<composition_strategy_any_tag> {
|
||||
template <typename Continuable>
|
||||
static auto finalize(Continuable&& continuation) {
|
||||
template <typename Composition>
|
||||
static constexpr auto hint() {
|
||||
return decltype(traits::unpack(std::declval<Composition>(),
|
||||
any::determine_shared_result{})){};
|
||||
}
|
||||
|
||||
auto ownership = base::attorney::ownership_of(continuation);
|
||||
template <typename Composition>
|
||||
static auto finalize(Composition&& composition) {
|
||||
return [composition = std::forward<Composition>(composition)](
|
||||
auto&& callback) mutable {
|
||||
// Create the submitter which calls the given callback once at the
|
||||
// first callback invocation.
|
||||
auto submitter = any::make_any_result_submitter(
|
||||
std::forward<decltype(callback)>(callback));
|
||||
|
||||
auto composition =
|
||||
base::attorney::consume_data(std::forward<Continuable>(continuation));
|
||||
|
||||
constexpr auto const signature =
|
||||
traits::unpack(composition, any::determine_shared_result{});
|
||||
|
||||
return base::attorney::create(
|
||||
[composition = std::move(composition)](auto&& callback) mutable {
|
||||
|
||||
// Create the submitter which calls the given callback once at the
|
||||
// first callback invocation.
|
||||
auto submitter = any::make_any_result_submitter(
|
||||
std::forward<decltype(callback)>(callback));
|
||||
|
||||
traits::static_for_each_in(std::move(composition),
|
||||
[&](auto&& entry) mutable {
|
||||
// Invoke the continuation with a
|
||||
// submission callback
|
||||
base::attorney::invoke_continuation(
|
||||
std::forward<decltype(entry)>(entry),
|
||||
submitter->create_callback());
|
||||
});
|
||||
},
|
||||
signature, std::move(ownership));
|
||||
traits::static_for_each_in(std::move(composition),
|
||||
[&](auto&& entry) mutable {
|
||||
// Invoke the continuation with a
|
||||
// submission callback
|
||||
base::attorney::invoke_continuation(
|
||||
std::forward<decltype(entry)>(entry),
|
||||
submitter->create_callback());
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace composition
|
||||
|
||||
@ -202,6 +202,16 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assigns the right ownership to this one
|
||||
ownership& operator|=(ownership const& right) noexcept {
|
||||
if (!right.is_acquired()) {
|
||||
release();
|
||||
}
|
||||
if (right.is_frozen()) {
|
||||
freeze();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
// Merges both ownerships together
|
||||
ownership operator|(ownership const& right) const noexcept {
|
||||
return ownership(is_acquired() && right.is_acquired(),
|
||||
@ -214,6 +224,10 @@ public:
|
||||
constexpr bool is_frozen() const noexcept {
|
||||
return frozen_;
|
||||
}
|
||||
/// Returns true when the ownership is in the default state
|
||||
constexpr bool is_default() const noexcept {
|
||||
return is_acquired() && !is_frozen();
|
||||
}
|
||||
|
||||
void release() noexcept {
|
||||
assert(is_acquired() && "Tried to release the ownership twice!");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user