From ba6c4cc905360e31d9a110bc0c9e561ac663d99e Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Mon, 26 Feb 2018 18:55:06 +0100 Subject: [PATCH] More work on the sequential compositioning --- include/continuable/detail/composition.hpp | 9 ++- .../continuable/detail/composition_all.hpp | 58 +++++++++++++++++-- .../continuable/detail/composition_any.hpp | 4 ++ .../detail/composition_remapping.hpp | 5 +- .../continuable/detail/composition_seq.hpp | 25 ++++---- test/playground/test-playground.cpp | 12 +++- 6 files changed, 93 insertions(+), 20 deletions(-) diff --git a/include/continuable/detail/composition.hpp b/include/continuable/detail/composition.hpp index 5050b1c..91e3f4e 100644 --- a/include/continuable/detail/composition.hpp +++ b/include/continuable/detail/composition.hpp @@ -49,6 +49,7 @@ namespace detail { namespace composition { struct composition_strategy_all_tag {}; struct composition_strategy_any_tag {}; +struct composition_strategy_any_fail_fast_tag {}; struct composition_strategy_seq_tag {}; template @@ -60,6 +61,12 @@ struct is_composition_strategy // ... template <> struct is_composition_strategy // ... : std::true_type {}; +template <> +struct is_composition_strategy // ... + : std::true_type {}; +template <> +struct is_composition_strategy // ... + : std::true_type {}; /// Adds the given continuation tuple to the left composition template @@ -158,7 +165,7 @@ struct consume_ownership { template >::value>* = nullptr> - void operator()(Continuable& continuable) noexcept { + void operator()(Continuable&& continuable) noexcept { util::ownership other = base::attorney::ownership_of(continuable); assert(other.is_acquired() && "Only valid continuables should be passed!"); diff --git a/include/continuable/detail/composition_all.hpp b/include/continuable/detail/composition_all.hpp index fce2291..cc63beb 100644 --- a/include/continuable/detail/composition_all.hpp +++ b/include/continuable/detail/composition_all.hpp @@ -163,10 +163,61 @@ auto make_all_result_submitter(Callback&& callback, /// A callable object to merge multiple signature hints together struct entry_merger { template - constexpr auto operator()(T&... entries) const noexcept { - return traits::merge(hints::hint_of(traits::identity_of(entries))...); + constexpr auto operator()(T&&...) const noexcept { + return traits::merge(hints::hint_of(traits::identify())...); } }; + +struct all_hint_deducer { + static constexpr auto deduce(hints::signature_hint_tag<>) noexcept { + return spread_this(); + } + template + static constexpr auto deduce(hints::signature_hint_tag) { + return First{}; + } + template + static constexpr auto + deduce(hints::signature_hint_tag) { + return std::make_tuple(First{}, Second{}, Args{}...); + } + + template < + typename T, + std::enable_if_t>::value>* = nullptr> + auto operator()(T&& /*continuable*/) const { + return deduce(hints::hint_of(traits::identify{})); + } +}; + +/// Converts the given argument to a tuple if it isn't a tuple already +template +constexpr auto tupelize(T&& arg) { + return std::make_tuple(std::forward(arg)); +} +/// Converts the given argument to a tuple if it isn't a tuple already +template +constexpr auto tupelize(std::tuple arg) { + return std::move(arg); +} + +/// Lift the first tuple hierarchy inside the given tuple +template +constexpr auto flatten(T&& tuple) { + return traits::unpack(std::forward(tuple), [](auto&&... args) { + return std::tuple_cat(tupelize(std::forward(args))...); + }); +} + +template +constexpr auto deduce_hint(Composition&& composition) { + auto deduced = flatten( + map_pack(all_hint_deducer{}, std::forward(composition))); + + return traits::unpack(std::move(deduced), [](auto... args) { + return hints::signature_hint_tag{}; + }); +} } // namespace all /// Finalizes the all logic of a given composition @@ -174,8 +225,7 @@ template <> struct composition_finalizer { template static constexpr auto hint() { - return decltype( - traits::unpack(std::declval(), all::entry_merger{})){}; + return decltype(all::deduce_hint(std::declval())){}; } /// Finalizes the all logic of a given composition diff --git a/include/continuable/detail/composition_any.hpp b/include/continuable/detail/composition_any.hpp index cb9f6d8..5e28fa3 100644 --- a/include/continuable/detail/composition_any.hpp +++ b/include/continuable/detail/composition_any.hpp @@ -179,6 +179,10 @@ struct composition_finalizer { }; } }; + +template <> +struct composition_finalizer + : composition_finalizer {}; } // namespace composition } // namespace detail } // namespace cti diff --git a/include/continuable/detail/composition_remapping.hpp b/include/continuable/detail/composition_remapping.hpp index 274c99f..31be52d 100644 --- a/include/continuable/detail/composition_remapping.hpp +++ b/include/continuable/detail/composition_remapping.hpp @@ -79,7 +79,8 @@ struct result_extractor_mapper { } /// Initialize a multiple values as tuple template - static constexpr auto initialize(hints::signature_hint_tag<>) { + static constexpr auto + initialize(hints::signature_hint_tag) { // TODO Fix non default constructible values return std::make_tuple(First{}, Second{}, Args{}...); } @@ -116,7 +117,6 @@ struct result_relocator_mapper { void traverse(traversal::container_category_tag, Index* index, Result* result) { - evaluator(index, result); traverse_one(traits::is_invocable{}, index, result); } @@ -186,7 +186,6 @@ constexpr void relocate_index_pack(Relocator&& relocator, Index* index, mapper.traverse(tag, index, target); } - } // namespace remapping } // namespace composition } // namespace detail diff --git a/include/continuable/detail/composition_seq.hpp b/include/continuable/detail/composition_seq.hpp index 4269e7c..43d07d1 100644 --- a/include/continuable/detail/composition_seq.hpp +++ b/include/continuable/detail/composition_seq.hpp @@ -90,7 +90,8 @@ struct result_indexer_mapper { auto operator()(T& continuable) { auto constexpr const hint = hints::hint_of(traits::identify{}); - using target = decltype(result_extractor_mapper::initialize(hint)); + using target = + decltype(remapping::detail::result_extractor_mapper::initialize(hint)); using type = indexed_continuable, target>; return type{std::move(continuable), nullptr}; @@ -138,7 +139,7 @@ struct sequential_dispatch_data { template class sequential_dispatch_visitor - : std::enable_shared_from_this> { + : public std::enable_shared_from_this> { Data data_; @@ -146,16 +147,19 @@ public: explicit sequential_dispatch_visitor(Data&& data) : data_(std::move(data)) { // Assign the address of each result target to the corresponding // indexed continuable. - relocate_index_pack(index_relocator{}, &data.index, &data.result); + remapping::relocate_index_pack(index_relocator{}, &data.index, + &data.result); } + virtual ~sequential_dispatch_visitor() = default; + /// Returns the pack that should be traversed auto& head() { return data_.index; } - template ::value>* = nullptr> + template >::value>* = nullptr> bool operator()(async_traverse_visit_tag, Index&& /*index*/) { return false; } @@ -165,7 +169,7 @@ public: std::move(index.continuable) .then([ target = index.target, - next = std::forward(next) ](auto&&... args) { + next = std::forward(next) ](auto&&... args) mutable { // Assign the result to the target *target = wrap(std::forward(args)...); @@ -177,10 +181,10 @@ public: } template - void operator()(async_traverse_complete_tag, T&& pack) { + void operator()(async_traverse_complete_tag, T&& /*pack*/) { // Remove void result guard tags - auto cleaned = - map_pack(remapping::clean_void_results{}, std::forward(pack)); + auto cleaned = all::flatten( + map_pack(remapping::clean_void_results{}, std::move(data_.result))); // Call the final callback with the cleaned result traits::unpack(std::move(cleaned), std::move(data_.callback)); @@ -193,8 +197,7 @@ template <> struct composition_finalizer { template static constexpr auto hint() { - return decltype( - traits::unpack(std::declval(), all::entry_merger{})){}; + return decltype(all::deduce_hint(std::declval())){}; } /// Finalizes the all logic of a given composition diff --git a/test/playground/test-playground.cpp b/test/playground/test-playground.cpp index 766c862..17ead1f 100644 --- a/test/playground/test-playground.cpp +++ b/test/playground/test-playground.cpp @@ -68,7 +68,7 @@ struct my_callable { } }; -int main(int, char**) { +void old() { http_request("github.com").next(my_callable{}); http_request("github.com") | [](std::string) { @@ -118,3 +118,13 @@ int main(int, char**) { // ... }); } + +int main(int, char**) { + using namespace cti::detail; + + apply_composition(composition::composition_strategy_seq_tag{}, + cti::make_ready_continuable(0, 1), 2) + .then([](int a0, int a1, int a2) { + // ... + }); +}