Commit 2690ee57 authored by Eric Niebler's avatar Eric Niebler Committed by Facebook Github Bot

Use real concepts when they are available

fbshipit-source-id: bfecdc1c0e934cf073e610c2cb98518bfde84ecd
parent a68731cb
This diff is collapsed.
...@@ -350,9 +350,9 @@ PUSHMI_CONCEPT_DEF( ...@@ -350,9 +350,9 @@ PUSHMI_CONCEPT_DEF(
); );
template <class D> template <class D>
using time_point_t = PUSHMI_PP_CONSTRAINED_USING(
std::enable_if_t<TimeSender<D>, decltype(::pushmi::now(std::declval<D&>()))>; TimeSender<D>,
time_point_t =, decltype(::pushmi::now(std::declval<D&>())));
// this is a more general form where the constraint could be time or priority // this is a more general form where the constraint could be time or priority
// enum or any other ordering constraint value-type. // enum or any other ordering constraint value-type.
...@@ -386,9 +386,8 @@ PUSHMI_CONCEPT_DEF( ...@@ -386,9 +386,8 @@ PUSHMI_CONCEPT_DEF(
); );
template <class D> template <class D>
using constraint_t = PUSHMI_PP_CONSTRAINED_USING(
std::enable_if_t<
ConstrainedSender<D>, ConstrainedSender<D>,
decltype(::pushmi::top(std::declval<D&>()))>; constraint_t =, decltype(::pushmi::top(std::declval<D&>())));
} // namespace pushmi } // namespace pushmi
...@@ -29,21 +29,8 @@ class deferred<detail::erase_deferred_t, E> { ...@@ -29,21 +29,8 @@ class deferred<detail::erase_deferred_t, E> {
void (*submit_)(data&, any_none<E>) = s_submit; void (*submit_)(data&, any_none<E>) = s_submit;
static constexpr vtable const noop_{}; static constexpr vtable const noop_{};
} const* vptr_ = &vtable::noop_; } const* vptr_ = &vtable::noop_;
template <class T, class U = std::decay_t<T>> template <class Wrapped>
using wrapped_t = deferred(Wrapped obj, std::false_type) : deferred() {
std::enable_if_t<!std::is_same<U, deferred>::value, U>;
public:
using properties = property_set<is_sender<>, is_none<>>;
deferred() = default;
deferred(deferred&& that) noexcept : deferred() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE(class Wrapped)
(requires SenderTo<wrapped_t<Wrapped>, any_none<E>, is_none<>>
PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
explicit deferred(Wrapped obj) : deferred() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -58,10 +45,8 @@ class deferred<detail::erase_deferred_t, E> { ...@@ -58,10 +45,8 @@ class deferred<detail::erase_deferred_t, E> {
data_.pobj_ = new Wrapped(std::move(obj)); data_.pobj_ = new Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
PUSHMI_TEMPLATE(class Wrapped) template <class Wrapped>
(requires SenderTo<wrapped_t<Wrapped>, any_none<E>, is_none<>> deferred(Wrapped obj, std::true_type) noexcept : deferred() {
&& insitu<Wrapped>())
explicit deferred(Wrapped obj) noexcept : deferred() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -78,6 +63,21 @@ class deferred<detail::erase_deferred_t, E> { ...@@ -78,6 +63,21 @@ class deferred<detail::erase_deferred_t, E> {
new (data_.buffer_) Wrapped(std::move(obj)); new (data_.buffer_) Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
template <class T, class U = std::decay_t<T>>
using wrapped_t =
std::enable_if_t<!std::is_same<U, deferred>::value, U>;
public:
using properties = property_set<is_sender<>, is_none<>>;
deferred() = default;
deferred(deferred&& that) noexcept : deferred() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE(class Wrapped)
(requires SenderTo<wrapped_t<Wrapped>, any_none<E>, is_none<>>)
explicit deferred(Wrapped obj) noexcept(insitu<Wrapped>())
: deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
~deferred() { ~deferred() {
vptr_->op_(data_, nullptr); vptr_->op_(data_, nullptr);
} }
......
...@@ -34,21 +34,8 @@ class flow_single<V, PE, E> { ...@@ -34,21 +34,8 @@ class flow_single<V, PE, E> {
void (*starting_)(data&, any_none<PE>&) = s_starting; void (*starting_)(data&, any_none<PE>&) = s_starting;
static constexpr vtable const noop_ {}; static constexpr vtable const noop_ {};
} const* vptr_ = &vtable::noop_; } const* vptr_ = &vtable::noop_;
template <class T, class U = std::decay_t<T>> template <class Wrapped>
using wrapped_t = flow_single(Wrapped obj, std::false_type) : flow_single() {
std::enable_if_t<!std::is_same<U, flow_single>::value, U>;
public:
using properties = property_set<is_receiver<>, is_flow<>, is_single<>>;
flow_single() = default;
flow_single(flow_single&& that) noexcept : flow_single() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE(class Wrapped)
(requires FlowSingleReceiver<wrapped_t<Wrapped>, any_none<PE>, V, PE, E>
PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
explicit flow_single(Wrapped obj) : flow_single() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -75,10 +62,8 @@ public: ...@@ -75,10 +62,8 @@ public:
data_.pobj_ = new Wrapped(std::move(obj)); data_.pobj_ = new Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
PUSHMI_TEMPLATE(class Wrapped) template <class Wrapped>
(requires FlowSingleReceiver<wrapped_t<Wrapped>, any_none<PE>, V, PE, E> flow_single(Wrapped obj, std::true_type) noexcept : flow_single() {
&& insitu<Wrapped>())
explicit flow_single(Wrapped obj) noexcept : flow_single() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -108,6 +93,21 @@ public: ...@@ -108,6 +93,21 @@ public:
new (data_.buffer_) Wrapped(std::move(obj)); new (data_.buffer_) Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
template <class T, class U = std::decay_t<T>>
using wrapped_t =
std::enable_if_t<!std::is_same<U, flow_single>::value, U>;
public:
using properties = property_set<is_receiver<>, is_flow<>, is_single<>>;
flow_single() = default;
flow_single(flow_single&& that) noexcept : flow_single() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE(class Wrapped)
(requires FlowSingleReceiver<wrapped_t<Wrapped>, any_none<PE>, V, PE, E>)
explicit flow_single(Wrapped obj) noexcept(insitu<Wrapped>())
: flow_single{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
~flow_single() { ~flow_single() {
vptr_->op_(data_, nullptr); vptr_->op_(data_, nullptr);
} }
......
...@@ -26,22 +26,8 @@ class flow_single_deferred<V, PE, E> { ...@@ -26,22 +26,8 @@ class flow_single_deferred<V, PE, E> {
void (*submit_)(data&, flow_single<V, PE, E>) = s_submit; void (*submit_)(data&, flow_single<V, PE, E>) = s_submit;
static constexpr vtable const noop_ {}; static constexpr vtable const noop_ {};
} const* vptr_ = &vtable::noop_; } const* vptr_ = &vtable::noop_;
template <class T, class U = std::decay_t<T>> template <class Wrapped>
using wrapped_t = flow_single_deferred(Wrapped obj, std::false_type) : flow_single_deferred() {
std::enable_if_t<!std::is_same<U, flow_single_deferred>::value, U>;
public:
using properties = property_set<is_sender<>, is_flow<>, is_single<>>;
flow_single_deferred() = default;
flow_single_deferred(flow_single_deferred&& that) noexcept
: flow_single_deferred() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE (class Wrapped)
(requires FlowSender<wrapped_t<Wrapped>, is_single<>>
PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
explicit flow_single_deferred(Wrapped obj) : flow_single_deferred() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -56,9 +42,9 @@ class flow_single_deferred<V, PE, E> { ...@@ -56,9 +42,9 @@ class flow_single_deferred<V, PE, E> {
data_.pobj_ = new Wrapped(std::move(obj)); data_.pobj_ = new Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
PUSHMI_TEMPLATE (class Wrapped) template <class Wrapped>
(requires FlowSender<wrapped_t<Wrapped>, is_single<>> && insitu<Wrapped>()) flow_single_deferred(Wrapped obj, std::true_type) noexcept
explicit flow_single_deferred(Wrapped obj) noexcept : flow_single_deferred() { : flow_single_deferred() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -76,6 +62,22 @@ class flow_single_deferred<V, PE, E> { ...@@ -76,6 +62,22 @@ class flow_single_deferred<V, PE, E> {
new (data_.buffer_) Wrapped(std::move(obj)); new (data_.buffer_) Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
template <class T, class U = std::decay_t<T>>
using wrapped_t =
std::enable_if_t<!std::is_same<U, flow_single_deferred>::value, U>;
public:
using properties = property_set<is_sender<>, is_flow<>, is_single<>>;
flow_single_deferred() = default;
flow_single_deferred(flow_single_deferred&& that) noexcept
: flow_single_deferred() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE (class Wrapped)
(requires FlowSender<wrapped_t<Wrapped>, is_single<>>)
explicit flow_single_deferred(Wrapped obj) noexcept(insitu<Wrapped>())
: flow_single_deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
~flow_single_deferred() { ~flow_single_deferred() {
vptr_->op_(data_, nullptr); vptr_->op_(data_, nullptr);
} }
......
...@@ -29,21 +29,8 @@ class none<E> { ...@@ -29,21 +29,8 @@ class none<E> {
void (*error_)(data&, E) noexcept = s_error; void (*error_)(data&, E) noexcept = s_error;
static constexpr vtable const noop_ {}; static constexpr vtable const noop_ {};
} const* vptr_ = &vtable::noop_; } const* vptr_ = &vtable::noop_;
template <class T, class U = std::decay_t<T>> template <class Wrapped>
using wrapped_t = none(Wrapped obj, std::false_type) : none() {
std::enable_if_t<!std::is_same<U, none>::value, U>;
public:
using properties = property_set<is_receiver<>, is_none<>>;
none() = default;
none(none&& that) noexcept : none() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE(class Wrapped)
(requires NoneReceiver<wrapped_t<Wrapped>, E>
PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
explicit none(Wrapped obj) : none() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -61,9 +48,8 @@ public: ...@@ -61,9 +48,8 @@ public:
data_.pobj_ = new Wrapped(std::move(obj)); data_.pobj_ = new Wrapped(std::move(obj));
vptr_ = &vtable_v; vptr_ = &vtable_v;
} }
PUSHMI_TEMPLATE(class Wrapped) template <class Wrapped>
(requires NoneReceiver<wrapped_t<Wrapped>, E> && insitu<Wrapped>()) none(Wrapped obj, std::true_type) noexcept : none() {
explicit none(Wrapped obj) noexcept : none() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -83,6 +69,21 @@ public: ...@@ -83,6 +69,21 @@ public:
new (data_.buffer_) Wrapped(std::move(obj)); new (data_.buffer_) Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
template <class T, class U = std::decay_t<T>>
using wrapped_t =
std::enable_if_t<!std::is_same<U, none>::value, U>;
public:
using properties = property_set<is_receiver<>, is_none<>>;
none() = default;
none(none&& that) noexcept : none() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE(class Wrapped)
(requires NoneReceiver<wrapped_t<Wrapped>, E>)
explicit none(Wrapped obj) noexcept(insitu<Wrapped>())
: none{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
~none() { ~none() {
vptr_->op_(data_, nullptr); vptr_->op_(data_, nullptr);
} }
...@@ -196,40 +197,40 @@ inline auto make_none() -> none<> { ...@@ -196,40 +197,40 @@ inline auto make_none() -> none<> {
return {}; return {};
} }
PUSHMI_TEMPLATE(class EF) PUSHMI_TEMPLATE(class EF)
(requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<EF> && not lazy::Invocable<EF&>)) (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<EF> && not defer::Invocable<EF&>))
auto make_none(EF ef) -> none<EF, ignoreDF> { auto make_none(EF ef) -> none<EF, ignoreDF> {
return none<EF, ignoreDF>{std::move(ef)}; return none<EF, ignoreDF>{std::move(ef)};
} }
PUSHMI_TEMPLATE(class DF) PUSHMI_TEMPLATE(class DF)
(requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>)) (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
auto make_none(DF df) -> none<abortEF, DF> { auto make_none(DF df) -> none<abortEF, DF> {
return none<abortEF, DF>{std::move(df)}; return none<abortEF, DF>{std::move(df)};
} }
PUSHMI_TEMPLATE(class EF, class DF) PUSHMI_TEMPLATE(class EF, class DF)
(requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>)) (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
auto make_none(EF ef, DF df) -> none<EF, DF> { auto make_none(EF ef, DF df) -> none<EF, DF> {
return {std::move(ef), std::move(df)}; return {std::move(ef), std::move(df)};
} }
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>>) (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>)
auto make_none(Data d) -> none<Data, passDEF, passDDF> { auto make_none(Data d) -> none<Data, passDEF, passDDF> {
return none<Data, passDEF, passDDF>{std::move(d)}; return none<Data, passDEF, passDDF>{std::move(d)};
} }
PUSHMI_TEMPLATE(class Data, class DEF) PUSHMI_TEMPLATE(class Data, class DEF)
(requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>
PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>)) PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
auto make_none(Data d, DEF ef) -> none<Data, DEF, passDDF> { auto make_none(Data d, DEF ef) -> none<Data, DEF, passDDF> {
return {std::move(d), std::move(ef)}; return {std::move(d), std::move(ef)};
} }
PUSHMI_TEMPLATE(class Data, class DDF) PUSHMI_TEMPLATE(class Data, class DDF)
(requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> && (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
lazy::Invocable<DDF&, Data&>) defer::Invocable<DDF&, Data&>)
auto make_none(Data d, DDF df) -> none<Data, passDEF, DDF> { auto make_none(Data d, DDF df) -> none<Data, passDEF, DDF> {
return {std::move(d), std::move(df)}; return {std::move(d), std::move(df)};
} }
PUSHMI_TEMPLATE(class Data, class DEF, class DDF) PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
(requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> && (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
lazy::Invocable<DDF&, Data&>) defer::Invocable<DDF&, Data&>)
auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> { auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> {
return {std::move(d), std::move(ef), std::move(df)}; return {std::move(d), std::move(ef), std::move(df)};
} }
...@@ -240,34 +241,34 @@ auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> { ...@@ -240,34 +241,34 @@ auto make_none(Data d, DEF ef, DDF df) -> none<Data, DEF, DDF> {
none() -> none<>; none() -> none<>;
PUSHMI_TEMPLATE(class EF) PUSHMI_TEMPLATE(class EF)
(requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<EF> && not lazy::Invocable<EF&>)) (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<EF> && not defer::Invocable<EF&>))
none(EF) -> none<EF, ignoreDF>; none(EF) -> none<EF, ignoreDF>;
PUSHMI_TEMPLATE(class DF) PUSHMI_TEMPLATE(class DF)
(requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>)) (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
none(DF) -> none<abortEF, DF>; none(DF) -> none<abortEF, DF>;
PUSHMI_TEMPLATE(class EF, class DF) PUSHMI_TEMPLATE(class EF, class DF)
(requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>)) (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
none(EF, DF) -> none<EF, DF>; none(EF, DF) -> none<EF, DF>;
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>>) (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>)
none(Data) -> none<Data, passDEF, passDDF>; none(Data) -> none<Data, passDEF, passDDF>;
PUSHMI_TEMPLATE(class Data, class DEF) PUSHMI_TEMPLATE(class Data, class DEF)
(requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>>
PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>)) PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
none(Data, DEF) -> none<Data, DEF, passDDF>; none(Data, DEF) -> none<Data, DEF, passDDF>;
PUSHMI_TEMPLATE(class Data, class DDF) PUSHMI_TEMPLATE(class Data, class DDF)
(requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> && (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
lazy::Invocable<DDF&, Data&>) defer::Invocable<DDF&, Data&>)
none(Data, DDF) -> none<Data, passDEF, DDF>; none(Data, DDF) -> none<Data, passDEF, DDF>;
PUSHMI_TEMPLATE(class Data, class DEF, class DDF) PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
(requires lazy::Receiver<Data, is_none<>> && not lazy::Receiver<Data, is_single<>> && (requires defer::Receiver<Data, is_none<>> && not defer::Receiver<Data, is_single<>> &&
lazy::Invocable<DDF&, Data&>) defer::Invocable<DDF&, Data&>)
none(Data, DEF, DDF) -> none<Data, DEF, DDF>; none(Data, DEF, DDF) -> none<Data, DEF, DDF>;
#endif #endif
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
// LICENSE file in the root directory of this source tree. // LICENSE file in the root directory of this source tree.
#include "../single.h" #include "../single.h"
#include "../single_deferred.h"
#include "submit.h" #include "submit.h"
#include "extension_operators.h" #include "extension_operators.h"
......
...@@ -161,14 +161,16 @@ struct property_query_impl : ...@@ -161,14 +161,16 @@ struct property_query_impl :
meta::and_c<decltype(property_query_fn<ExpectedN>((properties_t<PS>*)nullptr))::value...> {}; meta::and_c<decltype(property_query_fn<ExpectedN>((properties_t<PS>*)nullptr))::value...> {};
} //namespace detail } //namespace detail
template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN> //template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
template<class PS, class... ExpectedN>
struct property_query struct property_query
: meta::if_c< : meta::if_c<
Properties<PS> && And<Property<ExpectedN>...>, Properties<PS> && And<Property<ExpectedN>...>,
detail::property_query_impl<PS, ExpectedN...>, detail::property_query_impl<PS, ExpectedN...>,
std::false_type> {}; std::false_type> {};
template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN> //template<PUSHMI_TYPE_CONSTRAINT(Properties) PS, PUSHMI_TYPE_CONSTRAINT(Property)... ExpectedN>
template<class PS, class... ExpectedN>
PUSHMI_INLINE_VAR constexpr bool property_query_v = property_query<PS, ExpectedN...>::value; PUSHMI_INLINE_VAR constexpr bool property_query_v = property_query<PS, ExpectedN...>::value;
} // namespace pushmi } // namespace pushmi
...@@ -17,7 +17,7 @@ class single<V, E> { ...@@ -17,7 +17,7 @@ class single<V, E> {
char buffer_[sizeof(std::promise<int>)]; // can hold a std::promise in-situ char buffer_[sizeof(std::promise<int>)]; // can hold a std::promise in-situ
} data_{}; } data_{};
template <class Wrapped> template <class Wrapped>
static constexpr bool insitu() { static constexpr bool insitu() noexcept {
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;
} }
...@@ -46,19 +46,8 @@ class single<V, E> { ...@@ -46,19 +46,8 @@ class single<V, E> {
static_assert(NothrowInvocable<decltype(::pushmi::set_error), Wrapped, E>, static_assert(NothrowInvocable<decltype(::pushmi::set_error), Wrapped, E>,
"Wrapped single must support E and be noexcept"); "Wrapped single must support E and be noexcept");
} }
public: template<class Wrapped>
using properties = property_set<is_receiver<>, is_single<>>; single(Wrapped obj, std::false_type) : single() {
single() = default;
single(single&& that) noexcept : single() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE(class Wrapped)
(requires SingleReceiver<wrapped_t<Wrapped>, V, E>
PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
explicit single(Wrapped obj) : single() {
check<Wrapped>();
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -82,10 +71,8 @@ public: ...@@ -82,10 +71,8 @@ public:
data_.pobj_ = new Wrapped(std::move(obj)); data_.pobj_ = new Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
PUSHMI_TEMPLATE(class Wrapped) template<class Wrapped>
(requires SingleReceiver<wrapped_t<Wrapped>, V, E> && insitu<Wrapped>()) single(Wrapped obj, std::true_type) noexcept : single() {
explicit single(Wrapped obj) noexcept : single() {
check<Wrapped>();
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -112,6 +99,20 @@ public: ...@@ -112,6 +99,20 @@ public:
new ((void*)data_.buffer_) Wrapped(std::move(obj)); new ((void*)data_.buffer_) Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
public:
using properties = property_set<is_receiver<>, is_single<>>;
single() = default;
single(single&& that) noexcept : single() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE(class Wrapped)
(requires SingleReceiver<wrapped_t<Wrapped>, V, E>)
explicit single(Wrapped obj) noexcept(insitu<Wrapped>())
: single{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {
check<Wrapped>();
}
~single() { ~single() {
vptr_->op_(data_, nullptr); vptr_->op_(data_, nullptr);
} }
...@@ -281,7 +282,7 @@ inline auto make_single() -> single<> { ...@@ -281,7 +282,7 @@ inline auto make_single() -> single<> {
return {}; return {};
} }
PUSHMI_TEMPLATE(class VF) PUSHMI_TEMPLATE(class VF)
(requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<VF&>)) (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<VF&>))
auto make_single(VF vf) -> single<VF, abortEF, ignoreDF> { auto make_single(VF vf) -> single<VF, abortEF, ignoreDF> {
return single<VF, abortEF, ignoreDF>{std::move(vf)}; return single<VF, abortEF, ignoreDF>{std::move(vf)};
} }
...@@ -290,58 +291,58 @@ auto make_single(on_error_fn<EFN...> ef) -> single<ignoreVF, on_error_fn<EFN...> ...@@ -290,58 +291,58 @@ auto make_single(on_error_fn<EFN...> ef) -> single<ignoreVF, on_error_fn<EFN...>
return single<ignoreVF, on_error_fn<EFN...>, ignoreDF>{std::move(ef)}; return single<ignoreVF, on_error_fn<EFN...>, ignoreDF>{std::move(ef)};
} }
PUSHMI_TEMPLATE(class DF) PUSHMI_TEMPLATE(class DF)
(requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>)) (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
auto make_single(DF df) -> single<ignoreVF, abortEF, DF> { auto make_single(DF df) -> single<ignoreVF, abortEF, DF> {
return single<ignoreVF, abortEF, DF>{std::move(df)}; return single<ignoreVF, abortEF, DF>{std::move(df)};
} }
PUSHMI_TEMPLATE(class VF, class EF) PUSHMI_TEMPLATE(class VF, class EF)
(requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<EF&>)) (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<EF&>))
auto make_single(VF vf, EF ef) -> single<VF, EF, ignoreDF> { auto make_single(VF vf, EF ef) -> single<VF, EF, ignoreDF> {
return {std::move(vf), std::move(ef)}; return {std::move(vf), std::move(ef)};
} }
PUSHMI_TEMPLATE(class EF, class DF) PUSHMI_TEMPLATE(class EF, class DF)
(requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>)) (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
auto make_single(EF ef, DF df) -> single<ignoreVF, EF, DF> { auto make_single(EF ef, DF df) -> single<ignoreVF, EF, DF> {
return {std::move(ef), std::move(df)}; return {std::move(ef), std::move(df)};
} }
PUSHMI_TEMPLATE(class VF, class EF, class DF) PUSHMI_TEMPLATE(class VF, class EF, class DF)
(requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<VF>)) (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<VF>))
auto make_single(VF vf, EF ef, DF df) -> single<VF, EF, DF> { auto make_single(VF vf, EF ef, DF df) -> single<VF, EF, DF> {
return {std::move(vf), std::move(ef), std::move(df)}; return {std::move(vf), std::move(ef), std::move(df)};
} }
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires lazy::Receiver<Data, is_single<>>) (requires defer::Receiver<Data, is_single<>>)
auto make_single(Data d) -> single<Data, passDVF, passDEF, passDDF> { auto make_single(Data d) -> single<Data, passDVF, passDEF, passDDF> {
return single<Data, passDVF, passDEF, passDDF>{std::move(d)}; return single<Data, passDVF, passDEF, passDDF>{std::move(d)};
} }
PUSHMI_TEMPLATE(class Data, class DVF) PUSHMI_TEMPLATE(class Data, class DVF)
(requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DVF&, Data&>)) (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DVF&, Data&>))
auto make_single(Data d, DVF vf) -> single<Data, DVF, passDEF, passDDF> { auto make_single(Data d, DVF vf) -> single<Data, DVF, passDEF, passDDF> {
return {std::move(d), std::move(vf)}; return {std::move(d), std::move(vf)};
} }
PUSHMI_TEMPLATE(class Data, class... DEFN) PUSHMI_TEMPLATE(class Data, class... DEFN)
(requires lazy::Receiver<Data, is_single<>>) (requires defer::Receiver<Data, is_single<>>)
auto make_single(Data d, on_error_fn<DEFN...> ef) -> auto make_single(Data d, on_error_fn<DEFN...> ef) ->
single<Data, passDVF, on_error_fn<DEFN...>, passDDF> { single<Data, passDVF, on_error_fn<DEFN...>, passDDF> {
return {std::move(d), std::move(ef)}; return {std::move(d), std::move(ef)};
} }
PUSHMI_TEMPLATE(class Data, class DDF) PUSHMI_TEMPLATE(class Data, class DDF)
(requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>) (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
auto make_single(Data d, DDF df) -> single<Data, passDVF, passDEF, DDF> { auto make_single(Data d, DDF df) -> single<Data, passDVF, passDEF, DDF> {
return {std::move(d), std::move(df)}; return {std::move(d), std::move(df)};
} }
PUSHMI_TEMPLATE(class Data, class DVF, class DEF) PUSHMI_TEMPLATE(class Data, class DVF, class DEF)
(requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>)) (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
auto make_single(Data d, DVF vf, DEF ef) -> single<Data, DVF, DEF, passDDF> { auto make_single(Data d, DVF vf, DEF ef) -> single<Data, DVF, DEF, passDDF> {
return {std::move(d), std::move(vf), std::move(ef)}; return {std::move(d), std::move(vf), std::move(ef)};
} }
PUSHMI_TEMPLATE(class Data, class DEF, class DDF) PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
(requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>) (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
auto make_single(Data d, DEF ef, DDF df) -> single<Data, passDVF, DEF, DDF> { auto make_single(Data d, DEF ef, DDF df) -> single<Data, passDVF, DEF, DDF> {
return {std::move(d), std::move(ef), std::move(df)}; return {std::move(d), std::move(ef), std::move(df)};
} }
PUSHMI_TEMPLATE(class Data, class DVF, class DEF, class DDF) PUSHMI_TEMPLATE(class Data, class DVF, class DEF, class DDF)
(requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>) (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF> { auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF> {
return {std::move(d), std::move(vf), std::move(ef), std::move(df)}; return {std::move(d), std::move(vf), std::move(ef), std::move(df)};
} }
...@@ -352,55 +353,55 @@ auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF> ...@@ -352,55 +353,55 @@ auto make_single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>
single() -> single<>; single() -> single<>;
PUSHMI_TEMPLATE(class VF) PUSHMI_TEMPLATE(class VF)
(requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<VF&>)) (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<VF&>))
single(VF) -> single<VF, abortEF, ignoreDF>; single(VF) -> single<VF, abortEF, ignoreDF>;
template <class... EFN> template <class... EFN>
single(on_error_fn<EFN...>) -> single<ignoreVF, on_error_fn<EFN...>, ignoreDF>; single(on_error_fn<EFN...>) -> single<ignoreVF, on_error_fn<EFN...>, ignoreDF>;
PUSHMI_TEMPLATE(class DF) PUSHMI_TEMPLATE(class DF)
(requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<DF>)) (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<DF>))
single(DF) -> single<ignoreVF, abortEF, DF>; single(DF) -> single<ignoreVF, abortEF, DF>;
PUSHMI_TEMPLATE(class VF, class EF) PUSHMI_TEMPLATE(class VF, class EF)
(requires PUSHMI_BROKEN_SUBSUMPTION(not lazy::Receiver<VF> && not lazy::Invocable<EF&>)) (requires PUSHMI_BROKEN_SUBSUMPTION(not defer::Receiver<VF> && not defer::Invocable<EF&>))
single(VF, EF) -> single<VF, EF, ignoreDF>; single(VF, EF) -> single<VF, EF, ignoreDF>;
PUSHMI_TEMPLATE(class EF, class DF) PUSHMI_TEMPLATE(class EF, class DF)
(requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<EF>)) (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<EF>))
single(EF, DF) -> single<ignoreVF, EF, DF>; single(EF, DF) -> single<ignoreVF, EF, DF>;
PUSHMI_TEMPLATE(class VF, class EF, class DF) PUSHMI_TEMPLATE(class VF, class EF, class DF)
(requires lazy::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Receiver<VF>)) (requires defer::Invocable<DF&> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Receiver<VF>))
single(VF, EF, DF) -> single<VF, EF, DF>; single(VF, EF, DF) -> single<VF, EF, DF>;
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires lazy::Receiver<Data, is_single<>>) (requires defer::Receiver<Data, is_single<>>)
single(Data d) -> single<Data, passDVF, passDEF, passDDF>; single(Data d) -> single<Data, passDVF, passDEF, passDDF>;
PUSHMI_TEMPLATE(class Data, class DVF) PUSHMI_TEMPLATE(class Data, class DVF)
(requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DVF&, Data&>)) (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DVF&, Data&>))
single(Data d, DVF vf) -> single<Data, DVF, passDEF, passDDF>; single(Data d, DVF vf) -> single<Data, DVF, passDEF, passDDF>;
PUSHMI_TEMPLATE(class Data, class... DEFN) PUSHMI_TEMPLATE(class Data, class... DEFN)
(requires lazy::Receiver<Data, is_single<>>) (requires defer::Receiver<Data, is_single<>>)
single(Data d, on_error_fn<DEFN...>) -> single(Data d, on_error_fn<DEFN...>) ->
single<Data, passDVF, on_error_fn<DEFN...>, passDDF>; single<Data, passDVF, on_error_fn<DEFN...>, passDDF>;
PUSHMI_TEMPLATE(class Data, class DDF) PUSHMI_TEMPLATE(class Data, class DDF)
(requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>) (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
single(Data d, DDF) -> single<Data, passDVF, passDEF, DDF>; single(Data d, DDF) -> single<Data, passDVF, passDEF, DDF>;
PUSHMI_TEMPLATE(class Data, class DVF, class DEF) PUSHMI_TEMPLATE(class Data, class DVF, class DEF)
(requires lazy::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not lazy::Invocable<DEF&, Data&>)) (requires defer::Receiver<Data, is_single<>> PUSHMI_BROKEN_SUBSUMPTION(&& not defer::Invocable<DEF&, Data&>))
single(Data d, DVF vf, DEF ef) -> single<Data, DVF, DEF, passDDF>; single(Data d, DVF vf, DEF ef) -> single<Data, DVF, DEF, passDDF>;
PUSHMI_TEMPLATE(class Data, class DEF, class DDF) PUSHMI_TEMPLATE(class Data, class DEF, class DDF)
(requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>) (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
single(Data d, DEF, DDF) -> single<Data, passDVF, DEF, DDF>; single(Data d, DEF, DDF) -> single<Data, passDVF, DEF, DDF>;
PUSHMI_TEMPLATE(class Data, class DVF, class DEF, class DDF) PUSHMI_TEMPLATE(class Data, class DVF, class DEF, class DDF)
(requires lazy::Receiver<Data, is_single<>> && lazy::Invocable<DDF&, Data&>) (requires defer::Receiver<Data, is_single<>> && defer::Invocable<DDF&, Data&>)
single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>; single(Data d, DVF vf, DEF ef, DDF df) -> single<Data, DVF, DEF, DDF>;
#endif #endif
......
...@@ -26,22 +26,8 @@ class any_single_deferred { ...@@ -26,22 +26,8 @@ class any_single_deferred {
void (*submit_)(data&, single<V, E>) = s_submit; void (*submit_)(data&, single<V, E>) = s_submit;
static constexpr vtable const noop_ {}; static constexpr vtable const noop_ {};
} const* vptr_ = &vtable::noop_; } const* vptr_ = &vtable::noop_;
template <class T, class U = std::decay_t<T>> template <class Wrapped>
using wrapped_t = any_single_deferred(Wrapped obj, std::false_type) : any_single_deferred() {
std::enable_if_t<!std::is_same<U, any_single_deferred>::value, U>;
public:
using properties = property_set<is_sender<>, is_single<>>;
any_single_deferred() = default;
any_single_deferred(any_single_deferred&& that) noexcept : any_single_deferred() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE(class Wrapped)
(requires SenderTo<wrapped_t<Wrapped>, single<V, E>, is_single<>>
PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
explicit any_single_deferred(Wrapped obj) : any_single_deferred() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -56,10 +42,9 @@ class any_single_deferred { ...@@ -56,10 +42,9 @@ class any_single_deferred {
data_.pobj_ = new Wrapped(std::move(obj)); data_.pobj_ = new Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
PUSHMI_TEMPLATE(class Wrapped) template <class Wrapped>
(requires SenderTo<wrapped_t<Wrapped>, single<V, E>, is_single<>> any_single_deferred(Wrapped obj, std::true_type) noexcept
&& insitu<Wrapped>()) : any_single_deferred() {
explicit any_single_deferred(Wrapped obj) noexcept : any_single_deferred() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -76,6 +61,23 @@ class any_single_deferred { ...@@ -76,6 +61,23 @@ class any_single_deferred {
new (data_.buffer_) Wrapped(std::move(obj)); new (data_.buffer_) Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
template <class T, class U = std::decay_t<T>>
using wrapped_t =
std::enable_if_t<!std::is_same<U, any_single_deferred>::value, U>;
public:
using properties = property_set<is_sender<>, is_single<>>;
any_single_deferred() = default;
any_single_deferred(any_single_deferred&& that) noexcept
: any_single_deferred() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE(class Wrapped)
(requires SenderTo<wrapped_t<Wrapped>, single<V, E>, is_single<>>)
explicit any_single_deferred(Wrapped obj) noexcept(insitu<Wrapped>())
: any_single_deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {}
~any_single_deferred() { ~any_single_deferred() {
vptr_->op_(data_, nullptr); vptr_->op_(data_, nullptr);
} }
...@@ -106,7 +108,7 @@ class single_deferred<SF> { ...@@ -106,7 +108,7 @@ class single_deferred<SF> {
: sf_(std::move(sf)) {} : sf_(std::move(sf)) {}
PUSHMI_TEMPLATE(class Out) PUSHMI_TEMPLATE(class Out)
(requires lazy::Receiver<Out, is_single<>> && lazy::Invocable<SF&, Out>) (requires defer::Receiver<Out, is_single<>> && defer::Invocable<SF&, Out>)
void submit(Out out) { void submit(Out out) {
sf_(std::move(out)); sf_(std::move(out));
} }
...@@ -127,7 +129,8 @@ class single_deferred_2 { ...@@ -127,7 +129,8 @@ class single_deferred_2 {
constexpr single_deferred_2(Data data, DSF sf) constexpr single_deferred_2(Data data, DSF sf)
: data_(std::move(data)), sf_(std::move(sf)) {} : data_(std::move(data)), sf_(std::move(sf)) {}
PUSHMI_TEMPLATE(class Out) PUSHMI_TEMPLATE(class Out)
(requires lazy::Receiver<Out, is_single<>> && lazy::Invocable<DSF&, Data&, Out>) (requires defer::Receiver<Out, is_single<>> &&
defer::Invocable<DSF&, Data&, Out>)
void submit(Out out) { void submit(Out out) {
sf_(data_, std::move(out)); sf_(data_, std::move(out));
} }
...@@ -136,7 +139,7 @@ class single_deferred_2 { ...@@ -136,7 +139,7 @@ class single_deferred_2 {
template <class A, class B> template <class A, class B>
using single_deferred_base = using single_deferred_base =
meta::if_c< meta::if_c<
Sender<A, is_single<>>, (bool)Sender<A, is_single<>>,
single_deferred_2<A, B>, single_deferred_2<A, B>,
any_single_deferred<A, B>>; any_single_deferred<A, B>>;
} // namespace detail } // namespace detail
......
...@@ -31,23 +31,9 @@ class any_time_single_deferred { ...@@ -31,23 +31,9 @@ class any_time_single_deferred {
void (*submit_)(data&, TP, single<V, E>) = s_submit; void (*submit_)(data&, TP, single<V, E>) = s_submit;
static constexpr vtable const noop_ = {}; static constexpr vtable const noop_ = {};
} const* vptr_ = &vtable::noop_; } const* vptr_ = &vtable::noop_;
template <class T, class U = std::decay_t<T>> template <class Wrapped>
using wrapped_t = any_time_single_deferred(Wrapped obj, std::false_type)
std::enable_if_t<!std::is_same<U, any_time_single_deferred>::value, U>;
public:
using properties = property_set<is_time<>, is_single<>>;
any_time_single_deferred() = default;
any_time_single_deferred(any_time_single_deferred&& that) noexcept
: any_time_single_deferred() { : any_time_single_deferred() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE (class Wrapped)
(requires TimeSenderTo<wrapped_t<Wrapped>, single<V, E>>
PUSHMI_BROKEN_SUBSUMPTION(&& !insitu<Wrapped>()))
explicit any_time_single_deferred(Wrapped obj) : any_time_single_deferred() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -68,10 +54,9 @@ class any_time_single_deferred { ...@@ -68,10 +54,9 @@ class any_time_single_deferred {
data_.pobj_ = new Wrapped(std::move(obj)); data_.pobj_ = new Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
PUSHMI_TEMPLATE (class Wrapped) template <class Wrapped>
(requires TimeSenderTo<wrapped_t<Wrapped>, single<V, E>> && any_time_single_deferred(Wrapped obj, std::true_type) noexcept
insitu<Wrapped>()) : any_time_single_deferred() {
explicit any_time_single_deferred(Wrapped obj) noexcept : any_time_single_deferred() {
struct s { struct s {
static void op(data& src, data* dst) { static void op(data& src, data* dst) {
if (dst) if (dst)
...@@ -93,6 +78,24 @@ class any_time_single_deferred { ...@@ -93,6 +78,24 @@ class any_time_single_deferred {
new (data_.buffer_) Wrapped(std::move(obj)); new (data_.buffer_) Wrapped(std::move(obj));
vptr_ = &vtbl; vptr_ = &vtbl;
} }
template <class T, class U = std::decay_t<T>>
using wrapped_t =
std::enable_if_t<!std::is_same<U, any_time_single_deferred>::value, U>;
public:
using properties = property_set<is_time<>, is_single<>>;
any_time_single_deferred() = default;
any_time_single_deferred(any_time_single_deferred&& that) noexcept
: any_time_single_deferred() {
that.vptr_->op_(that.data_, &data_);
std::swap(that.vptr_, vptr_);
}
PUSHMI_TEMPLATE (class Wrapped)
(requires TimeSenderTo<wrapped_t<Wrapped>, single<V, E>>)
explicit any_time_single_deferred(Wrapped obj) noexcept(insitu<Wrapped>())
: any_time_single_deferred{std::move(obj), meta::bool_<insitu<Wrapped>()>{}} {
}
~any_time_single_deferred() { ~any_time_single_deferred() {
vptr_->op_(data_, nullptr); vptr_->op_(data_, nullptr);
} }
...@@ -173,7 +176,7 @@ class time_single_deferred_2 { ...@@ -173,7 +176,7 @@ class time_single_deferred_2 {
template <class A, class B, class C> template <class A, class B, class C>
using time_single_deferred_base = using time_single_deferred_base =
meta::if_c< meta::if_c<
TimeSender<A, is_single<>>, (bool)TimeSender<A, is_single<>>,
time_single_deferred_2<A, B, C>, time_single_deferred_2<A, B, C>,
any_time_single_deferred<A, B, C>>; any_time_single_deferred<A, B, C>>;
} // namespace detail } // namespace detail
......
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