From cd6f7445f0436a1dc0ee9a4b5dfe7861e7c08ab4 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Mon, 12 Mar 2018 08:25:44 +0100 Subject: [PATCH] Calculate the connection hint directly from the intermediate result --- .../detail/composition-aggregated.hpp | 72 +++++-------------- .../continuable/detail/composition-all.hpp | 46 ++++++------ .../continuable/detail/composition-any.hpp | 31 ++++---- .../continuable/detail/composition-seq.hpp | 38 +++++----- include/continuable/detail/composition.hpp | 17 +---- 5 files changed, 78 insertions(+), 126 deletions(-) diff --git a/include/continuable/detail/composition-aggregated.hpp b/include/continuable/detail/composition-aggregated.hpp index dc24ddc..a94dbe1 100644 --- a/include/continuable/detail/composition-aggregated.hpp +++ b/include/continuable/detail/composition-aggregated.hpp @@ -200,20 +200,28 @@ constexpr auto unbox_continuables(Args&&... args) { namespace detail { template -void finalize_impl(traits::identity, Callback&& callback, Data&&) { - std::forward(callback)(); +constexpr auto finalize_impl(traits::identity, Callback&& callback, + Data&&) { + return std::forward(callback)(); } template -void finalize_impl(traits::identity>, Callback&& callback, - Data&& data) { +constexpr auto finalize_impl(traits::identity>, + Callback&& callback, Data&& data) { // Call the final callback with the cleaned result - traits::unpack(unbox_continuables(std::forward(data)), - std::forward(callback)); + return traits::unpack(unbox_continuables(std::forward(data)), + std::forward(callback)); } + +struct hint_mapper { + template + constexpr auto operator()(T...) -> hints::signature_hint_tag { + return {}; + } +}; } // namespace detail template -void finalize_data(Callback&& callback, Data&& data) { +constexpr auto finalize_data(Callback&& callback, Data&& data) { using result_t = decltype(unbox_continuables(std::forward(data))); // Guard the final result against void return detail::finalize_impl(traits::identity>{}, @@ -221,54 +229,10 @@ void finalize_data(Callback&& callback, Data&& data) { std::forward(data)); } -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 unpack_lazy(lazy_value_t{}); - } - - template - static constexpr auto - deduce(hints::signature_hint_tag) { - return spread_this(unpack_lazy(lazy_value_t{}), - unpack_lazy(lazy_value_t{}), - unpack_lazy(lazy_value_t{})...); - } - - template < - typename T, - std::enable_if_t>::value>* = nullptr> - auto operator()(T&& /*continuable*/) const { - return deduce(hints::hint_of(traits::identify{})); - } -}; - -constexpr auto deduce_from_pack(traits::identity) - -> hints::signature_hint_tag<>; -template -constexpr auto deduce_from_pack(traits::identity>) - -> hints::signature_hint_tag; -template -constexpr auto deduce_from_pack(traits::identity) - -> hints::signature_hint_tag; - -// We must guard the mapped type against to be void since this represents an -// empty signature hint. -template -constexpr auto deduce_hint(Composition&& /*composition*/) { - // Don't change this way since it addresses a GCC compiler bug: - // error: extra ';' [-Werror=pedantic] - // std::declval()))>{})){}; - using mapped_t = - decltype(map_pack(all_hint_deducer{}, std::declval())); - using deduced_t = decltype(deduce_from_pack(traits::identity{})); - return deduced_t{}; +template +constexpr auto hint_of_data() { + return decltype(finalize_data(detail::hint_mapper{}, std::declval())){}; } - } // namespace aggregated } // namespace composition } // namespace detail diff --git a/include/continuable/detail/composition-all.hpp b/include/continuable/detail/composition-all.hpp index 3159411..2c570c6 100644 --- a/include/continuable/detail/composition-all.hpp +++ b/include/continuable/detail/composition-all.hpp @@ -153,36 +153,36 @@ struct is_composition_strategy // ... /// Finalizes the all logic of a given composition template <> struct composition_finalizer { - template - static constexpr auto hint() { - return decltype(aggregated::deduce_hint(std::declval())){}; - } - /// Finalizes the all logic of a given composition template - static auto finalize(Composition&& composition) { - return [composition = std::forward(composition)] // ... - (auto&& callback) mutable { + static auto finalize(Composition&& composition, util::ownership ownership) { + // Create the target result from the composition + auto result = + aggregated::box_continuables(std::forward(composition)); - // Create the target result from the composition - auto result = aggregated::box_continuables(std::move(composition)); + auto signature = aggregated::hint_of_data(); - using submitter_t = - all::result_submitter, - std::decay_t>; + return base::attorney::create( + [result = std::move(result)](auto&& callback) mutable { - // Create the shared state which holds the result and the final callback - auto state = std::make_shared( - std::forward(callback), std::move(result)); + using submitter_t = + all::result_submitter, + std::decay_t>; - // Dispatch the continuables and store its partial result - // in the whole result - traverse_pack(all::continuable_dispatcher{state}, - state->head()); + // Create the shared state which holds the result and the final + // callback + auto state = std::make_shared( + std::forward(callback), std::move(result)); - // Finalize the composition if all results arrived in-place - state->accept(); - }; + // Dispatch the continuables and store its partial result + // in the whole result + traverse_pack(all::continuable_dispatcher{state}, + state->head()); + + // Finalize the composition if all results arrived in-place + state->accept(); + }, + signature, std::move(ownership)); } }; } // namespace composition diff --git a/include/continuable/detail/composition-any.hpp b/include/continuable/detail/composition-any.hpp index 0472e81..961346c 100644 --- a/include/continuable/detail/composition-any.hpp +++ b/include/continuable/detail/composition-any.hpp @@ -169,28 +169,27 @@ struct is_composition_strategy // ... template <> struct composition_finalizer { template - static constexpr auto hint() { - return decltype(any::result_deducer::deduce( + static auto finalize(Composition&& composition, util::ownership ownership) { + auto signature = decltype(any::result_deducer::deduce( traversal::container_category_of_t>{}, traits::identity>{})){}; - } - template - static auto finalize(Composition&& composition) { - return [composition = std::forward(composition)]( - auto&& callback) mutable { + return base::attorney::create( + [composition = + std::forward(composition)](auto&& callback) mutable { - using submitter_t = - any::any_result_submitter>; + using submitter_t = + any::any_result_submitter>; - // Create the submitter which calls the given callback once at the - // first callback invocation. - auto submitter = std::make_shared( - std::forward(callback)); + // Create the submitter which calls the given callback once at the + // first callback invocation. + auto submitter = std::make_shared( + std::forward(callback)); - traverse_pack(any::continuable_dispatcher{submitter}, - std::move(composition)); - }; + traverse_pack(any::continuable_dispatcher{submitter}, + std::move(composition)); + }, + signature, std::move(ownership)); } }; } // namespace composition diff --git a/include/continuable/detail/composition-seq.hpp b/include/continuable/detail/composition-seq.hpp index a9cb60e..f3e782c 100644 --- a/include/continuable/detail/composition-seq.hpp +++ b/include/continuable/detail/composition-seq.hpp @@ -134,31 +134,31 @@ struct is_composition_strategy // ... /// Finalizes the seq logic of a given composition template <> struct composition_finalizer { - template - static constexpr auto hint() { - return decltype(aggregated::deduce_hint(std::declval())){}; - } - /// Finalizes the all logic of a given composition template - static auto finalize(Composition&& composition) { - return [composition = std::forward(composition)] // ... - (auto&& callback) mutable { + static auto finalize(Composition&& composition, util::ownership ownership) { - auto boxed = aggregated::box_continuables(std::move(composition)); + auto result = + aggregated::box_continuables(std::forward(composition)); - // The data from which the visitor is constructed in-place - using data_t = - seq::sequential_dispatch_data, - std::decay_t>; + auto signature = aggregated::hint_of_data(); - // The visitor type - using visitor_t = seq::sequential_dispatch_visitor; + return base::attorney::create( + [result = std::move(result)](auto&& callback) mutable { - traverse_pack_async( - async_traverse_in_place_tag{}, - data_t{std::forward(callback), std::move(boxed)}); - }; + // The data from which the visitor is constructed in-place + using data_t = + seq::sequential_dispatch_data, + std::decay_t>; + + // The visitor type + using visitor_t = seq::sequential_dispatch_visitor; + + traverse_pack_async(async_traverse_in_place_tag{}, + data_t{std::forward(callback), + std::move(result)}); + }, + signature, std::move(ownership)); } }; } // namespace composition diff --git a/include/continuable/detail/composition.hpp b/include/continuable/detail/composition.hpp index 75adb14..eaabaf3 100644 --- a/include/continuable/detail/composition.hpp +++ b/include/continuable/detail/composition.hpp @@ -47,7 +47,7 @@ namespace detail { /// The namespace `composition` offers methods to chain continuations together /// with `all`, `any` or `seq` logic. namespace composition { - template +template struct is_composition_strategy // ... : std::false_type {}; @@ -133,13 +133,8 @@ auto finalize_composition(continuable_base&& continuation) { 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(); - // Return a new continuable which - return base::attorney::create(finalizer::finalize(std::move(composition)), - signature, std::move(ownership)); + return finalizer::finalize(std::move(composition), std::move(ownership)); } /// A base class from which the continuable may inherit in order to @@ -203,13 +198,7 @@ auto apply_composition(Strategy, Args&&... args) { auto composition = map_pack(prepare_continuables{ownership}, std::make_tuple(std::forward(args)...)); - // Retrieve the new signature hint - constexpr auto const signature = - finalizer::template hint(); - - // Return a new continuable which - return base::attorney::create(finalizer::finalize(std::move(composition)), - signature, std::move(ownership)); + return finalizer::finalize(std::move(composition), std::move(ownership)); } } // namespace composition } // namespace detail