Commit 059ca1b2 authored by Eric Niebler's avatar Eric Niebler Committed by Facebook Github Bot

remove executor category properties; refactor, simplify, remove concepts.

Summary:
Now that we have `.schedule()`, We can syntactically determine what things are executors and which are not. We can also tell what kind of executor, be it constrained, or time, or neither. Therefore, we no longer need the `is_executor<>` property query. Nuke it.

In addition, all the `Sender`, `Receiver`, and `Executor` concepts, in addition to testing for the required syntac, took an arbitrary number of properties to query. Those were breaking subsumption relationships (e.g., `Sender<From, is_many<>>` doesn't subsume `Sender<From>`). Move those property queries out of the concept heirarchy and into separate algorithm requirements that test the properties directly.

Reviewed By: kirkshoop

Differential Revision: D14570712

fbshipit-source-id: 8ae0d96e5c9f00dcea3fbff4bbbe04c71bb0df07
parent 323f42e1
...@@ -84,10 +84,7 @@ using countdownmany = countdown<decltype(mi::make_receiver)>; ...@@ -84,10 +84,7 @@ using countdownmany = countdown<decltype(mi::make_receiver)>;
using countdownflowmany = countdown<decltype(mi::make_flow_receiver)>; using countdownflowmany = countdown<decltype(mi::make_flow_receiver)>;
struct inline_time_executor { struct inline_time_executor {
using properties = mi::property_set< using properties = mi::property_set<mi::is_fifo_sequence<>>;
mi::is_executor<>,
mi::is_time<>,
mi::is_fifo_sequence<>>;
struct task { struct task {
std::chrono::system_clock::time_point at; std::chrono::system_clock::time_point at;
...@@ -116,9 +113,7 @@ struct inline_time_executor { ...@@ -116,9 +113,7 @@ struct inline_time_executor {
}; };
struct inline_executor { struct inline_executor {
using properties = mi::property_set< using properties = mi::property_set<mi::is_fifo_sequence<>>;
mi::is_executor<>,
mi::is_fifo_sequence<>>;
struct task { struct task {
using properties = mi::property_set< using properties = mi::property_set<
...@@ -141,9 +136,7 @@ template <class CancellationFactory> ...@@ -141,9 +136,7 @@ template <class CancellationFactory>
struct inline_executor_flow_single { struct inline_executor_flow_single {
CancellationFactory cf; CancellationFactory cf;
using properties = mi::property_set< using properties = mi::property_set<mi::is_fifo_sequence<>>;
mi::is_executor<>,
mi::is_fifo_sequence<>>;
struct task { struct task {
CancellationFactory cf; CancellationFactory cf;
...@@ -225,9 +218,7 @@ using inline_executor_flow_single_entangled = ...@@ -225,9 +218,7 @@ using inline_executor_flow_single_entangled =
inline_executor_flow_single<entangled_cancellation_factory>; inline_executor_flow_single<entangled_cancellation_factory>;
struct inline_executor_flow_single_ignore { struct inline_executor_flow_single_ignore {
using properties = mi::property_set< using properties = mi::property_set<mi::is_fifo_sequence<>>;
mi::is_executor<>,
mi::is_fifo_sequence<>>;
struct task { struct task {
using properties = mi::property_set< using properties = mi::property_set<
...@@ -256,9 +247,7 @@ struct inline_executor_flow_many { ...@@ -256,9 +247,7 @@ struct inline_executor_flow_many {
std::atomic<int>* counter = nullptr; std::atomic<int>* counter = nullptr;
using properties = mi::property_set< using properties = mi::property_set<mi::is_fifo_sequence<>>;
mi::is_executor<>,
mi::is_fifo_sequence<>>;
struct task { struct task {
std::atomic<int>* counter = nullptr; std::atomic<int>* counter = nullptr;
...@@ -322,9 +311,7 @@ struct inline_executor_flow_many { ...@@ -322,9 +311,7 @@ struct inline_executor_flow_many {
}; };
struct inline_executor_flow_many_ignore { struct inline_executor_flow_many_ignore {
using properties = mi::property_set< using properties = mi::property_set<mi::is_fifo_sequence<>>;
mi::is_executor<>,
mi::is_fifo_sequence<>>;
struct task { struct task {
using properties = mi::property_set< using properties = mi::property_set<
...@@ -347,9 +334,7 @@ struct inline_executor_flow_many_ignore { ...@@ -347,9 +334,7 @@ struct inline_executor_flow_many_ignore {
}; };
struct inline_executor_many { struct inline_executor_many {
using properties = mi::property_set< using properties = mi::property_set<mi::is_fifo_sequence<>>;
mi::is_executor<>,
mi::is_fifo_sequence<>>;
struct task { struct task {
using properties = mi::property_set< using properties = mi::property_set<
......
...@@ -33,10 +33,6 @@ template <class PS> ...@@ -33,10 +33,6 @@ template <class PS>
struct has_cardinality : category_query<PS, cardinality_category> {}; struct has_cardinality : category_query<PS, cardinality_category> {};
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool has_cardinality_v = has_cardinality<PS>::value; PUSHMI_INLINE_VAR constexpr bool has_cardinality_v = has_cardinality<PS>::value;
PUSHMI_CONCEPT_DEF(
template(class PS) //
concept Cardinality, //
has_cardinality_v<PS>);
// flow affects both sender and receiver // flow affects both sender and receiver
...@@ -48,12 +44,6 @@ struct receiver_category {}; ...@@ -48,12 +44,6 @@ struct receiver_category {};
struct sender_category {}; struct sender_category {};
// for executors
// time and constrained are mutually exclusive refinements of executor (time is
// a special case of constrained and may be folded in later)
struct executor_category {};
// blocking affects senders // blocking affects senders
struct blocking_category {}; struct blocking_category {};
...@@ -62,7 +52,7 @@ struct blocking_category {}; ...@@ -62,7 +52,7 @@ struct blocking_category {};
struct sequence_category {}; struct sequence_category {};
// Single trait and tag // is_single trait and tag
template <class... TN> template <class... TN>
struct is_single; struct is_single;
// Tag // Tag
...@@ -75,12 +65,8 @@ template <class PS> ...@@ -75,12 +65,8 @@ template <class PS>
struct is_single<PS> : property_query<PS, is_single<>> {}; struct is_single<PS> : property_query<PS, is_single<>> {};
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_single_v = is_single<PS>::value; PUSHMI_INLINE_VAR constexpr bool is_single_v = is_single<PS>::value;
PUSHMI_CONCEPT_DEF(
template(class PS) //
concept Single, //
is_single_v<PS>);
// Many trait and tag // is_many trait and tag
template <class... TN> template <class... TN>
struct is_many; struct is_many;
// Tag // Tag
...@@ -93,12 +79,8 @@ template <class PS> ...@@ -93,12 +79,8 @@ template <class PS>
struct is_many<PS> : property_query<PS, is_many<>> {}; struct is_many<PS> : property_query<PS, is_many<>> {};
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_many_v = is_many<PS>::value; PUSHMI_INLINE_VAR constexpr bool is_many_v = is_many<PS>::value;
PUSHMI_CONCEPT_DEF(
template(class PS) //
concept Many, //
is_many_v<PS>);
// Flow trait and tag // is_flow trait and tag
template <class... TN> template <class... TN>
struct is_flow; struct is_flow;
// Tag // Tag
...@@ -111,10 +93,6 @@ template <class PS> ...@@ -111,10 +93,6 @@ template <class PS>
struct is_flow<PS> : property_query<PS, is_flow<>> {}; struct is_flow<PS> : property_query<PS, is_flow<>> {};
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_flow_v = is_flow<PS>::value; PUSHMI_INLINE_VAR constexpr bool is_flow_v = is_flow<PS>::value;
PUSHMI_CONCEPT_DEF(
template(class PS) //
concept Flow, //
is_flow_v<PS>);
// Receiver trait and tag // Receiver trait and tag
template <class... TN> template <class... TN>
...@@ -130,6 +108,32 @@ struct is_receiver<PS> : property_query<PS, is_receiver<>> {}; ...@@ -130,6 +108,32 @@ struct is_receiver<PS> : property_query<PS, is_receiver<>> {};
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_receiver_v = is_receiver<PS>::value; PUSHMI_INLINE_VAR constexpr bool is_receiver_v = is_receiver<PS>::value;
// add concepts to support receivers
//
PUSHMI_CONCEPT_DEF(
template(class R) //
(concept Receiver)(R), //
requires(R& r) //
(set_done(r)) &&
SemiMovable<std::decay_t<R>> &&
is_receiver_v<R>);
PUSHMI_CONCEPT_DEF(
template(class R, class... VN) //
(concept ReceiveValue)(R, VN...), //
requires(R& r) //
(set_value(r, std::declval<VN&&>()...)) &&
Receiver<R>&& And<MoveConstructible<VN>...>);
PUSHMI_CONCEPT_DEF(
template(class R, class E = std::exception_ptr) //
(concept ReceiveError)(R, E), //
requires(R& r, E&& e)( //
set_error(r, (E &&) e)) &&
Receiver<R> && MoveConstructible<E>
);
// Sender trait and tag // Sender trait and tag
template <class... TN> template <class... TN>
struct is_sender; struct is_sender;
...@@ -144,53 +148,28 @@ struct is_sender<PS> : property_query<PS, is_sender<>> {}; ...@@ -144,53 +148,28 @@ struct is_sender<PS> : property_query<PS, is_sender<>> {};
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_sender_v = is_sender<PS>::value; PUSHMI_INLINE_VAR constexpr bool is_sender_v = is_sender<PS>::value;
// Executor trait and tag // add concepts to support senders
template <class... TN> //
struct is_executor;
// Tag
template <>
struct is_executor<> {
using property_category = executor_category;
};
// Trait
template <class PS>
struct is_executor<PS> : property_query<PS, is_executor<>> {};
template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_executor_v = is_executor<PS>::value;
// Constrained trait and tag
template <class... TN>
struct is_constrained;
// Tag
template <>
struct is_constrained<> : is_executor<> {};
// Trait
template <class PS>
struct is_constrained<PS> : property_query<PS, is_constrained<>> {};
template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_constrained_v = is_constrained<PS>::value;
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class PS) // template(class S) //
concept Constrained, // (concept SenderImpl)(S), //
is_constrained_v<PS>&& is_executor_v<PS>); SemiMovable<S>&& has_cardinality_v<S>&&
is_sender_v<S>);
PUSHMI_CONCEPT_DEF(
template(class S) //
(concept Sender)(S), //
SenderImpl<std::decay_t<S>>);
// Time trait and tag
template <class... TN>
struct is_time;
// Tag
template <>
struct is_time<> : is_constrained<> {};
// Trait
template <class PS>
struct is_time<PS> : property_query<PS, is_time<>> {};
template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_time_v = is_time<PS>::value;
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class PS) // template(class S, class R) //
concept Time, // (concept SenderTo)(S, R), //
is_time_v<PS>&& is_constrained_v<PS>&& is_executor_v<PS>); requires(S&& s, R&& r) //
(submit((S &&) s, (R &&) r)) &&
Sender<S> && Receiver<R>);
// AlwaysBlocking trait and tag // is_always_blocking trait and tag
template <class... TN> template <class... TN>
struct is_always_blocking; struct is_always_blocking;
// Tag // Tag
...@@ -204,12 +183,8 @@ struct is_always_blocking<PS> : property_query<PS, is_always_blocking<>> {}; ...@@ -204,12 +183,8 @@ struct is_always_blocking<PS> : property_query<PS, is_always_blocking<>> {};
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_always_blocking_v = PUSHMI_INLINE_VAR constexpr bool is_always_blocking_v =
is_always_blocking<PS>::value; is_always_blocking<PS>::value;
PUSHMI_CONCEPT_DEF(
template(class PS) //
concept AlwaysBlocking, //
is_always_blocking_v<PS>&& is_sender_v<PS>);
// NeverBlocking trait and tag // is_never_blocking trait and tag
template <class... TN> template <class... TN>
struct is_never_blocking; struct is_never_blocking;
// Tag // Tag
...@@ -223,12 +198,8 @@ struct is_never_blocking<PS> : property_query<PS, is_never_blocking<>> {}; ...@@ -223,12 +198,8 @@ struct is_never_blocking<PS> : property_query<PS, is_never_blocking<>> {};
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_never_blocking_v = PUSHMI_INLINE_VAR constexpr bool is_never_blocking_v =
is_never_blocking<PS>::value; is_never_blocking<PS>::value;
PUSHMI_CONCEPT_DEF(
template(class PS) //
concept NeverBlocking, //
is_never_blocking_v<PS>&& is_sender_v<PS>);
// MaybeBlocking trait and tag // is_maybe_blocking trait and tag
template <class... TN> template <class... TN>
struct is_maybe_blocking; struct is_maybe_blocking;
// Tag // Tag
...@@ -242,12 +213,8 @@ struct is_maybe_blocking<PS> : property_query<PS, is_maybe_blocking<>> {}; ...@@ -242,12 +213,8 @@ struct is_maybe_blocking<PS> : property_query<PS, is_maybe_blocking<>> {};
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_maybe_blocking_v = PUSHMI_INLINE_VAR constexpr bool is_maybe_blocking_v =
is_maybe_blocking<PS>::value; is_maybe_blocking<PS>::value;
PUSHMI_CONCEPT_DEF(
template(class PS) //
concept MaybeBlocking, //
is_maybe_blocking_v<PS>&& is_sender_v<PS>);
// FifoSequence trait and tag // is_fifo_sequence trait and tag
template <class... TN> template <class... TN>
struct is_fifo_sequence; struct is_fifo_sequence;
// Tag // Tag
...@@ -261,12 +228,8 @@ struct is_fifo_sequence<PS> : property_query<PS, is_fifo_sequence<>> {}; ...@@ -261,12 +228,8 @@ struct is_fifo_sequence<PS> : property_query<PS, is_fifo_sequence<>> {};
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_fifo_sequence_v = PUSHMI_INLINE_VAR constexpr bool is_fifo_sequence_v =
is_fifo_sequence<PS>::value; is_fifo_sequence<PS>::value;
PUSHMI_CONCEPT_DEF(
template(class PS) //
concept FifoSequence, //
is_fifo_sequence_v<PS>&& is_executor_v<PS>);
// ConcurrentSequence trait and tag // is_concurrent_sequence trait and tag
template <class... TN> template <class... TN>
struct is_concurrent_sequence; struct is_concurrent_sequence;
// Tag // Tag
...@@ -281,46 +244,49 @@ struct is_concurrent_sequence<PS> ...@@ -281,46 +244,49 @@ struct is_concurrent_sequence<PS>
template <class PS> template <class PS>
PUSHMI_INLINE_VAR constexpr bool is_concurrent_sequence_v = PUSHMI_INLINE_VAR constexpr bool is_concurrent_sequence_v =
is_concurrent_sequence<PS>::value; is_concurrent_sequence<PS>::value;
PUSHMI_CONCEPT_DEF(
template(class PS) //
concept ConcurrentSequence, //
is_concurrent_sequence_v<PS>&& is_executor_v<PS>);
// concepts to support execution // concepts to support execution
// //
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class Exec, class... PropertyN) // template(class Exec) //
(concept Executor)(Exec, PropertyN...), // (concept Executor)(Exec), //
requires(Exec& exec) // requires(Exec& exec)( //
(schedule(exec), requires_<is_sender_v<decltype(schedule(exec))>>) && schedule(exec),
SemiMovable<std::decay_t<Exec>> && property_query_v<Exec, PropertyN...> && requires_<Sender<decltype(schedule(exec))>>) &&
is_executor_v<Exec>); SemiMovable<std::decay_t<Exec>>);
template <class Exec> template <class Exec, class... Args>
PUSHMI_PP_CONSTRAINED_USING( PUSHMI_PP_CONSTRAINED_USING(
Executor<Exec>, Executor<Exec>,
sender_t =, sender_t =,
decltype(schedule(std::declval<Exec&>()))); decltype(schedule(std::declval<Exec&>(), std::declval<Args>()...)));
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class Exec, class... PropertyN) // template(class Exec) //
(concept ExecutorProvider)(Exec, PropertyN...), // (concept ExecutorProvider)(Exec), //
requires(Exec& exec) // requires(Exec& exec)( //
(get_executor(exec), get_executor(exec),
requires_<Executor<decltype(get_executor(exec))>>) && requires_<Executor<decltype(get_executor(exec))>>) &&
SemiMovable<std::decay_t<Exec>> && property_query_v<Exec, PropertyN...>); SemiMovable<std::decay_t<Exec>>);
template <class S>
PUSHMI_PP_CONSTRAINED_USING(
ExecutorProvider<S>,
executor_t =,
decltype(get_executor(std::declval<S&>())));
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class Exec, class... PropertyN) // template(class Exec) //
(concept Strand)(Exec, PropertyN...), // (concept Strand)(Exec), //
Executor<Exec>&& property_query_v<Exec, is_fifo_sequence<>, PropertyN...>); Executor<Exec>&&
is_fifo_sequence_v<Exec>);
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class Exec) // template(class Exec) //
(concept StrandFactory)(Exec), // (concept StrandFactory)(Exec), //
requires(Exec& exec) // requires(Exec& exec)( //
(make_strand(exec), requires_<Strand<decltype(make_strand(exec))>>) && make_strand(exec), requires_<Strand<decltype(make_strand(exec))>>) &&
SemiMovable<std::decay_t<Exec>>); SemiMovable<std::decay_t<Exec>>);
template <class Exec> template <class Exec>
...@@ -336,17 +302,16 @@ PUSHMI_PP_CONSTRAINED_USING( ...@@ -336,17 +302,16 @@ PUSHMI_PP_CONSTRAINED_USING(
// //
// top() returns the constraint value that will cause the item to run asap. // top() returns the constraint value that will cause the item to run asap.
// So now() for time and NORMAL for priority. // So now() for time and NORMAL for priority.
//
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class Exec, class... PropertyN) // template(class Exec) //
(concept ConstrainedExecutor)(Exec, PropertyN...), // (concept ConstrainedExecutor)(Exec), //
requires(Exec& exec) // requires(Exec& exec)( //
(top(exec), top(exec),
requires_<Regular<decltype(top(exec))>>, requires_<Regular<decltype(top(exec))>>,
schedule(exec, top(exec)), schedule(exec, top(exec)),
requires_<is_sender_v<decltype(schedule(exec, top(exec)))>>) && requires_<Sender<decltype(schedule(exec, top(exec)))>>) &&
Executor<Exec, is_constrained<>, PropertyN...>); Executor<Exec>);
template <class Exec> template <class Exec>
PUSHMI_PP_CONSTRAINED_USING( PUSHMI_PP_CONSTRAINED_USING(
...@@ -355,13 +320,36 @@ PUSHMI_PP_CONSTRAINED_USING( ...@@ -355,13 +320,36 @@ PUSHMI_PP_CONSTRAINED_USING(
decltype(top(std::declval<Exec&>()))); decltype(top(std::declval<Exec&>())));
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class Exec, class... PropertyN) // template(class Exec, class TP, class Duration) //
(concept TimeExecutor)(Exec, PropertyN...), // concept TimeExecutorImpl2_, //
requires(Exec& exec) // requires(Exec& exec, TP tp, Duration d)( //
(now(exec), requires_<Sender<decltype(exec.schedule(tp + d))>>,
requires_<Sender<decltype(exec.schedule(d + tp))>>,
requires_<Sender<decltype(exec.schedule(tp - d))>>,
tp += d,
tp -= d));
PUSHMI_CONCEPT_DEF(
template(class Exec, class TP = decltype(now(std::declval<Exec&>()))) //
(concept TimeExecutorImpl_)(Exec, TP), //
Regular<TP> &&
TimeExecutorImpl2_<Exec, TP, std::chrono::nanoseconds> &&
TimeExecutorImpl2_<Exec, TP, std::chrono::microseconds> &&
TimeExecutorImpl2_<Exec, TP, std::chrono::milliseconds> &&
TimeExecutorImpl2_<Exec, TP, std::chrono::seconds> &&
TimeExecutorImpl2_<Exec, TP, std::chrono::minutes> &&
TimeExecutorImpl2_<Exec, TP, std::chrono::hours> &&
TimeExecutorImpl2_<Exec, TP, decltype(TP{} - TP{})>);
PUSHMI_CONCEPT_DEF(
template(class Exec) //
(concept TimeExecutor)(Exec), //
requires(Exec& exec)( //
now(exec),
schedule(exec, now(exec)), schedule(exec, now(exec)),
requires_<Regular<decltype(now(exec) + std::chrono::seconds(1))>>) && requires_<Sender<decltype(schedule(exec, now(exec)))>>) &&
ConstrainedExecutor<Exec, is_time<>, PropertyN...>); ConstrainedExecutor<Exec> &&
TimeExecutorImpl_<Exec>);
template <class Exec> template <class Exec>
PUSHMI_PP_CONSTRAINED_USING( PUSHMI_PP_CONSTRAINED_USING(
...@@ -369,95 +357,42 @@ PUSHMI_PP_CONSTRAINED_USING( ...@@ -369,95 +357,42 @@ PUSHMI_PP_CONSTRAINED_USING(
time_point_t =, time_point_t =,
decltype(now(std::declval<Exec&>()))); decltype(now(std::declval<Exec&>())));
// add concepts to support receivers
//
PUSHMI_CONCEPT_DEF(
template(class R, class... PropertyN) //
(concept Receiver)(R, PropertyN...), //
requires(R& r) //
(set_done(r)) &&
SemiMovable<std::decay_t<R>> &&
property_query_v<R, PropertyN...> &&
is_receiver_v<R> && !is_sender_v<R>
);
PUSHMI_CONCEPT_DEF(
template(class R, class... VN) //
(concept ReceiveValue)(R, VN...), //
requires(R& r) //
(set_value(r, std::declval<VN&&>()...)) &&
Receiver<R>&& And<MoveConstructible<VN>...>);
PUSHMI_CONCEPT_DEF(
template(class R, class E = std::exception_ptr) //
(concept ReceiveError)(R, E), //
requires(R& r, E&& e)( //
set_error(r, (E &&) e)) &&
Receiver<R> && MoveConstructible<E>);
// add concepts to support senders
//
PUSHMI_CONCEPT_DEF(
template(class S, class... PropertyN) //
(concept SenderImpl)(S, PropertyN...), //
SemiMovable<S>&& Cardinality<S>&& property_query_v<S, PropertyN...>&&
is_sender_v<S> &&
!is_receiver_v<S>);
PUSHMI_CONCEPT_DEF(
template(class S, class... PropertyN) //
(concept Sender)(S, PropertyN...), //
SenderImpl<std::decay_t<S>, PropertyN...>);
PUSHMI_CONCEPT_DEF(
template(class S, class R, class... PropertyN) //
(concept SenderTo)(S, R, PropertyN...), //
requires(S&& s, R&& r) //
(submit((S &&) s, (R &&) r)) &&
Sender<S, PropertyN...> && Receiver<R>);
template <class S>
PUSHMI_PP_CONSTRAINED_USING(
Sender<S>,
executor_t =,
decltype(get_executor(std::declval<S&>())));
// add concepts to support cancellation and rate control // add concepts to support cancellation and rate control
// //
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class R, class... PropertyN) // template(class R) //
(concept FlowReceiver)(R, PropertyN...), // (concept FlowReceiver)(R), //
Receiver<R>&& property_query_v<R, PropertyN...>&& Flow<R>); Receiver<R>&&
is_flow_v<R>);
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class R, class... VN) // template(class R, class... VN) //
(concept FlowReceiveValue)(R, VN...), // (concept FlowReceiveValue)(R, VN...), //
Flow<R>&& ReceiveValue<R, VN...>); is_flow_v<R>&& ReceiveValue<R, VN...>);
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class R, class E = std::exception_ptr) // template(class R, class E = std::exception_ptr) //
(concept FlowReceiveError)(R, E), // (concept FlowReceiveError)(R, E), //
Flow<R>&& ReceiveError<R, E>); is_flow_v<R>&& ReceiveError<R, E>);
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class R, class Up) // template(class R, class Up) //
(concept FlowUpTo)(R, Up), // (concept FlowUpTo)(R, Up), //
requires(R& r, Up&& up) // requires(R& r, Up&& up)( //
(set_starting(r, (Up &&) up)) && set_starting(r, (Up &&) up)) &&
Flow<R>); is_flow_v<R>);
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class S, class... PropertyN) // template(class S) //
(concept FlowSender)(S, PropertyN...), // (concept FlowSender)(S), //
Sender<S>&& property_query_v<S, PropertyN...>&& Flow<S>); Sender<S>&&
is_flow_v<S>);
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template(class S, class R, class... PropertyN) // template(class S, class R) //
(concept FlowSenderTo)(S, R, PropertyN...), // (concept FlowSenderTo)(S, R), //
FlowSender<S>&& SenderTo<S, R>&& property_query_v<S, PropertyN...>&& FlowSender<S>&& SenderTo<S, R>&&
FlowReceiver<R>); FlowReceiver<R>);
} // namespace pushmi } // namespace pushmi
......
...@@ -32,7 +32,7 @@ class pool_executor { ...@@ -32,7 +32,7 @@ class pool_executor {
public: public:
using properties = using properties =
property_set<is_executor<>, is_concurrent_sequence<>>; property_set<is_concurrent_sequence<>>;
pool_executor() = default; pool_executor() = default;
explicit pool_executor(pool &e); explicit pool_executor(pool &e);
......
...@@ -103,7 +103,7 @@ class any_executor { ...@@ -103,7 +103,7 @@ class any_executor {
std::enable_if_t<!std::is_same<U, any_executor>::value, U>; std::enable_if_t<!std::is_same<U, any_executor>::value, U>;
public: public:
using properties = property_set<is_executor<>>; using properties = property_set<>;
any_executor() = default; any_executor() = default;
any_executor(const any_executor& that) noexcept : any_executor() { any_executor(const any_executor& that) noexcept : any_executor() {
...@@ -147,7 +147,7 @@ class executor<SF> { ...@@ -147,7 +147,7 @@ class executor<SF> {
SF sf_; SF sf_;
public: public:
using properties = property_set<is_executor<>>; using properties = property_set<>;
constexpr executor() = default; constexpr executor() = default;
constexpr explicit executor(SF sf) : sf_(std::move(sf)) {} constexpr explicit executor(SF sf) : sf_(std::move(sf)) {}
...@@ -167,9 +167,7 @@ class executor<Data, DSF> { ...@@ -167,9 +167,7 @@ class executor<Data, DSF> {
DSF sf_; DSF sf_;
public: public:
using properties = property_set_insert_t< using properties = properties_t<Data>;
properties_t<Data>,
property_set<is_executor<>>>;
constexpr executor() = default; constexpr executor() = default;
constexpr explicit executor(Data data) : data_(std::move(data)) {} constexpr explicit executor(Data data) : data_(std::move(data)) {}
...@@ -257,7 +255,7 @@ struct any_executor_ref { ...@@ -257,7 +255,7 @@ struct any_executor_ref {
using wrapped_t = detail::not_any_executor_ref_t<T>; using wrapped_t = detail::not_any_executor_ref_t<T>;
public: public:
using properties = property_set<is_executor<>>; using properties = property_set<>;
any_executor_ref() = delete; any_executor_ref() = delete;
any_executor_ref(const any_executor_ref&) = default; any_executor_ref(const any_executor_ref&) = default;
...@@ -416,7 +414,7 @@ class any_constrained_executor { ...@@ -416,7 +414,7 @@ class any_constrained_executor {
std::enable_if_t<!std::is_same<U, any_constrained_executor>::value, U>; std::enable_if_t<!std::is_same<U, any_constrained_executor>::value, U>;
public: public:
using properties = property_set<is_constrained<>>; using properties = property_set<>;
any_constrained_executor() = default; any_constrained_executor() = default;
any_constrained_executor(const any_constrained_executor& that) noexcept any_constrained_executor(const any_constrained_executor& that) noexcept
...@@ -469,7 +467,7 @@ class constrained_executor<SF, ZF> { ...@@ -469,7 +467,7 @@ class constrained_executor<SF, ZF> {
ZF zf_; ZF zf_;
public: public:
using properties = property_set<is_constrained<>>; using properties = property_set<>;
constexpr constrained_executor() = default; constexpr constrained_executor() = default;
constexpr explicit constrained_executor(SF sf) : sf_(std::move(sf)) {} constexpr explicit constrained_executor(SF sf) : sf_(std::move(sf)) {}
...@@ -496,9 +494,7 @@ class constrained_executor<Data, DSF, DZF> { ...@@ -496,9 +494,7 @@ class constrained_executor<Data, DSF, DZF> {
DZF zf_; DZF zf_;
public: public:
using properties = property_set_insert_t< using properties = properties_t<Data>;
properties_t<Data>,
property_set<is_constrained<>>>;
constexpr constrained_executor() = default; constexpr constrained_executor() = default;
constexpr explicit constrained_executor(Data data) : data_(std::move(data)) {} constexpr explicit constrained_executor(Data data) : data_(std::move(data)) {}
...@@ -617,7 +613,7 @@ struct any_constrained_executor_ref { ...@@ -617,7 +613,7 @@ struct any_constrained_executor_ref {
using wrapped_t = detail::not_any_constrained_executor_ref_t<T>; using wrapped_t = detail::not_any_constrained_executor_ref_t<T>;
public: public:
using properties = property_set<is_constrained<>>; using properties = property_set<>;
any_constrained_executor_ref() = delete; any_constrained_executor_ref() = delete;
any_constrained_executor_ref(const any_constrained_executor_ref&) = default; any_constrained_executor_ref(const any_constrained_executor_ref&) = default;
...@@ -792,7 +788,7 @@ class any_time_executor { ...@@ -792,7 +788,7 @@ class any_time_executor {
std::enable_if_t<!std::is_same<U, any_time_executor>::value, U>; std::enable_if_t<!std::is_same<U, any_time_executor>::value, U>;
public: public:
using properties = property_set<is_time<>>; using properties = property_set<>;
any_time_executor() = default; any_time_executor() = default;
any_time_executor(const any_time_executor& that) noexcept : any_time_executor() { any_time_executor(const any_time_executor& that) noexcept : any_time_executor() {
...@@ -843,7 +839,7 @@ class time_executor<SF, NF> { ...@@ -843,7 +839,7 @@ class time_executor<SF, NF> {
NF nf_; NF nf_;
public: public:
using properties = property_set<is_time<>>; using properties = property_set<>;
constexpr time_executor() = default; constexpr time_executor() = default;
constexpr explicit time_executor(SF sf) : sf_(std::move(sf)) {} constexpr explicit time_executor(SF sf) : sf_(std::move(sf)) {}
...@@ -870,9 +866,7 @@ class time_executor<Data, DSF, DNF> { ...@@ -870,9 +866,7 @@ class time_executor<Data, DSF, DNF> {
DNF nf_; DNF nf_;
public: public:
using properties = property_set_insert_t< using properties = properties_t<Data>;
properties_t<Data>,
property_set<is_time<>>>;
constexpr time_executor() = default; constexpr time_executor() = default;
constexpr explicit time_executor(Data data) : data_(std::move(data)) {} constexpr explicit time_executor(Data data) : data_(std::move(data)) {}
...@@ -991,7 +985,7 @@ struct any_time_executor_ref { ...@@ -991,7 +985,7 @@ struct any_time_executor_ref {
using wrapped_t = detail::not_any_time_executor_ref_t<T>; using wrapped_t = detail::not_any_time_executor_ref_t<T>;
public: public:
using properties = property_set<is_time<>>; using properties = property_set<>;
any_time_executor_ref() = delete; any_time_executor_ref() = delete;
any_time_executor_ref(const any_time_executor_ref&) = default; any_time_executor_ref(const any_time_executor_ref&) = default;
......
...@@ -91,7 +91,7 @@ class any_flow_many_sender { ...@@ -91,7 +91,7 @@ class any_flow_many_sender {
std::swap(that.vptr_, vptr_); std::swap(that.vptr_, vptr_);
} }
PUSHMI_TEMPLATE (class Wrapped) PUSHMI_TEMPLATE (class Wrapped)
(requires FlowSender<wrapped_t<Wrapped>, is_many<>>) (requires FlowSender<wrapped_t<Wrapped>> && is_many_v<wrapped_t<Wrapped>>)
explicit any_flow_many_sender(Wrapped obj) noexcept(insitu<Wrapped>()) explicit any_flow_many_sender(Wrapped obj) noexcept(insitu<Wrapped>())
: any_flow_many_sender{std::move(obj), bool_<insitu<Wrapped>()>{}} {} : any_flow_many_sender{std::move(obj), bool_<insitu<Wrapped>()>{}} {}
~any_flow_many_sender() { ~any_flow_many_sender() {
...@@ -173,12 +173,12 @@ PUSHMI_INLINE_VAR constexpr struct make_flow_many_sender_fn { ...@@ -173,12 +173,12 @@ PUSHMI_INLINE_VAR constexpr struct make_flow_many_sender_fn {
return flow_many_sender<SF>{std::move(sf)}; return flow_many_sender<SF>{std::move(sf)};
} }
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires True<> && Sender<Data, is_many<>, is_flow<>>) (requires True<> && FlowSender<Data> && is_many_v<Data>)
auto operator()(Data d) const { auto operator()(Data d) const {
return flow_many_sender<Data, passDSF>{std::move(d)}; return flow_many_sender<Data, passDSF>{std::move(d)};
} }
PUSHMI_TEMPLATE(class Data, class DSF) PUSHMI_TEMPLATE(class Data, class DSF)
(requires Sender<Data, is_many<>, is_flow<>>) (requires FlowSender<Data> && is_many_v<Data>)
auto operator()(Data d, DSF sf) const { auto operator()(Data d, DSF sf) const {
return flow_many_sender<Data, DSF>{std::move(d), std::move(sf)}; return flow_many_sender<Data, DSF>{std::move(d), std::move(sf)};
} }
...@@ -194,11 +194,11 @@ PUSHMI_TEMPLATE(class SF) ...@@ -194,11 +194,11 @@ PUSHMI_TEMPLATE(class SF)
flow_many_sender(SF) -> flow_many_sender<SF>; flow_many_sender(SF) -> flow_many_sender<SF>;
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires True<> && Sender<Data, is_many<>, is_flow<>>) (requires True<> && FlowSender<Data> && is_many_v<Data>)
flow_many_sender(Data) -> flow_many_sender<Data, passDSF>; flow_many_sender(Data) -> flow_many_sender<Data, passDSF>;
PUSHMI_TEMPLATE(class Data, class DSF) PUSHMI_TEMPLATE(class Data, class DSF)
(requires Sender<Data, is_many<>, is_flow<>>) (requires FlowSender<Data> && is_many_v<Data>)
flow_many_sender(Data, DSF) -> flow_many_sender<Data, DSF>; flow_many_sender(Data, DSF) -> flow_many_sender<Data, DSF>;
#endif #endif
......
...@@ -319,7 +319,7 @@ class flow_receiver<> ...@@ -319,7 +319,7 @@ class flow_receiver<>
PUSHMI_CONCEPT_DEF( PUSHMI_CONCEPT_DEF(
template (class T) template (class T)
concept FlowReceiverDataArg, concept FlowReceiverDataArg,
Receiver<T, is_flow<>> && FlowReceiver<T> &&
not Invocable<T&> not Invocable<T&>
); );
......
...@@ -98,7 +98,7 @@ class any_flow_single_sender { ...@@ -98,7 +98,7 @@ class any_flow_single_sender {
std::swap(that.vptr_, vptr_); std::swap(that.vptr_, vptr_);
} }
PUSHMI_TEMPLATE (class Wrapped) PUSHMI_TEMPLATE (class Wrapped)
(requires FlowSender<wrapped_t<Wrapped>, is_single<>>) (requires FlowSender<wrapped_t<Wrapped>> &&is_single_v<wrapped_t<Wrapped>>)
explicit any_flow_single_sender(Wrapped obj) noexcept(insitu<Wrapped>()) explicit any_flow_single_sender(Wrapped obj) noexcept(insitu<Wrapped>())
: any_flow_single_sender{std::move(obj), bool_<insitu<Wrapped>()>{}} {} : any_flow_single_sender{std::move(obj), bool_<insitu<Wrapped>()>{}} {}
~any_flow_single_sender() { ~any_flow_single_sender() {
...@@ -184,12 +184,12 @@ PUSHMI_INLINE_VAR constexpr struct make_flow_single_sender_fn { ...@@ -184,12 +184,12 @@ PUSHMI_INLINE_VAR constexpr struct make_flow_single_sender_fn {
return flow_single_sender<SF>{std::move(sf)}; return flow_single_sender<SF>{std::move(sf)};
} }
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires True<> && Sender<Data, is_single<>, is_flow<>>) (requires True<> && FlowSender<Data> && is_single_v<Data>)
auto operator()(Data d) const { auto operator()(Data d) const {
return flow_single_sender<Data, passDSF>{std::move(d)}; return flow_single_sender<Data, passDSF>{std::move(d)};
} }
PUSHMI_TEMPLATE(class Data, class DSF) PUSHMI_TEMPLATE(class Data, class DSF)
(requires Sender<Data, is_single<>, is_flow<>>) (requires FlowSender<Data> && is_single_v<Data>)
auto operator()(Data d, DSF sf) const { auto operator()(Data d, DSF sf) const {
return flow_single_sender<Data, DSF>{std::move(d), std::move(sf)}; return flow_single_sender<Data, DSF>{std::move(d), std::move(sf)};
} }
...@@ -205,11 +205,11 @@ PUSHMI_TEMPLATE(class SF) ...@@ -205,11 +205,11 @@ PUSHMI_TEMPLATE(class SF)
flow_single_sender(SF) -> flow_single_sender<SF>; flow_single_sender(SF) -> flow_single_sender<SF>;
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires True<> && Sender<Data, is_single<>, is_flow<>>) (requires True<> && FlowSender<Data> && is_single_v<Data>)
flow_single_sender(Data) -> flow_single_sender<Data, passDSF>; flow_single_sender(Data) -> flow_single_sender<Data, passDSF>;
PUSHMI_TEMPLATE(class Data, class DSF) PUSHMI_TEMPLATE(class Data, class DSF)
(requires Sender<Data, is_single<>, is_flow<>>) (requires FlowSender<Data> && is_single_v<Data>)
flow_single_sender(Data, DSF) -> flow_single_sender<Data, DSF>; flow_single_sender(Data, DSF) -> flow_single_sender<Data, DSF>;
#endif #endif
......
...@@ -48,14 +48,6 @@ struct is_receiver; ...@@ -48,14 +48,6 @@ struct is_receiver;
template <class... TN> template <class... TN>
struct is_sender; struct is_sender;
template <class... TN>
struct is_executor;
template <class... TN>
struct is_time;
template <class... TN>
struct is_constrained;
template <class... TN> template <class... TN>
struct is_always_blocking; struct is_always_blocking;
......
...@@ -22,9 +22,7 @@ namespace pushmi { ...@@ -22,9 +22,7 @@ namespace pushmi {
class inline_constrained_executor_t { class inline_constrained_executor_t {
public: public:
using properties = property_set< using properties = property_set<is_fifo_sequence<>>;
is_constrained<>,
is_fifo_sequence<>>;
template<class CV> template<class CV>
struct task { struct task {
...@@ -65,9 +63,7 @@ inline inline_constrained_executor_t inline_constrained_executor() { ...@@ -65,9 +63,7 @@ inline inline_constrained_executor_t inline_constrained_executor() {
class inline_time_executor_t { class inline_time_executor_t {
public: public:
using properties = property_set< using properties = property_set<is_fifo_sequence<>>;
is_time<>,
is_fifo_sequence<>>;
template<class TP> template<class TP>
struct task { struct task {
...@@ -110,9 +106,7 @@ inline inline_time_executor_t inline_time_executor() { ...@@ -110,9 +106,7 @@ inline inline_time_executor_t inline_time_executor() {
class inline_executor_t { class inline_executor_t {
public: public:
using properties = property_set< using properties = property_set<is_fifo_sequence<>>;
is_executor<>,
is_fifo_sequence<>>;
struct task { struct task {
using properties = property_set< using properties = property_set<
......
...@@ -91,10 +91,8 @@ class any_many_sender { ...@@ -91,10 +91,8 @@ class any_many_sender {
} }
PUSHMI_TEMPLATE(class Wrapped) PUSHMI_TEMPLATE(class Wrapped)
(requires SenderTo< (requires SenderTo<wrapped_t<Wrapped>, any_receiver<E, VN...>> &&
wrapped_t<Wrapped>, is_many_v<wrapped_t<Wrapped>>) //
any_receiver<E, VN...>,
is_many<>>) //
explicit any_many_sender(Wrapped obj) // explicit any_many_sender(Wrapped obj) //
noexcept(insitu<Wrapped>()) noexcept(insitu<Wrapped>())
: any_many_sender{std::move(obj), bool_<insitu<Wrapped>()>{}} {} : any_many_sender{std::move(obj), bool_<insitu<Wrapped>()>{}} {}
...@@ -184,13 +182,13 @@ PUSHMI_INLINE_VAR constexpr struct make_many_sender_fn { ...@@ -184,13 +182,13 @@ PUSHMI_INLINE_VAR constexpr struct make_many_sender_fn {
return many_sender<SF>{std::move(sf)}; return many_sender<SF>{std::move(sf)};
} }
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires True<>&& Sender<Data, is_many<>>) // (requires True<>&& Sender<Data> && is_many_v<Data>) //
auto auto
operator()(Data d) const { operator()(Data d) const {
return many_sender<Data, passDSF>{std::move(d)}; return many_sender<Data, passDSF>{std::move(d)};
} }
PUSHMI_TEMPLATE(class Data, class DSF) PUSHMI_TEMPLATE(class Data, class DSF)
(requires Sender<Data, is_many<>>) // (requires Sender<Data> && is_many_v<Data>) //
auto auto
operator()(Data d, DSF sf) const { operator()(Data d, DSF sf) const {
return many_sender<Data, DSF>{std::move(d), std::move(sf)}; return many_sender<Data, DSF>{std::move(d), std::move(sf)};
...@@ -208,12 +206,12 @@ PUSHMI_TEMPLATE(class SF) ...@@ -208,12 +206,12 @@ PUSHMI_TEMPLATE(class SF)
->many_sender<SF>; ->many_sender<SF>;
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires True<>&& Sender<Data, is_many<>>) // (requires True<>&& Sender<Data> && is_many_v<Data>) //
many_sender(Data) many_sender(Data)
->many_sender<Data, passDSF>; ->many_sender<Data, passDSF>;
PUSHMI_TEMPLATE(class Data, class DSF) PUSHMI_TEMPLATE(class Data, class DSF)
(requires Sender<Data, is_many<>>) // (requires Sender<Data> && is_many_v<Data>) //
many_sender(Data, DSF) many_sender(Data, DSF)
->many_sender<Data, DSF>; ->many_sender<Data, DSF>;
#endif #endif
......
...@@ -45,7 +45,7 @@ struct new_thread_task { ...@@ -45,7 +45,7 @@ struct new_thread_task {
}; };
struct new_thread_executor { struct new_thread_executor {
using properties = property_set<is_executor<>, is_concurrent_sequence<>>; using properties = property_set<is_concurrent_sequence<>>;
new_thread_task schedule() { new_thread_task schedule() {
return {}; return {};
......
...@@ -75,7 +75,7 @@ struct for_each_fn { ...@@ -75,7 +75,7 @@ struct for_each_fn {
struct fn { struct fn {
std::tuple<AN...> args_; std::tuple<AN...> args_;
PUSHMI_TEMPLATE(class In) PUSHMI_TEMPLATE(class In)
(requires Sender<In>&& Flow<In>&& Many<In>) (requires FlowSender<In>&& is_many_v<In>)
In operator()(In in) { In operator()(In in) {
auto out{::folly::pushmi::detail::receiver_from_fn<subset< auto out{::folly::pushmi::detail::receiver_from_fn<subset<
is_sender<>, is_sender<>,
......
...@@ -120,16 +120,22 @@ struct blocking_submit_fn { ...@@ -120,16 +120,22 @@ struct blocking_submit_fn {
using properties = properties_t<Exec>; using properties = properties_t<Exec>;
PUSHMI_TEMPLATE(class... ZN) PUSHMI_TEMPLATE(class Exec_ = Exec)
(requires Constrained<Exec>) // (requires ConstrainedExecutor<Exec_>) //
auto top() { auto top() {
return ::folly::pushmi::top(ex_); return ::folly::pushmi::top(ex_);
} }
template<class... VN> auto schedule() {
auto schedule(VN&&... vn) {
auto protected_scope = protect_stack{state_}; auto protected_scope = protect_stack{state_};
return nested_task_impl<decltype(::folly::pushmi::schedule(ex_, (VN&&)vn...))>{ return nested_task_impl<decltype(::folly::pushmi::schedule(ex_))>{
state_, ::folly::pushmi::schedule(ex_, (VN&&)vn...)}; state_, ::folly::pushmi::schedule(ex_)};
}
PUSHMI_TEMPLATE(class Exec_ = Exec)
(requires ConstrainedExecutor<Exec_>) //
auto schedule(constraint_t<Exec_> top) {
auto protected_scope = protect_stack{state_};
return nested_task_impl<sender_t<Exec_, constraint_t<Exec_>>>{
state_, ::folly::pushmi::schedule(ex_, std::move(top))};
} }
}; };
...@@ -272,7 +278,7 @@ struct blocking_submit_fn { ...@@ -272,7 +278,7 @@ struct blocking_submit_fn {
receiver_impl<std::decay_t<In>>&, receiver_impl<std::decay_t<In>>&,
lock_state*, lock_state*,
std::tuple<AN...>&&>> && std::tuple<AN...>&&>> &&
not AlwaysBlocking<In>) // not is_always_blocking_v<In>) //
void void
operator()(In&& in) { operator()(In&& in) {
lock_state state{}; lock_state state{};
...@@ -331,8 +337,10 @@ struct get_fn { ...@@ -331,8 +337,10 @@ struct get_fn {
static_assert( static_assert(
SenderTo<In, Out>, SenderTo<In, Out>,
"'In' does not deliver value compatible with 'T' to 'Out'"); "'In' does not deliver value compatible with 'T' to 'Out'");
std::conditional_t<AlwaysBlocking<In>, submit_fn, blocking_submit_fn>{}( std::conditional_t<
std::move(out))(std::move(in)); is_always_blocking_v<In>,
submit_fn,
blocking_submit_fn>{}(std::move(out))(std::move(in));
if (!!ep_) { if (!!ep_) {
std::rethrow_exception(*ep_); std::rethrow_exception(*ep_);
} }
......
...@@ -71,8 +71,7 @@ struct transform_on<F, is_single<>, true> { ...@@ -71,8 +71,7 @@ struct transform_on<F, is_single<>, true> {
::folly::pushmi::SemiMovable<Result>, ::folly::pushmi::SemiMovable<Result>,
"none of the functions supplied to transform can convert this value"); "none of the functions supplied to transform can convert this value");
static_assert( static_assert(
::folly::pushmi::Flow<Out> && ::folly::pushmi::FlowReceiveValue<Out, Result>,
::folly::pushmi::ReceiveValue<Out, Result>,
"Result of value transform cannot be delivered to Out"); "Result of value transform cannot be delivered to Out");
set_value(out, f_((V0 &&) v0, (VN &&) vn...)); set_value(out, f_((V0 &&) v0, (VN &&) vn...));
} }
...@@ -116,8 +115,7 @@ struct transform_on<F, is_many<>, true> { ...@@ -116,8 +115,7 @@ struct transform_on<F, is_many<>, true> {
::folly::pushmi::SemiMovable<Result>, ::folly::pushmi::SemiMovable<Result>,
"none of the functions supplied to transform can convert this value"); "none of the functions supplied to transform can convert this value");
static_assert( static_assert(
::folly::pushmi::Flow<Out> && ::folly::pushmi::FlowReceiveValue<Out, Result>,
::folly::pushmi::ReceiveValue<Out, Result>,
"Result of value transform cannot be delivered to Out"); "Result of value transform cannot be delivered to Out");
set_value(out, f_((V0 &&) v0, (VN &&) vn...)); set_value(out, f_((V0 &&) v0, (VN &&) vn...));
} }
......
...@@ -497,7 +497,7 @@ template<> ...@@ -497,7 +497,7 @@ template<>
struct construct_deduced<receiver> : make_receiver_fn {}; struct construct_deduced<receiver> : make_receiver_fn {};
PUSHMI_TEMPLATE (class T, class In) PUSHMI_TEMPLATE (class T, class In)
(requires SenderTo<In, std::promise<T>, is_single<>>) (requires SenderTo<In, std::promise<T>> && is_single_v<In>)
std::future<T> future_from(In&& in) { std::future<T> future_from(In&& in) {
std::promise<T> p; std::promise<T> p;
auto result = p.get_future(); auto result = p.get_future();
...@@ -505,7 +505,7 @@ std::future<T> future_from(In&& in) { ...@@ -505,7 +505,7 @@ std::future<T> future_from(In&& in) {
return result; return result;
} }
PUSHMI_TEMPLATE (class In) PUSHMI_TEMPLATE (class In)
(requires SenderTo<In, std::promise<void>, is_single<>>) (requires SenderTo<In, std::promise<void>> && is_single_v<In>)
std::future<void> future_from(In&& in) { std::future<void> future_from(In&& in) {
std::promise<void> p; std::promise<void> p;
auto result = p.get_future(); auto result = p.get_future();
......
...@@ -218,13 +218,13 @@ PUSHMI_INLINE_VAR constexpr struct make_single_sender_fn { ...@@ -218,13 +218,13 @@ PUSHMI_INLINE_VAR constexpr struct make_single_sender_fn {
return single_sender<SF>{std::move(sf)}; return single_sender<SF>{std::move(sf)};
} }
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires True<>&& Sender<Data, is_single<>>) // (requires True<>&& Sender<Data> && is_single_v<Data>) //
auto auto
operator()(Data d) const { operator()(Data d) const {
return single_sender<Data, passDSF>{std::move(d)}; return single_sender<Data, passDSF>{std::move(d)};
} }
PUSHMI_TEMPLATE(class Data, class DSF) PUSHMI_TEMPLATE(class Data, class DSF)
(requires Sender<Data, is_single<>>) // (requires Sender<Data> && is_single_v<Data>) //
auto auto
operator()(Data d, DSF sf) const { operator()(Data d, DSF sf) const {
return single_sender<Data, DSF>{std::move(d), std::move(sf)}; return single_sender<Data, DSF>{std::move(d), std::move(sf)};
...@@ -242,12 +242,12 @@ PUSHMI_TEMPLATE(class SF) ...@@ -242,12 +242,12 @@ PUSHMI_TEMPLATE(class SF)
->single_sender<SF>; ->single_sender<SF>;
PUSHMI_TEMPLATE(class Data) PUSHMI_TEMPLATE(class Data)
(requires True<>&& Sender<Data, is_single<>>) // (requires True<>&& Sender<Data> && is_single_v<Data>) //
single_sender(Data) single_sender(Data)
->single_sender<Data, passDSF>; ->single_sender<Data, passDSF>;
PUSHMI_TEMPLATE(class Data, class DSF) PUSHMI_TEMPLATE(class Data, class DSF)
(requires Sender<Data, is_single<>>) // (requires Sender<Data> && is_single_v<Data>) //
single_sender(Data, DSF) single_sender(Data, DSF)
->single_sender<Data, DSF>; ->single_sender<Data, DSF>;
#endif #endif
......
...@@ -210,7 +210,7 @@ class strand_executor { ...@@ -210,7 +210,7 @@ class strand_executor {
std::shared_ptr<strand_queue<E, Exec>> queue_; std::shared_ptr<strand_queue<E, Exec>> queue_;
public: public:
using properties = property_set<is_executor<>, is_fifo_sequence<>>; using properties = property_set<is_fifo_sequence<>>;
strand_executor(std::shared_ptr<strand_queue<E, Exec>> queue) strand_executor(std::shared_ptr<strand_queue<E, Exec>> queue)
: queue_(std::move(queue)) {} : queue_(std::move(queue)) {}
...@@ -239,12 +239,12 @@ class same_strand_factory_fn { ...@@ -239,12 +239,12 @@ class same_strand_factory_fn {
PUSHMI_TEMPLATE(class E = std::exception_ptr, class Provider) PUSHMI_TEMPLATE(class E = std::exception_ptr, class Provider)
(requires ExecutorProvider<Provider>&& (requires ExecutorProvider<Provider>&&
ConcurrentSequence<executor_t<Provider>>) // is_concurrent_sequence_v<executor_t<Provider>>) //
auto strands(Provider ep) { auto strands(Provider ep) {
return same_strand_factory_fn<E, executor_t<Provider>>{get_executor(ep)}; return same_strand_factory_fn<E, executor_t<Provider>>{get_executor(ep)};
} }
PUSHMI_TEMPLATE(class E = std::exception_ptr, class Exec) PUSHMI_TEMPLATE(class E = std::exception_ptr, class Exec)
(requires Executor<Exec>&& ConcurrentSequence<Exec>) // (requires Executor<Exec>&& is_concurrent_sequence_v<Exec>) //
auto strands(Exec ex) { auto strands(Exec ex) {
return same_strand_factory_fn<E, Exec>{std::move(ex)}; return same_strand_factory_fn<E, Exec>{std::move(ex)};
} }
......
...@@ -39,14 +39,14 @@ TEST(EmptySingleSender, TapAndSubmit) { ...@@ -39,14 +39,14 @@ TEST(EmptySingleSender, TapAndSubmit) {
auto e = op::empty(); auto e = op::empty();
using E = decltype(e); using E = decltype(e);
EXPECT_THAT((v::SenderTo<E, v::any_receiver<>, v::is_single<>>), Eq(true)) EXPECT_THAT((v::SenderTo<E, v::any_receiver<>> && v::is_single_v<E>), Eq(true))
<< "expected empty to return a single sender that can take an any_receiver<>"; << "expected empty to return a single sender that can take an any_receiver<>";
EXPECT_THAT( EXPECT_THAT(
(v::SenderTo< (v::SenderTo<
E, E,
v::any_receiver<std::exception_ptr, int>, v::any_receiver<std::exception_ptr, int>> &&
v::is_single<>>), v::is_single_v<E>),
Eq(true)) Eq(true))
<< "expected empty to return a single sender that can take an any_receiver<int>"; << "expected empty to return a single sender that can take an any_receiver<int>";
...@@ -80,8 +80,8 @@ TEST(JustIntSingleSender, TransformAndSubmit) { ...@@ -80,8 +80,8 @@ TEST(JustIntSingleSender, TransformAndSubmit) {
EXPECT_THAT( EXPECT_THAT(
(v::SenderTo< (v::SenderTo<
J, J,
v::any_receiver<std::exception_ptr, int>, v::any_receiver<std::exception_ptr, int>> &&
v::is_single<>>), v::is_single_v<J>),
Eq(true)) Eq(true))
<< "expected empty to return a single sender that can take an any_receiver<int>"; << "expected empty to return a single sender that can take an any_receiver<int>";
...@@ -131,7 +131,7 @@ TEST(FromIntManySender, TransformAndSubmit) { ...@@ -131,7 +131,7 @@ TEST(FromIntManySender, TransformAndSubmit) {
using M = decltype(m); using M = decltype(m);
EXPECT_THAT( EXPECT_THAT(
(v::SenderTo<M, v::any_receiver<std::exception_ptr, int>, v::is_many<>>), (v::SenderTo<M, v::any_receiver<std::exception_ptr, int>> && v::is_many_v<M>),
Eq(true)) Eq(true))
<< "expected empty to return a many sender that can take an any_receiver<int>"; << "expected empty to return a many sender that can take an any_receiver<int>";
......
...@@ -481,8 +481,7 @@ class time_source_executor { ...@@ -481,8 +481,7 @@ class time_source_executor {
std::shared_ptr<time_source_queue<E, time_point, NF, Exec>> queue_; std::shared_ptr<time_source_queue<E, time_point, NF, Exec>> queue_;
public: public:
using properties = property_set<is_time<>, using properties = property_set<is_fifo_sequence<>>;
is_fifo_sequence<>>;
time_source_executor( time_source_executor(
std::shared_ptr<time_source_shared<E, time_point>> source, std::shared_ptr<time_source_shared<E, time_point>> source,
...@@ -583,14 +582,16 @@ class time_source { ...@@ -583,14 +582,16 @@ class time_source {
} }
PUSHMI_TEMPLATE(class NF, class Factory) PUSHMI_TEMPLATE(class NF, class Factory)
(requires StrandFactory<Factory> && not Executor<Factory> && not ExecutorProvider<Factory>) // (requires StrandFactory<Factory> && not Executor<Factory> &&
not ExecutorProvider<Factory>) //
auto make(NF nf, Factory ef) { auto make(NF nf, Factory ef) {
return time_source_executor_factory_fn<E, time_point, NF, Factory>{ return time_source_executor_factory_fn<E, time_point, NF, Factory>{
source_, std::move(nf), std::move(ef)}; source_, std::move(nf), std::move(ef)};
} }
PUSHMI_TEMPLATE(class NF, class Provider) PUSHMI_TEMPLATE(class NF, class Provider)
(requires ExecutorProvider<Provider>&& (requires ExecutorProvider<Provider>&&
NeverBlocking<sender_t<executor_t<Provider>>> && not StrandFactory<Provider>) // is_never_blocking_v<sender_t<executor_t<Provider>>> &&
not StrandFactory<Provider>) //
auto make(NF nf, Provider ep) { auto make(NF nf, Provider ep) {
auto ex = ::folly::pushmi::get_executor(ep); auto ex = ::folly::pushmi::get_executor(ep);
auto queue = auto queue =
...@@ -601,7 +602,7 @@ class time_source { ...@@ -601,7 +602,7 @@ class time_source {
} }
PUSHMI_TEMPLATE(class NF, class Exec) PUSHMI_TEMPLATE(class NF, class Exec)
(requires Executor<Exec>&& (requires Executor<Exec>&&
NeverBlocking<sender_t<Exec>> && not StrandFactory<Exec>) // is_never_blocking_v<sender_t<Exec>> && not StrandFactory<Exec>) //
auto make(NF nf, Exec ex) { auto make(NF nf, Exec ex) {
auto queue = auto queue =
std::make_shared<time_source_queue<E, time_point, NF, Exec>>( std::make_shared<time_source_queue<E, time_point, NF, Exec>>(
......
...@@ -67,7 +67,7 @@ struct trampoline_task { ...@@ -67,7 +67,7 @@ struct trampoline_task {
template <class E = std::exception_ptr> template <class E = std::exception_ptr>
class delegator : pipeorigin { class delegator : pipeorigin {
public: public:
using properties = property_set<is_executor<>, is_fifo_sequence<>>; using properties = property_set<is_fifo_sequence<>>;
trampoline_task<E, ownordelegate_t> schedule() { trampoline_task<E, ownordelegate_t> schedule() {
return {}; return {};
...@@ -77,7 +77,7 @@ class delegator : pipeorigin { ...@@ -77,7 +77,7 @@ class delegator : pipeorigin {
template <class E = std::exception_ptr> template <class E = std::exception_ptr>
class nester : pipeorigin { class nester : pipeorigin {
public: public:
using properties = property_set<is_executor<>, is_fifo_sequence<>>; using properties = property_set<is_fifo_sequence<>>;
trampoline_task<E, ownornest_t> schedule() { trampoline_task<E, ownornest_t> schedule() {
return {}; return {};
......
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