From 3df06820ef4859b2d12ca4e99554a83544e8b185 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Mon, 12 Mar 2018 08:02:43 +0100 Subject: [PATCH] Make the seq dependency only dependent from the aggregate header --- doc/installation.dox | 3 + ...mapping.hpp => composition-aggregated.hpp} | 53 ++++++++++++++++- .../continuable/detail/composition-all.hpp | 59 ++----------------- .../continuable/detail/composition-seq.hpp | 15 ++--- 4 files changed, 65 insertions(+), 65 deletions(-) rename include/continuable/detail/{composition-remapping.hpp => composition-aggregated.hpp} (81%) diff --git a/doc/installation.dox b/doc/installation.dox index 1e546d3..e0dff0a 100644 --- a/doc/installation.dox +++ b/doc/installation.dox @@ -38,6 +38,9 @@ following compilers: Although the build is observed with the listed compilers earlier versions might work. +\warning GCC is proven to be slower than Clang in template compilation and + thus it is suggested to use Clang instead. + \section installation-dependencies Dependencies Continuable is a header-only library with one required header-only dependency: diff --git a/include/continuable/detail/composition-remapping.hpp b/include/continuable/detail/composition-aggregated.hpp similarity index 81% rename from include/continuable/detail/composition-remapping.hpp rename to include/continuable/detail/composition-aggregated.hpp index afd68cb..dc24ddc 100644 --- a/include/continuable/detail/composition-remapping.hpp +++ b/include/continuable/detail/composition-aggregated.hpp @@ -54,7 +54,7 @@ namespace composition { /// - value -> value /// - single async value -> single value /// - multiple async value -> tuple of async values. -namespace remapping { +namespace aggregated { /// Guards a type to be default constructible, /// and wraps it into an optional type if it isn't default constructible. template @@ -220,7 +220,56 @@ void finalize_data(Callback&& callback, Data&& data) { std::forward(callback), std::forward(data)); } -} // namespace remapping + +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{}; +} + +} // namespace aggregated } // namespace composition } // namespace detail } // namespace cti diff --git a/include/continuable/detail/composition-all.hpp b/include/continuable/detail/composition-all.hpp index d7cdb5c..91e466c 100644 --- a/include/continuable/detail/composition-all.hpp +++ b/include/continuable/detail/composition-all.hpp @@ -39,7 +39,7 @@ #include #include -#include +#include #include #include #include @@ -49,55 +49,6 @@ namespace cti { namespace detail { namespace composition { namespace all { -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 remapping::unpack_lazy(remapping::lazy_value_t{}); - } - - template - static constexpr auto - deduce(hints::signature_hint_tag) { - return spread_this( - remapping::unpack_lazy(remapping::lazy_value_t{}), - remapping::unpack_lazy(remapping::lazy_value_t{}), - remapping::unpack_lazy(remapping::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{}; -} - /// Caches the partial results and invokes the callback when all results /// are arrived. This class is thread safe. template @@ -118,7 +69,7 @@ class result_submitter // Call the final callback with the cleaned result std::call_once(flag_, [&] { - remapping::finalize_data(std::move(callback_), std::move(result_)); + aggregated::finalize_data(std::move(callback_), std::move(result_)); }); } @@ -185,7 +136,7 @@ template struct continuable_dispatcher { std::shared_ptr& submitter; - template >::value>* = nullptr> void operator()(Box&& box) const { // Retrieve a callback from the submitter and attach it to the continuable @@ -199,7 +150,7 @@ template <> struct composition_finalizer { template static constexpr auto hint() { - return decltype(all::deduce_hint(std::declval())){}; + return decltype(aggregated::deduce_hint(std::declval())){}; } /// Finalizes the all logic of a given composition @@ -209,7 +160,7 @@ struct composition_finalizer { (auto&& callback) mutable { // Create the target result from the composition - auto result = remapping::box_continuables(std::move(composition)); + auto result = aggregated::box_continuables(std::move(composition)); using submitter_t = all::result_submitter, diff --git a/include/continuable/detail/composition-seq.hpp b/include/continuable/detail/composition-seq.hpp index 522673d..adc4573 100644 --- a/include/continuable/detail/composition-seq.hpp +++ b/include/continuable/detail/composition-seq.hpp @@ -39,8 +39,7 @@ #include #include -#include -#include +#include #include #include @@ -93,7 +92,7 @@ public: return data_.box; } - template >::value>* = nullptr> bool operator()(async_traverse_visit_tag, Box&& /*box*/) { return false; @@ -121,8 +120,8 @@ public: template void operator()(async_traverse_complete_tag, T&& /*pack*/) { - return remapping::finalize_data(std::move(data_.callback), - std::move(data_.box)); + return aggregated::finalize_data(std::move(data_.callback), + std::move(data_.box)); } }; } // namespace seq @@ -132,9 +131,7 @@ template <> struct composition_finalizer { template static constexpr auto hint() { - // The result is the same as in the all composition - using all_finalizer = composition_finalizer; - return all_finalizer::hint(); + return decltype(aggregated::deduce_hint(std::declval())){}; } /// Finalizes the all logic of a given composition @@ -143,7 +140,7 @@ struct composition_finalizer { return [composition = std::forward(composition)] // ... (auto&& callback) mutable { - auto boxed = remapping::box_continuables(std::move(composition)); + auto boxed = aggregated::box_continuables(std::move(composition)); // The data from which the visitor is constructed in-place using data_t =