proxygen
concepts.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
21 
22 namespace folly {
23 namespace pushmi {
24 
25 // traits & tags
26 
27 // cardinality affects both sender and receiver
28 
30 
31 // Trait
32 template <class PS>
33 struct has_cardinality : category_query<PS, cardinality_category> {};
34 template <class PS>
37  template(class PS) concept Cardinality,
38  has_cardinality_v<PS>);
39 
40 // flow affects both sender and receiver
41 
42 struct flow_category {};
43 
44 // sender and receiver are mutually exclusive
45 
47 
48 struct sender_category {};
49 
50 // for senders that are executors
51 
53 
54 // time and constrained are mutually exclusive refinements of sender (time is a
55 // special case of constrained and may be folded in later)
56 
57 // blocking affects senders
58 
60 
61 // sequence affects senders
62 
64 
65 // Single trait and tag
66 template <class... TN>
67 struct is_single;
68 // Tag
69 template <>
70 struct is_single<> {
72 };
73 // Trait
74 template <class PS>
75 struct is_single<PS> : property_query<PS, is_single<>> {};
76 template <class PS>
78 PUSHMI_CONCEPT_DEF(template(class PS) concept Single, is_single_v<PS>);
79 
80 // Many trait and tag
81 template <class... TN>
82 struct is_many;
83 // Tag
84 template <>
85 struct is_many<> {
87 }; // many::value() does not terminate, so it is not a refinement of single
88 // Trait
89 template <class PS>
90 struct is_many<PS> : property_query<PS, is_many<>> {};
91 template <class PS>
93 PUSHMI_CONCEPT_DEF(template(class PS) concept Many, is_many_v<PS>);
94 
95 // Flow trait and tag
96 template <class... TN>
97 struct is_flow;
98 // Tag
99 template <>
100 struct is_flow<> {
102 };
103 // Trait
104 template <class PS>
105 struct is_flow<PS> : property_query<PS, is_flow<>> {};
106 template <class PS>
108 PUSHMI_CONCEPT_DEF(template(class PS) concept Flow, is_flow_v<PS>);
109 
110 // Receiver trait and tag
111 template <class... TN>
112 struct is_receiver;
113 // Tag
114 template <>
115 struct is_receiver<> {
117 };
118 // Trait
119 template <class PS>
120 struct is_receiver<PS> : property_query<PS, is_receiver<>> {};
121 template <class PS>
123 // PUSHMI_CONCEPT_DEF(
124 // template (class PS)
125 // concept Receiver,
126 // is_receiver_v<PS>
127 // );
128 
129 // Sender trait and tag
130 template <class... TN>
131 struct is_sender;
132 // Tag
133 template <>
134 struct is_sender<> {
136 };
137 // Trait
138 template <class PS>
139 struct is_sender<PS> : property_query<PS, is_sender<>> {};
140 template <class PS>
142 // PUSHMI_CONCEPT_DEF(
143 // template (class PS)
144 // concept Sender,
145 // is_sender_v<PS>
146 // );
147 
148 // Executor trait and tag
149 template <class... TN>
150 struct is_executor;
151 // Tag
152 template <>
153 struct is_executor<> {
155 };
156 // Trait
157 template <class PS>
158 struct is_executor<PS> : property_query<PS, is_executor<>> {};
159 template <class PS>
162  template(class PS) concept Executor,
163  is_executor_v<PS>&& is_sender_v<PS>&& is_single_v<PS>);
164 
165 // Constrained trait and tag
166 template <class... TN>
168 // Tag
169 template <>
170 struct is_constrained<> : is_sender<> {};
171 // Trait
172 template <class PS>
173 struct is_constrained<PS> : property_query<PS, is_constrained<>> {};
174 template <class PS>
177  template(class PS) concept Constrained,
178  is_constrained_v<PS>&& is_sender_v<PS>);
179 
180 // Time trait and tag
181 template <class... TN>
182 struct is_time;
183 // Tag
184 template <>
185 struct is_time<> : is_constrained<> {};
186 // Trait
187 template <class PS>
188 struct is_time<PS> : property_query<PS, is_time<>> {};
189 template <class PS>
192  template(class PS) concept Time,
193  is_time_v<PS>&& is_constrained_v<PS>&& is_sender_v<PS>);
194 
195 // AlwaysBlocking trait and tag
196 template <class... TN>
198 // Tag
199 template <>
202 };
203 // Trait
204 template <class PS>
205 struct is_always_blocking<PS> : property_query<PS, is_always_blocking<>> {};
206 template <class PS>
210  template(class PS) concept AlwaysBlocking,
211  is_always_blocking_v<PS>&& is_sender_v<PS>);
212 
213 // NeverBlocking trait and tag
214 template <class... TN>
216 // Tag
217 template <>
220 };
221 // Trait
222 template <class PS>
223 struct is_never_blocking<PS> : property_query<PS, is_never_blocking<>> {};
224 template <class PS>
228  template(class PS) concept NeverBlocking,
229  is_never_blocking_v<PS>&& is_sender_v<PS>);
230 
231 // MaybeBlocking trait and tag
232 template <class... TN>
234 // Tag
235 template <>
238 };
239 // Trait
240 template <class PS>
241 struct is_maybe_blocking<PS> : property_query<PS, is_maybe_blocking<>> {};
242 template <class PS>
246  template(class PS) concept MaybeBlocking,
247  is_maybe_blocking_v<PS>&& is_sender_v<PS>);
248 
249 // FifoSequence trait and tag
250 template <class... TN>
252 // Tag
253 template <>
256 };
257 // Trait
258 template <class PS>
259 struct is_fifo_sequence<PS> : property_query<PS, is_fifo_sequence<>> {};
260 template <class PS>
264  template(class PS) concept FifoSequence,
265  is_fifo_sequence_v<PS>&& is_sender_v<PS>);
266 
267 // ConcurrentSequence trait and tag
268 template <class... TN>
270 // Tag
271 template <>
274 };
275 // Trait
276 template <class PS>
278  : property_query<PS, is_concurrent_sequence<>> {};
279 template <class PS>
283  template(class PS) concept ConcurrentSequence,
284  is_concurrent_sequence_v<PS>&& is_sender_v<PS>);
285 
287  template(class R, class... PropertyN)(concept Receiver)(R, PropertyN...),
288  requires(R& r)(
289  set_done(r),
290  set_error(r, std::exception_ptr{})) &&
291  SemiMovable<R> && property_query_v<R, PropertyN...> &&
292  is_receiver_v<R> && !is_sender_v<R>);
293 
295  template(class R, class... VN)(concept ReceiveValue)(R, VN...),
296  requires(R& r)(set_value(r, std::declval<VN&&>()...)) &&
297  Receiver<R> &&
298  // GCC w/-fconcepts ICE on SemiMovable<VN>...
299  True<> // And<SemiMovable<VN>...>
300 );
301 
303  template(class R, class E = std::exception_ptr)(concept ReceiveError)(R, E),
304  requires(R& r, E&& e)(set_error(r, (E &&) e)) && Receiver<R> &&
305  SemiMovable<E>);
306 
308  template(class D, class... PropertyN)(concept Sender)(D, PropertyN...),
309  requires(D& d)(
310  executor(d),
311  requires_<Executor<decltype(executor(d))>>) &&
312  SemiMovable<D> && Cardinality<D> && property_query_v<D, PropertyN...> &&
313  is_sender_v<D> && !is_receiver_v<D>);
314 
316  template(class D, class S, class... PropertyN)(
317  concept SenderTo)(D, S, PropertyN...),
318  requires(D& d, S&& s)(submit(d, (S &&) s)) && Sender<D> &&
319  Receiver<S> && property_query_v<D, PropertyN...>);
320 
321 template <class D>
323  Sender<D>,
324  executor_t =,
325  decltype(executor(std::declval<D&>())));
326 
327 // add concepts to support cancellation
328 //
329 
331  template(class S, class... PropertyN)(
332  concept FlowReceiver)(S, PropertyN...),
333  Receiver<S>&& property_query_v<S, PropertyN...>&& Flow<S>);
334 
336  template(class R, class... VN)(concept FlowReceiveValue)(R, VN...),
337  Flow<R>&& ReceiveValue<R, VN...>);
338 
340  template(class R, class E = std::exception_ptr)(
341  concept FlowReceiveError)(R, E),
342  Flow<R>&& ReceiveError<R, E>);
343 
345  template(class R, class Up)(concept FlowUpTo)(R, Up),
346  requires(R& r, Up&& up)(set_starting(r, (Up &&) up)) && Flow<R>);
347 
349  template(class S, class... PropertyN)(concept FlowSender)(S, PropertyN...),
350  Sender<S>&& property_query_v<S, PropertyN...>&& Flow<S>);
351 
353  template(class D, class S, class... PropertyN)(
354  concept FlowSenderTo)(D, S, PropertyN...),
355  FlowSender<D>&& property_query_v<D, PropertyN...>&& FlowReceiver<S>);
356 
357 // add concepts for constraints
358 //
359 // the constraint could be time or priority enum or any other
360 // ordering constraint value-type.
361 //
362 // top() returns the constraint value that will cause the item to run asap.
363 // So now() for time and NORMAL for priority.
364 //
365 
367  template(class D, class... PropertyN)(
368  concept ConstrainedSender)(D, PropertyN...),
369  requires(D& d)(
370  top(d),
371  requires_<Regular<decltype(top(d))>>) &&
372  Sender<D> && property_query_v<D, PropertyN...> && Constrained<D>);
373 
375  template(class D, class S, class... PropertyN)(
376  concept ConstrainedSenderTo)(D, S, PropertyN...),
377  requires(D& d, S&& s)(submit(d, top(d), (S &&) s)) &&
378  ConstrainedSender<D> && property_query_v<D, PropertyN...> &&
379  Receiver<S>);
380 
381 template <class D>
383  ConstrainedSender<D>,
384  constraint_t =,
385  decltype(top(std::declval<D&>())));
386 
388  template(class D, class... PropertyN)(concept TimeSender)(D, PropertyN...),
389  requires(D& d)(
390  now(d),
391  requires_<
392  Regular<decltype(now(d) + std::chrono::seconds(1))>>) &&
393  ConstrainedSender<D, PropertyN...> && Time<D>);
394 
396  template(class D, class S, class... PropertyN)(
397  concept TimeSenderTo)(D, S, PropertyN...),
398  ConstrainedSenderTo<D, S, PropertyN...>&& TimeSender<D>);
399 
400 template <class D>
402  TimeSender<D>,
403  time_point_t =,
404  decltype(now(std::declval<D&>())));
405 
406 } // namespace pushmi
407 } // namespace folly
std::true_type True
Definition: TypeList.h:82
PUSHMI_INLINE_VAR constexpr bool is_never_blocking_v
Definition: concepts.h:225
constexpr std::enable_if_t< B, int > requires_
Definition: concept_def.h:554
PUSHMI_INLINE_VAR constexpr bool is_flow_v
Definition: concepts.h:107
PUSHMI_INLINE_VAR constexpr bool is_executor_v
Definition: concepts.h:160
PUSHMI_INLINE_VAR constexpr bool is_concurrent_sequence_v
Definition: concepts.h:280
PUSHMI_INLINE_VAR constexpr bool is_time_v
Definition: concepts.h:190
PUSHMI_INLINE_VAR constexpr __adl::set_error_fn set_error
PUSHMI_INLINE_VAR constexpr bool is_always_blocking_v
Definition: concepts.h:207
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
PUSHMI_PP_CONSTRAINED_USING(Sender< D >, executor_t=, decltype(executor(std::declval< D & >())))
PUSHMI_INLINE_VAR constexpr bool is_single_v
Definition: concepts.h:77
#define D(name, bit)
Definition: CpuId.h:145
PUSHMI_CONCEPT_DEF(template(class PS) concept Cardinality, has_cardinality_v< PS >)
PUSHMI_INLINE_VAR constexpr bool is_sender_v
Definition: concepts.h:141
#define concept
PUSHMI_INLINE_VAR constexpr bool is_maybe_blocking_v
Definition: concepts.h:243
#define PUSHMI_INLINE_VAR
Definition: concept_def.h:60
PUSHMI_INLINE_VAR constexpr __adl::set_starting_fn set_starting
requires requires(detail::apply_impl(std::declval< F >(), std::declval< Tuple >(), detail::tupidxs< Tuple >{}))) const expr decltype(auto) apply(F &&f
PUSHMI_INLINE_VAR constexpr __adl::get_top_fn now
PUSHMI_INLINE_VAR constexpr __adl::get_top_fn top
PUSHMI_INLINE_VAR constexpr bool is_many_v
Definition: concepts.h:92
PUSHMI_INLINE_VAR constexpr __adl::set_value_fn set_value
static set< string > s
PUSHMI_INLINE_VAR constexpr __adl::do_submit_fn submit
PUSHMI_INLINE_VAR constexpr bool is_fifo_sequence_v
Definition: concepts.h:261
PUSHMI_INLINE_VAR constexpr bool is_receiver_v
Definition: concepts.h:122
PUSHMI_INLINE_VAR constexpr bool is_constrained_v
Definition: concepts.h:175
PUSHMI_INLINE_VAR constexpr bool has_cardinality_v
Definition: concepts.h:35
PUSHMI_INLINE_VAR constexpr __adl::set_done_fn set_done