Implement the nested when_any connection

This commit is contained in:
Denis Blank 2018-03-04 08:14:11 +01:00
parent cdbc332287
commit 9ecbb00f5a
2 changed files with 23 additions and 39 deletions

View File

@ -39,6 +39,7 @@
#include <utility>
#include <continuable/continuable-promise-base.hpp>
#include <continuable/continuable-traverse.hpp>
#include <continuable/detail/base.hpp>
#include <continuable/detail/container-category.hpp>
#include <continuable/detail/hints.hpp>
@ -94,14 +95,6 @@ private:
}
};
/// Creates a submitter that continues `any` chains
template <typename Callback>
auto make_any_result_submitter(Callback&& callback) {
return std::make_shared<
any_result_submitter<std::decay_t<decltype(callback)>>>(
std::forward<decltype(callback)>(callback));
}
struct result_deducer {
template <typename T>
static auto deduce_one(std::false_type, traits::identity<T>) {
@ -159,6 +152,21 @@ struct result_deducer {
return deduce_tuple_like(i, id);
}
};
template <typename Submitter>
struct continuable_dispatcher {
std::shared_ptr<Submitter>& submitter;
template <typename Continuable,
std::enable_if_t<base::is_continuable<
std::decay_t<Continuable>>::value>* = nullptr>
void operator()(Continuable&& continuable) const {
// Retrieve a callback from the submitter and attach it to the continuable
std::forward<Continuable>(continuable)
.next(submitter->create_callback())
.done();
}
};
} // namespace any
/// Finalizes the any logic of a given composition
@ -175,19 +183,17 @@ struct composition_finalizer<composition_strategy_any_tag> {
static auto finalize(Composition&& composition) {
return [composition = std::forward<Composition>(composition)](
auto&& callback) mutable {
using submitter_t =
any::any_result_submitter<std::decay_t<decltype(callback)>>;
// Create the submitter which calls the given callback once at the
// first callback invocation.
auto submitter = any::make_any_result_submitter(
auto submitter = std::make_shared<submitter_t>(
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());
});
traverse_pack(any::continuable_dispatcher<submitter_t>{submitter},
std::move(composition));
};
}
};

View File

@ -198,18 +198,6 @@ constexpr auto static_if_impl(std::false_type, Type&& type,
return std::forward<FalseCallback>(falseCallback)(std::forward<Type>(type));
}
/// Applies the given callable to all objects in a sequence
template <typename C>
struct apply_to_all {
C callable;
template <typename... T>
constexpr void operator()(T&&... args) {
(void)std::initializer_list<int>{
0, ((void)callable(std::forward<decltype(args)>(args)), 0)...};
}
};
/// Evaluates to the size of the given tuple like type,
// / if the type has no static size it will be one.
template <typename T, typename Enable = void>
@ -364,16 +352,6 @@ constexpr auto unpack(F&& first_sequenceable, S&& second_sequenceable,
sequence_of(identity_of(second_sequenceable)));
}
/// Applies the handler function to each element contained in the sequenceable
// TODO Maybe crashes MSVC in constexpr mode
template <typename Sequenceable, typename Handler>
constexpr void static_for_each_in(Sequenceable&& sequenceable,
Handler&& handler) {
unpack(std::forward<Sequenceable>(sequenceable),
detail::apply_to_all<std::decay_t<Handler>>{
std::forward<Handler>(handler)});
}
/// Adds the given type at the back of the left sequenceable
template <typename Left, typename Element>
constexpr auto push(Left&& left, Element&& element) {