diff --git a/include/continuable/detail/composition-seq.hpp b/include/continuable/detail/composition-seq.hpp index fbf832d..c907a9c 100644 --- a/include/continuable/detail/composition-seq.hpp +++ b/include/continuable/detail/composition-seq.hpp @@ -95,7 +95,11 @@ struct result_indexer_mapper { decltype(remapping::detail::result_extractor_mapper::initialize(hint)); using type = indexed_continuable, target>; - return type{std::forward(continuable), nullptr}; + + // We have to pass the continuables as l-value so we can move the whole pack + // afterwards as r-value, thus we move the continuable from a l-value here. + // NOLINTNEXTLINE(misc-move-forwarding-reference) + return type{std::move(continuable), nullptr}; } }; diff --git a/include/continuable/detail/composition.hpp b/include/continuable/detail/composition.hpp index 91e3f4e..341c100 100644 --- a/include/continuable/detail/composition.hpp +++ b/include/continuable/detail/composition.hpp @@ -159,23 +159,27 @@ auto finalize_composition(continuable_base&& continuation) { signature, std::move(ownership)); } -struct consume_ownership { +struct prepare_continuables { util::ownership& ownership_; template >::value>* = nullptr> - void operator()(Continuable&& continuable) noexcept { - util::ownership other = base::attorney::ownership_of(continuable); + auto operator()(Continuable&& continuable) noexcept { + util::ownership current = base::attorney::ownership_of(continuable); + assert(current.is_acquired() && + "Only valid continuables should be passed!"); - assert(other.is_acquired() && "Only valid continuables should be passed!"); - - if (!ownership_.is_frozen() && other.is_frozen()) { + // Propagate a frozen state to the new continuable + if (!ownership_.is_frozen() && current.is_frozen()) { ownership_.freeze(); } // Freeze the continuable since it is stored for later usage continuable.freeze(); + + // Materialize every continuable + return base::attorney::materialize(std::forward(continuable)); } }; @@ -183,18 +187,18 @@ template auto apply_composition(Strategy, Args&&... args) { using finalizer = composition_finalizer; - auto composition = std::make_tuple(std::forward(args)...); - - // Retrieve the new signature hint - constexpr auto const signature = - finalizer::template hint(); - // Freeze every continuable inside the given arguments, // and freeze the ownership if one of the continuables // is frozen already. // Additionally test whether every continuable is acquired. + // Also materialize every continuable. util::ownership ownership; - traverse_pack(consume_ownership{ownership}, std::move(composition)); + 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)),