Commit 1a1bb9d7 authored by Eric Niebler's avatar Eric Niebler Committed by Facebook Github Bot

executor wrappers don't take extra schedule parameters

Summary: The type-erasing executor wrappers and the generic executor wrappers accept extra parameters to their `schedule` member functions, but nowhere is that functionality used, and such executor types would fail to satisfy the Executor concepts anyway. Remove that functionality.

Reviewed By: kirkshoop

Differential Revision: D14541290

fbshipit-source-id: 8cf0fd7bdc6dea72e43d5decc9e70ba843ab2db8
parent 38694971
...@@ -34,11 +34,11 @@ using not_is_t = std::enable_if_t<!is_v<std::decay_t<T>, C>, std::decay_t<T>>; ...@@ -34,11 +34,11 @@ using not_is_t = std::enable_if_t<!is_v<std::decay_t<T>, C>, std::decay_t<T>>;
// //
// define types for executors // define types for executors
template <class E, class... VN> template <class E>
class any_executor { class any_executor {
union data { union data {
void* pobj_ = nullptr; void* pobj_ = nullptr;
std::aligned_union_t< 0, std::tuple<VN...> > buffer_; std::aligned_storage_t< 2 * sizeof(void*) > buffer_;
} data_{}; } data_{};
template <class Wrapped> template <class Wrapped>
static constexpr bool insitu() { static constexpr bool insitu() {
...@@ -48,10 +48,10 @@ class any_executor { ...@@ -48,10 +48,10 @@ class any_executor {
struct vtable { struct vtable {
static void s_op(data&, data*) {} static void s_op(data&, data*) {}
static void s_consume_op(data&&, data*) {} static void s_consume_op(data&&, data*) {}
static any_single_sender<E, any_executor_ref<E>> s_schedule(data&, VN...) { return {}; } static any_single_sender<E, any_executor_ref<E>> s_schedule(data&) { return {}; }
void (*op_)(data&, data*) = vtable::s_op; void (*op_)(data&, data*) = vtable::s_op;
void (*consume_op_)(data&, data*) = vtable::s_consume_op; void (*consume_op_)(data&, data*) = vtable::s_consume_op;
any_single_sender<E, any_executor_ref<E>> (*schedule_)(data&, VN...) = vtable::s_schedule; any_single_sender<E, any_executor_ref<E>> (*schedule_)(data&) = vtable::s_schedule;
}; };
static constexpr vtable const noop_{}; static constexpr vtable const noop_{};
vtable const* vptr_ = &noop_; vtable const* vptr_ = &noop_;
...@@ -66,9 +66,9 @@ class any_executor { ...@@ -66,9 +66,9 @@ class any_executor {
dst->pobj_ = std::exchange(src.pobj_, nullptr); dst->pobj_ = std::exchange(src.pobj_, nullptr);
delete static_cast<Wrapped const*>(src.pobj_); delete static_cast<Wrapped const*>(src.pobj_);
} }
static any_single_sender<E, any_executor_ref<E>> schedule(data& src, VN... vn) { static any_single_sender<E, any_executor_ref<E>> schedule(data& src) {
return any_single_sender<E, any_executor_ref<E>>{::folly::pushmi::schedule( return any_single_sender<E, any_executor_ref<E>>{::folly::pushmi::schedule(
*static_cast<Wrapped*>(src.pobj_), vn...)}; *static_cast<Wrapped*>(src.pobj_))};
} }
}; };
static const vtable vtbl{s::op, s::consume_op, s::schedule}; static const vtable vtbl{s::op, s::consume_op, s::schedule};
...@@ -89,9 +89,9 @@ class any_executor { ...@@ -89,9 +89,9 @@ class any_executor {
Wrapped(std::move(*static_cast<Wrapped*>((void*)src.buffer_))); Wrapped(std::move(*static_cast<Wrapped*>((void*)src.buffer_)));
static_cast<Wrapped const*>((void*)src.buffer_)->~Wrapped(); static_cast<Wrapped const*>((void*)src.buffer_)->~Wrapped();
} }
static any_single_sender<E, any_executor_ref<E>> schedule(data& src, VN... vn) { static any_single_sender<E, any_executor_ref<E>> schedule(data& src) {
return any_single_sender<E, any_executor_ref<E>>{::folly::pushmi::schedule( return any_single_sender<E, any_executor_ref<E>>{::folly::pushmi::schedule(
*static_cast<Wrapped*>((void*)src.buffer_), vn...)}; *static_cast<Wrapped*>((void*)src.buffer_))};
} }
}; };
static const vtable vtbl{s::op, s::consume_op, s::schedule}; static const vtable vtbl{s::op, s::consume_op, s::schedule};
...@@ -132,20 +132,15 @@ class any_executor { ...@@ -132,20 +132,15 @@ class any_executor {
new ((void*)this) any_executor(std::move(that)); new ((void*)this) any_executor(std::move(that));
return *this; return *this;
} }
PUSHMI_TEMPLATE(class... AN) any_single_sender<E, any_executor_ref<E>> schedule() {
(requires sizeof...(VN) == sizeof...(AN)) // return vptr_->schedule_(data_);
any_single_sender<E, any_executor_ref<E>> schedule(AN&&... an) {
// moved this check out of the requires due to a
// mismatched pack size between VN and AN on gcc.
static_assert(And<Constructible<VN, AN>...>, "arguments must be convertible");
return vptr_->schedule_(data_, VN{(AN &&) an}...);
} }
}; };
// Class static definitions: // Class static definitions:
template <class E, class... VN> template <class E>
constexpr typename any_executor<E, VN...>::vtable const constexpr typename any_executor<E>::vtable const
any_executor<E, VN...>::noop_; any_executor<E>::noop_;
template <class SF> template <class SF>
class executor<SF> { class executor<SF> {
...@@ -157,11 +152,10 @@ class executor<SF> { ...@@ -157,11 +152,10 @@ class executor<SF> {
constexpr executor() = default; constexpr executor() = default;
constexpr explicit executor(SF sf) : sf_(std::move(sf)) {} constexpr explicit executor(SF sf) : sf_(std::move(sf)) {}
PUSHMI_TEMPLATE(class... AN) PUSHMI_TEMPLATE(class SF_ = SF)
(requires PUSHMI_EXP( (requires Invocable<SF_&>) //
lazy::Invocable<SF&, AN...>)) // auto schedule() {
auto schedule(AN&&... an) { return sf_();
return sf_((AN&&)an...);
} }
}; };
...@@ -182,11 +176,10 @@ class executor<Data, DSF> { ...@@ -182,11 +176,10 @@ class executor<Data, DSF> {
constexpr executor(Data data, DSF sf) constexpr executor(Data data, DSF sf)
: data_(std::move(data)), sf_(std::move(sf)) {} : data_(std::move(data)), sf_(std::move(sf)) {}
PUSHMI_TEMPLATE(class... AN) PUSHMI_TEMPLATE(class DSF_ = DSF)
(requires PUSHMI_EXP( (requires Invocable<DSF_&, Data&>) //
lazy::Invocable<DSF&, Data&, AN...>)) // auto schedule() {
auto schedule(AN&&... an) { return sf_(data_);
return sf_(data_, (AN&&)an...);
} }
}; };
...@@ -252,13 +245,13 @@ template <class T> ...@@ -252,13 +245,13 @@ template <class T>
using not_any_executor_ref_t = not_is_t<T, any_executor_ref>; using not_any_executor_ref_t = not_is_t<T, any_executor_ref>;
} // namespace detail } // namespace detail
template <class E, class... VN> template <class E>
struct any_executor_ref { struct any_executor_ref {
private: private:
using This = any_executor_ref; using This = any_executor_ref;
void* pobj_; void* pobj_;
struct vtable { struct vtable {
any_single_sender<E, any_executor_ref<E>> (*schedule_)(void*, VN...); any_single_sender<E, any_executor_ref<E>> (*schedule_)(void*);
} const* vptr_; } const* vptr_;
template <class T> template <class T>
using wrapped_t = detail::not_any_executor_ref_t<T>; using wrapped_t = detail::not_any_executor_ref_t<T>;
...@@ -273,9 +266,9 @@ struct any_executor_ref { ...@@ -273,9 +266,9 @@ struct any_executor_ref {
(requires Executor<wrapped_t<Wrapped>>) // (requires Executor<wrapped_t<Wrapped>>) //
any_executor_ref(Wrapped& w) { any_executor_ref(Wrapped& w) {
struct s { struct s {
static any_single_sender<E, any_executor_ref<E>> schedule(void* pobj, VN... vn) { static any_single_sender<E, any_executor_ref<E>> schedule(void* pobj) {
return any_single_sender<E, any_executor_ref<E>>{ return any_single_sender<E, any_executor_ref<E>>{
::folly::pushmi::schedule(*static_cast<Wrapped*>(pobj), vn...)}; ::folly::pushmi::schedule(*static_cast<Wrapped*>(pobj))};
} }
}; };
static const vtable vtbl{s::schedule}; static const vtable vtbl{s::schedule};
...@@ -283,8 +276,8 @@ struct any_executor_ref { ...@@ -283,8 +276,8 @@ struct any_executor_ref {
vptr_ = &vtbl; vptr_ = &vtbl;
} }
template<class... AN> template<class... AN>
any_single_sender<E, any_executor_ref<E>> schedule(AN&&... an) { any_single_sender<E, any_executor_ref<E>> schedule() {
return vptr_->schedule_(pobj_, VN{(AN&&)an}...); return vptr_->schedule_(pobj_);
} }
}; };
...@@ -316,28 +309,36 @@ PUSHMI_TEMPLATE(class Wrapped) ...@@ -316,28 +309,36 @@ PUSHMI_TEMPLATE(class Wrapped)
// define types for constrained executors // define types for constrained executors
template <class E, class CV, class... VN> template <class E, class CV>
class any_constrained_executor { class any_constrained_executor {
union data { union data {
void* pobj_ = nullptr; void* pobj_ = nullptr;
std::aligned_union_t< 0, std::tuple<CV, VN...> > buffer_; std::aligned_storage_t< 2 * sizeof(void*) > buffer_;
} data_{}; } data_{};
template <class Wrapped> template <class Wrapped>
static constexpr bool insitu() { static constexpr bool insitu() {
return sizeof(Wrapped) <= sizeof(data::buffer_) && return sizeof(Wrapped) <= sizeof(data::buffer_) &&
std::is_nothrow_move_constructible<Wrapped>::value; std::is_nothrow_move_constructible<Wrapped>::value;
} }
using exec_ref = any_constrained_executor_ref<E>;
struct vtable { struct vtable {
static void s_op(data&, data*) {} static void s_op(data&, data*) {}
static void s_consume_op(data&&, data*) {} static void s_consume_op(data&&, data*) {}
static any_single_sender<E, any_constrained_executor_ref<E>> s_schedule(data&, VN...) { std::terminate(); return {}; } static any_single_sender<E, exec_ref> s_schedule(data&) {
static any_single_sender<E, any_constrained_executor_ref<E>> s_schedule_cv(data&, CV, VN...) { std::terminate(); return {}; } std::terminate();
return {};
}
static any_single_sender<E, exec_ref> s_schedule_cv(data&, CV) {
std::terminate();
return {};
}
static CV s_top(data&) { return {}; } static CV s_top(data&) { return {}; }
void (*op_)(data&, data*) = vtable::s_op; void (*op_)(data&, data*) = vtable::s_op;
void (*consume_op_)(data&&, data*) = vtable::s_consume_op; void (*consume_op_)(data&&, data*) = vtable::s_consume_op;
CV (*top_)(data&) = vtable::s_top; CV (*top_)(data&) = vtable::s_top;
any_single_sender<E, any_constrained_executor_ref<E>> (*schedule_)(data&, VN...) = vtable::s_schedule; any_single_sender<E, exec_ref> (*schedule_)(data&) = vtable::s_schedule;
any_single_sender<E, any_constrained_executor_ref<E>> (*schedule_cv_)(data&, CV, VN...) = vtable::s_schedule_cv; any_single_sender<E, exec_ref> (*schedule_cv_)(data&, CV) =
vtable::s_schedule_cv;
}; };
static constexpr vtable const noop_{}; static constexpr vtable const noop_{};
vtable const* vptr_ = &noop_; vtable const* vptr_ = &noop_;
...@@ -355,16 +356,22 @@ class any_constrained_executor { ...@@ -355,16 +356,22 @@ class any_constrained_executor {
static CV top(data& src) { static CV top(data& src) {
return ::folly::pushmi::top(*static_cast<Wrapped*>(src.pobj_)); return ::folly::pushmi::top(*static_cast<Wrapped*>(src.pobj_));
} }
static any_single_sender<E, any_constrained_executor_ref<E>> schedule(data& src, VN... vn) { static any_single_sender<E, exec_ref> schedule(data& src) {
return any_single_sender<E, any_constrained_executor_ref<E>>{::folly::pushmi::schedule( return any_single_sender<E, exec_ref>{::folly::pushmi::schedule(
*static_cast<Wrapped*>(src.pobj_), vn...)}; *static_cast<Wrapped*>(src.pobj_))};
} }
static any_single_sender<E, any_constrained_executor_ref<E>> schedule_cv(data& src, CV cv, VN... vn) { static any_single_sender<E, exec_ref> schedule_cv(data& src, CV cv) {
return any_single_sender<E, any_constrained_executor_ref<E>>{::folly::pushmi::schedule( return any_single_sender<E, exec_ref>{::folly::pushmi::schedule(
*static_cast<Wrapped*>(src.pobj_), cv, vn...)}; *static_cast<Wrapped*>(src.pobj_), cv)};
} }
}; };
static const vtable vtbl{s::op, s::consume_op, s::top, s::schedule, s::schedule_cv}; static const vtable vtbl{
s::op,
s::consume_op,
s::top,
s::schedule,
s::schedule_cv
};
data_.pobj_ = new Wrapped(std::move(obj)); data_.pobj_ = new Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
...@@ -385,16 +392,22 @@ class any_constrained_executor { ...@@ -385,16 +392,22 @@ class any_constrained_executor {
static CV top(data& src) { static CV top(data& src) {
return ::folly::pushmi::top(*static_cast<Wrapped*>((void*)src.buffer_)); return ::folly::pushmi::top(*static_cast<Wrapped*>((void*)src.buffer_));
} }
static any_single_sender<E, any_constrained_executor_ref<E>> schedule(data& src, VN... vn) { static any_single_sender<E, exec_ref> schedule(data& src) {
return any_single_sender<E, any_constrained_executor_ref<E>>{::folly::pushmi::schedule( return any_single_sender<E, exec_ref>{::folly::pushmi::schedule(
*static_cast<Wrapped*>((void*)src.buffer_), vn...)}; *static_cast<Wrapped*>((void*)src.buffer_))};
} }
static any_single_sender<E, any_constrained_executor_ref<E>> schedule_cv(data& src, CV cv, VN... vn) { static any_single_sender<E, exec_ref> schedule_cv(data& src, CV cv) {
return any_single_sender<E, any_constrained_executor_ref<E>>{::folly::pushmi::schedule( return any_single_sender<E, exec_ref>{::folly::pushmi::schedule(
*static_cast<Wrapped*>((void*)src.buffer_), cv, vn...)}; *static_cast<Wrapped*>((void*)src.buffer_), cv)};
} }
}; };
static const vtable vtbl{s::op, s::consume_op, s::top, s::schedule}; static const vtable vtbl{
s::op,
s::consume_op,
s::top,
s::schedule,
s::schedule_cv
};
new (data_.buffer_) Wrapped(std::move(obj)); new (data_.buffer_) Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
...@@ -406,11 +419,13 @@ class any_constrained_executor { ...@@ -406,11 +419,13 @@ class any_constrained_executor {
using properties = property_set<is_constrained<>>; using properties = property_set<is_constrained<>>;
any_constrained_executor() = default; any_constrained_executor() = default;
any_constrained_executor(const any_constrained_executor& that) noexcept : any_constrained_executor() { any_constrained_executor(const any_constrained_executor& that) noexcept
: any_constrained_executor() {
that.vptr_->op_(that.data_, &data_); that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_); std::swap(that.vptr_, vptr_);
} }
any_constrained_executor(any_constrained_executor&& that) noexcept : any_constrained_executor() { any_constrained_executor(any_constrained_executor&& that) noexcept
: any_constrained_executor() {
that.vptr_->consume_op_(std::move(that.data_), &data_); that.vptr_->consume_op_(std::move(that.data_), &data_);
std::swap(that.vptr_, vptr_); std::swap(that.vptr_, vptr_);
} }
...@@ -435,22 +450,18 @@ class any_constrained_executor { ...@@ -435,22 +450,18 @@ class any_constrained_executor {
CV top() { CV top() {
return vptr_->top_(data_); return vptr_->top_(data_);
} }
PUSHMI_TEMPLATE(class... AN) any_single_sender<E, any_constrained_executor_ref<E>> schedule() {
(requires And<Constructible<VN, AN>...>) return vptr_->schedule_(data_);
any_single_sender<E, any_constrained_executor_ref<E>> schedule(AN&&... an) {
return vptr_->schedule_(data_, VN{(AN &&) an}...);
} }
PUSHMI_TEMPLATE(class... AN) any_single_sender<E, any_constrained_executor_ref<E>> schedule(CV cv) {
(requires And<Constructible<VN, AN>...>) return vptr_->schedule_cv_(data_, cv);
any_single_sender<E, any_constrained_executor_ref<E>> schedule(CV cv, AN&&... an) {
return vptr_->schedule_cv_(data_, cv, VN{(AN &&) an}...);
} }
}; };
// Class static definitions: // Class static definitions:
template <class E, class CV, class... VN> template <class E, class CV>
constexpr typename any_constrained_executor<E, CV, VN...>::vtable const constexpr typename any_constrained_executor<E, CV>::vtable const
any_constrained_executor<E, CV, VN...>::noop_; any_constrained_executor<E, CV>::noop_;
template <class SF, class ZF> template <class SF, class ZF>
class constrained_executor<SF, ZF> { class constrained_executor<SF, ZF> {
...@@ -468,11 +479,10 @@ class constrained_executor<SF, ZF> { ...@@ -468,11 +479,10 @@ class constrained_executor<SF, ZF> {
return zf_(); return zf_();
} }
PUSHMI_TEMPLATE(class... AN) PUSHMI_TEMPLATE(class SF_ = SF)
(requires PUSHMI_EXP( (requires Invocable<SF_&>) //
lazy::Invocable<SF&, AN...>)) // auto schedule() {
auto schedule(AN&&... an) { return sf_();
return sf_((AN&&)an...);
} }
}; };
...@@ -501,11 +511,10 @@ class constrained_executor<Data, DSF, DZF> { ...@@ -501,11 +511,10 @@ class constrained_executor<Data, DSF, DZF> {
return zf_(data_); return zf_(data_);
} }
PUSHMI_TEMPLATE(class... AN) PUSHMI_TEMPLATE(class DSF_ = DSF)
(requires PUSHMI_EXP( (requires Invocable<DSF_&, Data&>) //
lazy::Invocable<DSF&, Data&, AN...>)) // auto schedule() {
auto schedule(AN&&... an) { return sf_(data_);
return sf_(data_, (AN&&)an...);
} }
}; };
...@@ -593,17 +602,16 @@ using not_any_constrained_executor_ref_t = ...@@ -593,17 +602,16 @@ using not_any_constrained_executor_ref_t =
not_is_t<T, any_constrained_executor_ref>; not_is_t<T, any_constrained_executor_ref>;
} // namespace detail } // namespace detail
template <class E, class CV, class... VN> template <class E, class CV>
struct any_constrained_executor_ref { struct any_constrained_executor_ref {
private: private:
using This = any_constrained_executor_ref; using This = any_constrained_executor_ref;
void* pobj_; void* pobj_;
using exec_ref = any_constrained_executor_ref<E, CV>;
struct vtable { struct vtable {
CV (*top_)(void*); CV (*top_)(void*);
any_single_sender<E, CV, any_constrained_executor_ref<E, CV>> (*schedule_)( any_single_sender<E, CV, exec_ref> (*schedule_)(void*);
void*, VN...); any_single_sender<E, CV, exec_ref> (*schedule_cv_)(void*, CV);
any_single_sender<E, CV, any_constrained_executor_ref<E, CV>> (
*schedule_cv_)(void*, CV, VN...);
} const* vptr_; } const* vptr_;
template <class T> template <class T>
using wrapped_t = detail::not_any_constrained_executor_ref_t<T>; using wrapped_t = detail::not_any_constrained_executor_ref_t<T>;
...@@ -621,15 +629,13 @@ struct any_constrained_executor_ref { ...@@ -621,15 +629,13 @@ struct any_constrained_executor_ref {
static CV top(void* pobj) { static CV top(void* pobj) {
return ::folly::pushmi::top(*static_cast<Wrapped*>(pobj)); return ::folly::pushmi::top(*static_cast<Wrapped*>(pobj));
} }
static any_single_sender<E, CV, any_constrained_executor_ref<E, CV>> static any_single_sender<E, CV, exec_ref> schedule(void* pobj) {
schedule(void* pobj, VN... vn) {
return ::folly::pushmi::schedule( return ::folly::pushmi::schedule(
*static_cast<Wrapped*>(pobj), *static_cast<Wrapped*>(pobj),
::folly::pushmi::top(*static_cast<Wrapped*>(pobj)), vn...); ::folly::pushmi::top(*static_cast<Wrapped*>(pobj)));
} }
static any_single_sender<E, CV, any_constrained_executor_ref<E, CV>> static any_single_sender<E, CV, exec_ref> schedule_cv(void* pobj, CV cv) {
schedule_cv(void* pobj, CV cv, VN... vn) { return ::folly::pushmi::schedule(*static_cast<Wrapped*>(pobj), cv);
return ::folly::pushmi::schedule(*static_cast<Wrapped*>(pobj), cv, vn...);
} }
}; };
static const vtable vtbl{s::top, s::schedule, s::schedule_cv}; static const vtable vtbl{s::top, s::schedule, s::schedule_cv};
...@@ -639,21 +645,11 @@ struct any_constrained_executor_ref { ...@@ -639,21 +645,11 @@ struct any_constrained_executor_ref {
CV top() { CV top() {
return vptr_->top_(pobj_); return vptr_->top_(pobj_);
} }
PUSHMI_TEMPLATE(class... AN) any_single_sender<E, any_constrained_executor_ref<E>> schedule() {
(requires sizeof...(VN) == sizeof...(AN)) // return vptr_->schedule_(pobj_);
any_single_sender<E, any_constrained_executor_ref<E>> schedule(AN&&... an) { }
// moved this check out of the requires due to a any_single_sender<E, any_constrained_executor_ref<E>> schedule(CV cv) {
// mismatched pack size between VN and AN on gcc. return vptr_->schedule_cv_(pobj_, cv);
static_assert(And<Constructible<VN, AN>...>, "arguments must be convertible");
return vptr_->schedule_(pobj_, VN{(AN&&)an}...);
}
PUSHMI_TEMPLATE(class... AN)
(requires sizeof...(VN) == sizeof...(AN)) //
any_single_sender<E, any_constrained_executor_ref<E>> schedule(CV cv, AN&&... an) {
// moved this check out of the requires due to a
// mismatched pack size between VN and AN on gcc.
static_assert(And<Constructible<VN, AN>...>, "arguments must be convertible");
return vptr_->schedule_cv_(pobj_, cv, VN{(AN&&)an}...);
} }
}; };
...@@ -689,28 +685,36 @@ PUSHMI_TEMPLATE(class Wrapped) ...@@ -689,28 +685,36 @@ PUSHMI_TEMPLATE(class Wrapped)
// //
// define types for time executors // define types for time executors
template <class E, class TP, class... VN> template <class E, class TP>
class any_time_executor { class any_time_executor {
union data { union data {
void* pobj_ = nullptr; void* pobj_ = nullptr;
std::aligned_union_t< 0, std::tuple<TP, VN...> > buffer_; std::aligned_storage_t< 2 * sizeof(void*) > buffer_;
} data_{}; } data_{};
template <class Wrapped> template <class Wrapped>
static constexpr bool insitu() { static constexpr bool insitu() {
return sizeof(Wrapped) <= sizeof(data::buffer_) && return sizeof(Wrapped) <= sizeof(data::buffer_) &&
std::is_nothrow_move_constructible<Wrapped>::value; std::is_nothrow_move_constructible<Wrapped>::value;
} }
using exec_ref = any_time_executor_ref<E>;
struct vtable { struct vtable {
static void s_op(data&, data*) {} static void s_op(data&, data*) {}
static void s_consume_op(data&&, data*) {} static void s_consume_op(data&&, data*) {}
static any_single_sender<E, any_time_executor_ref<E>> s_schedule(data&, VN...) { std::terminate(); return {}; } static any_single_sender<E, exec_ref> s_schedule(data&) {
static any_single_sender<E, any_time_executor_ref<E>> s_schedule_time(data&, TP, VN...) { std::terminate(); return {}; } std::terminate();
return {};
}
static any_single_sender<E, exec_ref> s_schedule_time(data&, TP) {
std::terminate();
return {};
}
static TP s_now(data&) { return {}; } static TP s_now(data&) { return {}; }
void (*op_)(data&, data*) = vtable::s_op; void (*op_)(data&, data*) = vtable::s_op;
void (*consume_op_)(data&&, data*) = vtable::s_consume_op; void (*consume_op_)(data&&, data*) = vtable::s_consume_op;
TP (*now_)(data&) = vtable::s_now; TP (*now_)(data&) = vtable::s_now;
any_single_sender<E, any_time_executor_ref<E>> (*schedule_)(data&, VN...) = vtable::s_schedule; any_single_sender<E, exec_ref> (*schedule_)(data&) = vtable::s_schedule;
any_single_sender<E, any_time_executor_ref<E>> (*schedule_time_)(data&, TP, VN...) = vtable::s_schedule_time; any_single_sender<E, exec_ref> (*schedule_time_)(data&, TP) =
vtable::s_schedule_time;
}; };
static constexpr vtable const noop_{}; static constexpr vtable const noop_{};
vtable const* vptr_ = &noop_; vtable const* vptr_ = &noop_;
...@@ -728,16 +732,22 @@ class any_time_executor { ...@@ -728,16 +732,22 @@ class any_time_executor {
static TP now(data& src) { static TP now(data& src) {
return ::folly::pushmi::now(*static_cast<Wrapped*>(src.pobj_)); return ::folly::pushmi::now(*static_cast<Wrapped*>(src.pobj_));
} }
static any_single_sender<E, any_time_executor_ref<E>> schedule(data& src, VN... vn) { static any_single_sender<E, exec_ref> schedule(data& src) {
return any_single_sender<E, any_time_executor_ref<E>>{::folly::pushmi::schedule( return any_single_sender<E, exec_ref>{::folly::pushmi::schedule(
*static_cast<Wrapped*>(src.pobj_), vn...)}; *static_cast<Wrapped*>(src.pobj_))};
} }
static any_single_sender<E, any_time_executor_ref<E>> schedule_time(data& src, TP tp, VN... vn) { static any_single_sender<E, exec_ref> schedule_time(data& src, TP tp) {
return any_single_sender<E, any_time_executor_ref<E>>{::folly::pushmi::schedule( return any_single_sender<E, exec_ref>{::folly::pushmi::schedule(
*static_cast<Wrapped*>(src.pobj_), tp, vn...)}; *static_cast<Wrapped*>(src.pobj_), tp)};
} }
}; };
static const vtable vtbl{s::op, s::consume_op, s::now, s::schedule, s::schedule_time}; static const vtable vtbl{
s::op,
s::consume_op,
s::now,
s::schedule,
s::schedule_time
};
data_.pobj_ = new Wrapped(std::move(obj)); data_.pobj_ = new Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
...@@ -758,16 +768,22 @@ class any_time_executor { ...@@ -758,16 +768,22 @@ class any_time_executor {
static TP now(data& src) { static TP now(data& src) {
return ::folly::pushmi::now(*static_cast<Wrapped*>((void*)src.buffer_)); return ::folly::pushmi::now(*static_cast<Wrapped*>((void*)src.buffer_));
} }
static any_single_sender<E, any_time_executor_ref<E>> schedule(data& src, VN... vn) { static any_single_sender<E, exec_ref> schedule(data& src) {
return any_single_sender<E, any_time_executor_ref<E>>{::folly::pushmi::schedule( return any_single_sender<E, exec_ref>{::folly::pushmi::schedule(
*static_cast<Wrapped*>((void*)src.buffer_), vn...)}; *static_cast<Wrapped*>((void*)src.buffer_))};
} }
static any_single_sender<E, any_time_executor_ref<E>> schedule_time(data& src, TP tp, VN... vn) { static any_single_sender<E, exec_ref> schedule_time(data& src, TP tp) {
return any_single_sender<E, any_time_executor_ref<E>>{::folly::pushmi::schedule( return any_single_sender<E, exec_ref>{::folly::pushmi::schedule(
*static_cast<Wrapped*>((void*)src.buffer_), tp, vn...)}; *static_cast<Wrapped*>((void*)src.buffer_), tp)};
} }
}; };
static const vtable vtbl{s::op, s::consume_op, s::now, s::schedule, s::schedule_time}; static const vtable vtbl{
s::op,
s::consume_op,
s::now,
s::schedule,
s::schedule_time
};
new (data_.buffer_) Wrapped(std::move(obj)); new (data_.buffer_) Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
...@@ -808,22 +824,18 @@ class any_time_executor { ...@@ -808,22 +824,18 @@ class any_time_executor {
TP top() { TP top() {
return vptr_->now_(data_); return vptr_->now_(data_);
} }
PUSHMI_TEMPLATE(class... AN) any_single_sender<E, any_time_executor_ref<E>> schedule() {
(requires And<Constructible<VN, AN>...>) return vptr_->schedule_(data_);
any_single_sender<E, any_time_executor_ref<E>> schedule(AN&&... an) {
return vptr_->schedule_(data_, VN{(AN &&) an}...);
} }
PUSHMI_TEMPLATE(class... AN) any_single_sender<E, any_time_executor_ref<E>> schedule(TP tp) {
(requires And<Constructible<VN, AN>...>) return vptr_->schedule_time_(data_, tp);
any_single_sender<E, any_time_executor_ref<E>> schedule(TP tp, AN&&... an) {
return vptr_->schedule_time_(data_, tp, VN{(AN &&) an}...);
} }
}; };
// Class static definitions: // Class static definitions:
template <class E, class TP, class... VN> template <class E, class TP>
constexpr typename any_time_executor<E, TP, VN...>::vtable const constexpr typename any_time_executor<E, TP>::vtable const
any_time_executor<E, TP, VN...>::noop_; any_time_executor<E, TP>::noop_;
template <class SF, class NF> template <class SF, class NF>
class time_executor<SF, NF> { class time_executor<SF, NF> {
...@@ -841,11 +853,10 @@ class time_executor<SF, NF> { ...@@ -841,11 +853,10 @@ class time_executor<SF, NF> {
return nf_(); return nf_();
} }
PUSHMI_TEMPLATE(class... AN) PUSHMI_TEMPLATE(class SF_ = SF)
(requires PUSHMI_EXP( (requires Invocable<SF_&>) //
lazy::Invocable<SF&, AN...>)) // auto schedule() {
auto schedule(AN&&... an) { return sf_();
return sf_((AN&&)an...);
} }
}; };
...@@ -874,11 +885,10 @@ class time_executor<Data, DSF, DNF> { ...@@ -874,11 +885,10 @@ class time_executor<Data, DSF, DNF> {
return nf_(data_); return nf_(data_);
} }
PUSHMI_TEMPLATE(class... AN) PUSHMI_TEMPLATE(class DSF_ = DSF)
(requires PUSHMI_EXP( (requires Invocable<DSF_&, Data&>) //
lazy::Invocable<DSF&, Data&, AN...>)) // auto schedule() {
auto schedule(AN&&... an) { return sf_(data_);
return sf_(data_, (AN&&)an...);
} }
}; };
...@@ -966,16 +976,16 @@ template <class T> ...@@ -966,16 +976,16 @@ template <class T>
using not_any_time_executor_ref_t = not_is_t<T, any_time_executor_ref>; using not_any_time_executor_ref_t = not_is_t<T, any_time_executor_ref>;
} // namespace detail } // namespace detail
template <class E, class TP, class... VN> template <class E, class TP>
struct any_time_executor_ref { struct any_time_executor_ref {
private: private:
using This = any_time_executor_ref; using This = any_time_executor_ref;
using exec_ref = any_time_executor_ref<E, TP>;
void* pobj_; void* pobj_;
struct vtable { struct vtable {
TP (*now_)(void*); TP (*now_)(void*);
any_single_sender<E, any_time_executor_ref<E, TP>> (*schedule_)(void*, VN...); any_single_sender<E, exec_ref> (*schedule_)(void*);
any_single_sender<E, any_time_executor_ref<E, TP>> ( any_single_sender<E, exec_ref> (*schedule_tp_)(void*, TP);
*schedule_tp_)(void*, TP, VN...);
} const* vptr_; } const* vptr_;
template <class T> template <class T>
using wrapped_t = detail::not_any_time_executor_ref_t<T>; using wrapped_t = detail::not_any_time_executor_ref_t<T>;
...@@ -993,17 +1003,17 @@ struct any_time_executor_ref { ...@@ -993,17 +1003,17 @@ struct any_time_executor_ref {
static TP now(void* pobj) { static TP now(void* pobj) {
return ::folly::pushmi::now(*static_cast<Wrapped*>(pobj)); return ::folly::pushmi::now(*static_cast<Wrapped*>(pobj));
} }
static any_single_sender<E, any_time_executor_ref<E, TP>> schedule( static any_single_sender<E, exec_ref> schedule(
void* pobj, VN... vn) { void* pobj) {
return any_single_sender<E, any_time_executor_ref<E, TP>>{::folly::pushmi::schedule( return any_single_sender<E, exec_ref>{::folly::pushmi::schedule(
*static_cast<Wrapped*>(pobj), *static_cast<Wrapped*>(pobj),
::folly::pushmi::now(*static_cast<Wrapped*>(pobj)), vn...)}; ::folly::pushmi::now(*static_cast<Wrapped*>(pobj)))};
} }
static any_single_sender<E, any_time_executor_ref<E, TP>> schedule_tp( static any_single_sender<E, exec_ref> schedule_tp(
void* pobj, void* pobj,
TP tp, TP tp) {
VN... vn) { return any_single_sender<E, exec_ref>{
return any_single_sender<E, any_time_executor_ref<E, TP>>{::folly::pushmi::schedule(*static_cast<Wrapped*>(pobj), tp, vn...)}; ::folly::pushmi::schedule(*static_cast<Wrapped*>(pobj), tp)};
} }
}; };
static const vtable vtbl{s::now, s::schedule, s::schedule_tp}; static const vtable vtbl{s::now, s::schedule, s::schedule_tp};
...@@ -1011,24 +1021,24 @@ struct any_time_executor_ref { ...@@ -1011,24 +1021,24 @@ struct any_time_executor_ref {
vptr_ = &vtbl; vptr_ = &vtbl;
} }
PUSHMI_TEMPLATE(class Wrapped) PUSHMI_TEMPLATE(class Wrapped)
(requires TimeExecutor<wrapped_t<Wrapped>> && std::is_rvalue_reference<Wrapped>::value) (requires TimeExecutor<wrapped_t<Wrapped>> && //
std::is_rvalue_reference<Wrapped>::value) //
any_time_executor_ref(Wrapped&& w) { any_time_executor_ref(Wrapped&& w) {
struct s { struct s {
static TP now(void* pobj) { static TP now(void* pobj) {
return ::folly::pushmi::now(*static_cast<Wrapped*>(pobj)); return ::folly::pushmi::now(*static_cast<Wrapped*>(pobj));
} }
static any_single_sender<E, any_time_executor_ref<E, TP>> schedule( static any_single_sender<E, exec_ref> schedule(
void* pobj, VN... vn) { void* pobj) {
return any_single_sender<E, any_time_executor_ref<E, TP>>{::folly::pushmi::schedule( return any_single_sender<E,exec_ref>{::folly::pushmi::schedule(
std::move(*static_cast<Wrapped*>(pobj)), std::move(*static_cast<Wrapped*>(pobj)),
::folly::pushmi::now(*static_cast<Wrapped*>(pobj)), vn...)}; ::folly::pushmi::now(*static_cast<Wrapped*>(pobj)))};
} }
static any_single_sender<E, any_time_executor_ref<E, TP>> schedule_tp( static any_single_sender<E, exec_ref> schedule_tp(void* pobj, TP tp) {
void* pobj, return any_single_sender<E, any_time_executor_ref<E, TP>>{
TP tp, ::folly::pushmi::schedule(
VN... vn) { std::move(*static_cast<Wrapped*>(pobj)),
return any_single_sender<E, any_time_executor_ref<E, TP>>{::folly::pushmi::schedule( tp)};
std::move(*static_cast<Wrapped*>(pobj)), tp, vn...)};
} }
}; };
static const vtable vtbl{s::now, s::schedule, s::schedule_tp}; static const vtable vtbl{s::now, s::schedule, s::schedule_tp};
...@@ -1038,21 +1048,11 @@ struct any_time_executor_ref { ...@@ -1038,21 +1048,11 @@ struct any_time_executor_ref {
TP top() { TP top() {
return vptr_->now_(pobj_); return vptr_->now_(pobj_);
} }
PUSHMI_TEMPLATE(class... AN) any_single_sender<E, any_time_executor_ref<E, TP>> schedule() {
(requires sizeof...(VN) == sizeof...(AN)) // return vptr_->schedule_(pobj_);
any_single_sender<E, any_time_executor_ref<E, TP>> schedule(AN&&... an) { }
// moved this check out of the requires due to a any_single_sender<E, any_time_executor_ref<E, TP>> schedule(TP tp) {
// mismatched pack size between VN and AN on gcc. return vptr_->schedule_tp_(pobj_, tp);
static_assert(And<Constructible<VN, AN>...>, "arguments must be convertible");
return vptr_->schedule_(pobj_, VN{(AN&&)an}...);
}
PUSHMI_TEMPLATE(class... AN)
(requires sizeof...(VN) == sizeof...(AN)) //
any_single_sender<E, any_time_executor_ref<E, TP>> schedule(TP tp, AN&&... an) {
// moved this check out of the requires due to a
// mismatched pack size between VN and AN on gcc.
static_assert(And<Constructible<VN, AN>...>, "arguments must be convertible");
return vptr_->schedule_tp_(pobj_, tp, VN{(AN&&)an}...);
} }
}; };
......
...@@ -126,28 +126,26 @@ template < ...@@ -126,28 +126,26 @@ template <
class... VN> class... VN>
class any_flow_many_sender; class any_flow_many_sender;
template <class E = std::exception_ptr, class... VN> template <class E = std::exception_ptr>
class any_executor; class any_executor;
template <class E = std::exception_ptr, class... VN> template <class E = std::exception_ptr>
struct any_executor_ref; struct any_executor_ref;
template <class E = std::exception_ptr, class CV = std::ptrdiff_t, class... VN> template <class E = std::exception_ptr, class CV = std::ptrdiff_t>
class any_constrained_executor; class any_constrained_executor;
template <class E = std::exception_ptr, class TP = std::ptrdiff_t, class... VN> template <class E = std::exception_ptr, class TP = std::ptrdiff_t>
struct any_constrained_executor_ref; struct any_constrained_executor_ref;
template < template <
class E = std::exception_ptr, class E = std::exception_ptr,
class TP = std::chrono::system_clock::time_point, class TP = std::chrono::system_clock::time_point>
class... VN>
class any_time_executor; class any_time_executor;
template < template <
class E = std::exception_ptr, class E = std::exception_ptr,
class TP = std::chrono::system_clock::time_point, class TP = std::chrono::system_clock::time_point>
class... VN>
struct any_time_executor_ref; struct any_time_executor_ref;
namespace operators {} namespace operators {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment