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(
std::forward<Continuation>(continuation),
detail::hints::extract(detail::traits::identity<Args...>{}),
detail::hints::from_explicit(detail::traits::identity<Args...>{}),
detail::util::ownership{});
}
@ -864,41 +864,22 @@ constexpr auto make_continuable(Continuation&& continuation) {
///
/// \since 3.0.0
template <typename... Args>
constexpr auto make_ready_continuable() {
return make_continuable<void>([](auto&& promise) {
std::forward<decltype(promise)>(promise).set_value();
});
auto make_ready_continuable() {
static_assert(
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
/// the promise with the given value.
///
/// \copydetails make_ready_continuable()
template <typename Result>
constexpr auto make_ready_continuable(Result&& result) {
return make_continuable<std::decay_t<Result>>( // ...
[result = std::forward<Result>(result)](auto&& promise) mutable {
std::forward<decltype(promise)>(promise).set_value(std::move(result));
});
}
/// 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));
});
template <typename... Args>
auto make_ready_continuable(Args&&... args) {
return make_continuable<std::decay_t<Args>...>(
detail::base::ready_continuable<std::decay_t<Args>...>(
std::forward<Args>(args)));
}
/// Returns a continuable_base with the parameterized result which instantly

View File

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

View File

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

View File

@ -69,23 +69,40 @@ struct is_continuable : std::false_type {};
template <typename Data, typename Annotation>
struct is_continuable<continuable_base<Data, Annotation>> : std::true_type {};
/*template <typename... Args>
template <typename... Args>
struct ready_continuable {
std::tuple<Args...> values_;
explicit ready_continuable(Args... values) : values_(std::move(values)) {
}
template <typename Callback>
void operator()(Callback&& callback) && {
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;
}
std::tuple<Args...> operator()(get_arg_t) && {
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>
struct proxy_continuable : Continuation {