diff --git a/include/continuable/detail/awaiting.hpp b/include/continuable/detail/awaiting.hpp index 1e59e7f..0974de8 100644 --- a/include/continuable/detail/awaiting.hpp +++ b/include/continuable/detail/awaiting.hpp @@ -68,7 +68,7 @@ class awaitable { typename trait_t::expected_type result_; public: - explicit awaitable(Continuable&& continuable) + explicit constexpr awaitable(Continuable&& continuable) : continuable_(std::move(continuable)) { } @@ -121,7 +121,7 @@ private: /// Converts a continuable into an awaitable object as described by /// the C++ coroutine TS. template -auto create_awaiter(T&& continuable) { +constexpr auto create_awaiter(T&& continuable) { return awaitable>(std::forward(continuable)); } } // namespace awaiting diff --git a/include/continuable/detail/base.hpp b/include/continuable/detail/base.hpp index 964a86d..b8ff045 100644 --- a/include/continuable/detail/base.hpp +++ b/include/continuable/detail/base.hpp @@ -171,7 +171,7 @@ invoker_of(traits::identity>) { using Type = decltype(attorney::materialize( std::declval>())); - auto constexpr const hint = hints::hint_of(traits::identity_of()); + auto constexpr const hint = hints::hint_of(traits::identify{}); return make_invoker( [](auto&& callback, auto&& next_callback, auto&&... args) { @@ -202,7 +202,7 @@ constexpr auto invoker_of(traits::identity) { std::move(result)); CONTINUABLE_BLOCK_TRY_END }, - traits::identity_of()); + traits::identify{}); } /// - void -> next_callback() @@ -322,8 +322,8 @@ struct result_handler_base(this)->callback_), std::move(args)...))>(); + auto result = traits::identify(this)->callback_), std::move(args)...))>{}; // Pick the correct invoker that handles decorating of the result auto invoker = decoration::invoker_of(result); @@ -478,7 +478,7 @@ next_hint_of(std::integral_constant, util::partial_invoke(std::declval(), std::declval()...)); // Return the hint of thr given invoker - return decoration::invoker_of(traits::identity_of()).hint(); + return decltype(decoration::invoker_of(traits::identify{}).hint()){}; } /// Don't progress the hint when we don't continue template @@ -506,9 +506,9 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback, "Expected a continuation!"); using Hint = decltype(hints::hint_of(traits::identity_of(continuation))); - auto next_hint = + constexpr auto next_hint = next_hint_of(std::integral_constant{}, - traits::identity_of(callback), Hint{}); + traits::identify{}, Hint{}); // TODO consume only the data here so the freeze isn't needed auto ownership_ = attorney::ownership_of(continuation); diff --git a/include/continuable/detail/composition.hpp b/include/continuable/detail/composition.hpp index 189065e..38a324b 100644 --- a/include/continuable/detail/composition.hpp +++ b/include/continuable/detail/composition.hpp @@ -170,7 +170,7 @@ class all_result_submitter : public std::enable_shared_from_this< void complete_one() { assert((left_ > 0U) && "Expected that the submitter isn't finished!"); - auto current = --left_; + auto const current = --left_; if (!current) { invoke(); } @@ -330,6 +330,14 @@ auto make_all_result_submitter(Callback&& callback, std::forward(callback)); } +/// A callable object to merge multiple signature hints together +struct entry_merger { + template + constexpr auto operator()(T&... entries) noexcept { + return traits::merge(hints::hint_of(traits::identity_of(entries))...); + } +}; + /// Finalizes the all logic of a given composition template auto finalize_composition( @@ -340,9 +348,7 @@ auto finalize_composition( auto composition = base::attorney::consume_data(std::move(continuation)); // Merge all signature hints together - auto signature = traits::unpack(composition, [](auto&... entries) { - return traits::merge(hints::hint_of(traits::identity_of(entries))...); - }); + constexpr auto signature = traits::unpack(composition, entry_merger{}); return base::attorney::create( [ signature, @@ -351,10 +357,10 @@ auto finalize_composition( // std::pair, size_constant> // ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ // Continuation pos Result pos - auto begin = std::make_pair(traits::size_constant_of<0>(), - traits::size_constant_of<0>()); - auto pack = traits::identity_of(composition); - auto end = traits::pack_size_of(pack); + constexpr auto begin = std::make_pair(traits::size_constant_of<0>(), + traits::size_constant_of<0>()); + constexpr auto pack = traits::identify{}; + constexpr auto end = traits::pack_size_of(pack); auto condition = [=](auto pos) { return pos.first < end; }; // Create the result submitter which caches all results and invokes @@ -368,11 +374,11 @@ auto finalize_composition( std::move(std::get(composition)); // This is the length of the arguments of the current continuable - auto arg_size = + constexpr auto arg_size = traits::pack_size_of(hints::hint_of(traits::identity_of(entry))); // The next position in the result tuple - auto next = current.second + arg_size; + constexpr auto next = current.second + arg_size; // Invoke the continuation with the associated submission callback base::attorney::invoke_continuation( @@ -395,7 +401,7 @@ auto make_any_result_submitter(Callback&& callback) { } template -T first_of(traits::identity) noexcept; +constexpr T first_of(traits::identity) noexcept; template constexpr auto common_result_of(Signature signature, diff --git a/include/continuable/detail/expected.hpp b/include/continuable/detail/expected.hpp index 3454001..18c81fa 100644 --- a/include/continuable/detail/expected.hpp +++ b/include/continuable/detail/expected.hpp @@ -387,7 +387,7 @@ struct expected_result_trait> { template using expected_result_trait_t = detail::expected_result_trait()))>; + hints::hint_of(traits::identify{}))>; } // namespace util } // namespace detail } // namespace cti diff --git a/include/continuable/detail/hints.hpp b/include/continuable/detail/hints.hpp index 5a9b4fe..2deac17 100644 --- a/include/continuable/detail/hints.hpp +++ b/include/continuable/detail/hints.hpp @@ -51,12 +51,12 @@ struct is_absent_hint : std::false_type {}; template <> struct is_absent_hint : std::true_type {}; - /// Returns the signature hint of the given continuable +/// Returns the signature hint of the given continuable template constexpr auto hint_of(traits::identity) { static_assert(traits::fail::value, "Expected a continuation with an existing signature hint!"); - return traits::identity_of(); + return traits::identity{}; } /// Returns the signature hint of the given continuable template diff --git a/include/continuable/detail/traits.hpp b/include/continuable/detail/traits.hpp index 067aaba..4deaf54 100644 --- a/include/continuable/detail/traits.hpp +++ b/include/continuable/detail/traits.hpp @@ -60,7 +60,7 @@ struct constant : std::integral_constant { /// \cond false #define CTI__INST(CTI__OP) \ template \ - /*constexpr*/ auto operator CTI__OP(std::integral_constant) \ + constexpr auto operator CTI__OP(std::integral_constant) \ const noexcept { \ return constant{}; \ @@ -68,7 +68,7 @@ struct constant : std::integral_constant { CTI__FOR_EACH_INTEGRAL_BIN_OP(CTI__INST) #undef CTI__INST #define CTI__INST(CTI__OP) \ - /*constexpr*/ auto operator CTI__OP() const noexcept { \ + constexpr auto operator CTI__OP() const noexcept { \ return constant{}; \ } CTI__FOR_EACH_INTEGRAL_UNA_OP(CTI__INST) @@ -81,14 +81,14 @@ struct constant : std::integral_constant { /// \cond false #define CTI__INST(CTI__OP) \ template \ - /*constexpr*/ auto operator CTI__OP(std::integral_constant) \ + constexpr auto operator CTI__OP(std::integral_constant) \ const noexcept { \ return constant{}; \ } CTI__FOR_EACH_BOOLEAN_BIN_OP(CTI__INST) #undef CTI__INST #define CTI__INST(CTI__OP) \ - /*constexpr*/ auto operator CTI__OP() const noexcept { \ + constexpr auto operator CTI__OP() const noexcept { \ return constant{}; \ } CTI__FOR_EACH_BOOLEAN_UNA_OP(CTI__INST) @@ -142,7 +142,7 @@ template struct is_identity> : std::true_type {}; template -identity> constexpr identity_of(T const& /*type*/) noexcept { +constexpr identity> identity_of(T const& /*type*/) noexcept { return {}; } template @@ -150,14 +150,12 @@ constexpr identity identity_of(identity /*type*/) noexcept { return {}; } template -constexpr auto identity_of() noexcept { - return std::conditional_t>::value, T, - identity>>{}; -} +using identify = std::conditional_t>::value, T, + identity>>; template constexpr auto get(identity) noexcept { - return identity_of>(); + return identify>{}; } namespace detail { @@ -327,9 +325,9 @@ constexpr auto unpack(F&& firstSequenceable, S&& secondSequenceable, } /// Calls the given unpacker with the content of the given sequenceable template -auto unpack(F&& firstSequenceable, U&& unpacker) { +constexpr auto unpack(F&& firstSequenceable, U&& unpacker) { return unpack(std::forward(firstSequenceable), std::forward(unpacker), - sequence_of(identity_of(firstSequenceable))); + sequence_of(identify{})); } /// Calls the given unpacker with the content of the given sequenceables template