Adapt the small functor capacity to hold a ready continuable at zero cost

This commit is contained in:
Denis Blank 2018-12-08 01:26:14 +01:00
parent da8ec15c6f
commit b293d9a342
4 changed files with 41 additions and 44 deletions

View File

@ -849,7 +849,7 @@ constexpr auto make_continuable(Continuation&& continuation) {
return detail::base::attorney::create_from( return detail::base::attorney::create_from(
std::forward<Continuation>(continuation), std::forward<Continuation>(continuation),
detail::hints::extract(detail::traits::identity<Args...>{}), detail::hints::from_explicit(detail::traits::identity<Args...>{}),
detail::util::ownership{}); detail::util::ownership{});
} }
@ -864,41 +864,22 @@ constexpr auto make_continuable(Continuation&& continuation) {
/// ///
/// \since 3.0.0 /// \since 3.0.0
template <typename... Args> template <typename... Args>
constexpr auto make_ready_continuable() { auto make_ready_continuable() {
return make_continuable<void>([](auto&& promise) { static_assert(
std::forward<decltype(promise)>(promise).set_value(); sizeof...(Args) == 0,
}); "make_ready_continuable with void continuables requires zero args!");
return make_continuable<void>(detail::base::ready_continuable<>());
} }
/// Returns a continuable_base with one result value which instantly resolves /// Returns a continuable_base with one result value which instantly resolves
/// the promise with the given value. /// the promise with the given value.
/// ///
/// \copydetails make_ready_continuable() /// \copydetails make_ready_continuable()
template <typename Result> template <typename... Args>
constexpr auto make_ready_continuable(Result&& result) { auto make_ready_continuable(Args&&... args) {
return make_continuable<std::decay_t<Result>>( // ... return make_continuable<std::decay_t<Args>...>(
[result = std::forward<Result>(result)](auto&& promise) mutable { detail::base::ready_continuable<std::decay_t<Args>...>(
std::forward<decltype(promise)>(promise).set_value(std::move(result)); std::forward<Args>(args)));
});
}
/// Returns a continuable_base with multiple result values which instantly
/// resolves the promise with the given values.
///
/// \copydetails make_ready_continuable()
template <typename FirstResult, typename SecondResult, typename... Rest>
constexpr auto make_ready_continuable(FirstResult&& first_result,
SecondResult&& second_result,
Rest&&... rest) {
return make_continuable<std::decay_t<FirstResult>, std::decay_t<SecondResult>,
std::decay_t<Rest>...>( // ...
[result = std::make_tuple(std::forward<FirstResult>(first_result),
std::forward<SecondResult>(second_result),
std::forward<Rest>(rest)...)](
auto&& promise) mutable {
detail::traits::unpack(std::forward<decltype(promise)>(promise),
std::move(result));
});
} }
/// Returns a continuable_base with the parameterized result which instantly /// Returns a continuable_base with the parameterized result which instantly

View File

@ -32,8 +32,8 @@
#define CONTINUABLE_TRAIT_HPP_INCLUDED #define CONTINUABLE_TRAIT_HPP_INCLUDED
#include <cstddef> #include <cstddef>
#include <continuable/continuable-primitives.hpp>
#include <continuable/continuable-base.hpp> #include <continuable/continuable-base.hpp>
#include <continuable/continuable-primitives.hpp>
#include <continuable/continuable-promise-base.hpp> #include <continuable/continuable-promise-base.hpp>
#include <continuable/detail/core/annotation.hpp> #include <continuable/detail/core/annotation.hpp>
#include <continuable/detail/core/types.hpp> #include <continuable/detail/core/types.hpp>
@ -61,18 +61,17 @@ template <template <std::size_t, typename...> class CallbackWrapper,
class continuable_trait { class continuable_trait {
using callback = CallbackWrapper<0U, void(Args...)&&, using callback = CallbackWrapper<0U, void(Args...)&&,
void(exception_arg_t, void(exception_arg_t, exception_t) &&>;
exception_t) &&>;
public: public:
/// The promise type which is used to resolve continuations /// The promise type which is used to resolve continuations
using promise = using promise = promise_base<callback, detail::traits::identity<Args...>>;
promise_base<callback, detail::traits::identity<Args...>>;
/// The continuable type for the given parameters. /// The continuable type for the given parameters.
using continuable = using continuable = continuable_base<
continuable_base<ContinuationWrapper<sizeof(callback), void(promise)>, ContinuationWrapper<sizeof(detail::base::ready_continuable<Args...>),
detail::traits::identity<Args...>>; void(promise)>,
detail::traits::identity<Args...>>;
}; };
/// \} /// \}
} // namespace cti } // namespace cti

View File

@ -54,13 +54,13 @@ namespace hints {
/// ///
/// This is the overload taking an arbitrary amount of args /// This is the overload taking an arbitrary amount of args
template <typename... HintArgs> template <typename... HintArgs>
constexpr auto extract(traits::identity<HintArgs...> hint) { constexpr auto from_explicit(traits::identity<HintArgs...> hint) {
return hint; return hint;
} }
/// \copybrief extract /// \copybrief from_explicit
/// ///
/// This is the overload taking a void arg. /// This is the overload taking a void arg.
constexpr auto extract(traits::identity<void> /*hint*/) { constexpr auto from_explicit(traits::identity<void> /*hint*/) {
return traits::identity<>{}; return traits::identity<>{};
} }
} // namespace hints } // namespace hints

View File

@ -69,23 +69,40 @@ struct is_continuable : std::false_type {};
template <typename Data, typename Annotation> template <typename Data, typename Annotation>
struct is_continuable<continuable_base<Data, Annotation>> : std::true_type {}; struct is_continuable<continuable_base<Data, Annotation>> : std::true_type {};
/*template <typename... Args> template <typename... Args>
struct ready_continuable { struct ready_continuable {
std::tuple<Args...> values_; std::tuple<Args...> values_;
explicit ready_continuable(Args... values) : values_(std::move(values)) {
}
template <typename Callback> template <typename Callback>
void operator()(Callback&& callback) && { void operator()(Callback&& callback) && {
traits::unpack(std::forward<Callback>(callback), std::move(values_)); traits::unpack(std::forward<Callback>(callback), std::move(values_));
} }
bool operator()(is_ready_arg_t) const noexcept { /*bool operator()(is_ready_arg_t) const noexcept {
return true; return true;
} }
std::tuple<Args...> operator()(get_arg_t) && { std::tuple<Args...> operator()(get_arg_t) && {
return std::move(values_); return std::move(values_);
}*/
};
template <>
struct ready_continuable<> {
template <typename Callback>
void operator()(Callback&& callback) && {
util::invoke(std::forward<Callback>(callback));
} }
};*/
/*bool operator()(is_ready_arg_t) const noexcept {
return true;
}
void operator()(get_arg_t) && {
}*/
};
/*template <typename Continuation, typename Args> /*template <typename Continuation, typename Args>
struct proxy_continuable : Continuation { struct proxy_continuable : Continuation {