proxygen
extension_points.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 
18 #include <future>
19 #include <functional>
20 
24 
25 namespace folly {
26 namespace pushmi {
27 namespace __adl {
28 
29 //
30 // support methods on a class reference
31 //
32 
33 PUSHMI_TEMPLATE (class S)
34  (requires requires (std::declval<S&>().done()))
35 void set_done(S& s) noexcept(noexcept(s.done())) {
36  s.done();
37 }
38 PUSHMI_TEMPLATE (class S, class E)
39  (requires requires (std::declval<S&>().error(std::declval<E>())))
40 void set_error(S& s, E e) noexcept(noexcept(s.error(std::move(e)))) {
41  s.error(std::move(e));
42 }
43 PUSHMI_TEMPLATE (class S, class... VN)
44  (requires requires (std::declval<S&>().value(std::declval<VN&&>()...)))
45 void set_value(S& s, VN&&... vn) noexcept(noexcept(s.value((VN&&) vn...))) {
46  s.value((VN&&) vn...);
47 }
48 
49 PUSHMI_TEMPLATE (class S, class Up)
50  (requires requires (std::declval<S&>().starting(std::declval<Up&&>())))
51 void set_starting(S& s, Up&& up) noexcept(noexcept(s.starting((Up&&) up))) {
52  s.starting((Up&&) up);
53 }
54 
55 PUSHMI_TEMPLATE (class SD)
56  (requires requires (std::declval<SD&>().executor()))
57 auto executor(SD& sd) noexcept(noexcept(sd.executor())) {
58  return sd.executor();
59 }
60 
61 PUSHMI_TEMPLATE (class SD, class Out)
63  std::declval<SD&>().submit(std::declval<Out>())
64  ))
65 void submit(SD& sd, Out out) noexcept(noexcept(sd.submit(std::move(out)))) {
66  sd.submit(std::move(out));
67 }
68 
69 PUSHMI_TEMPLATE (class SD)
70  (requires requires (std::declval<SD&>().top()))
71 auto top(SD& sd) noexcept(noexcept(sd.top())) {
72  return sd.top();
73 }
74 
75 PUSHMI_TEMPLATE (class SD, class TP, class Out)
77  std::declval<SD&>().submit(
78  std::declval<TP(&)(TP)>()(top(std::declval<SD&>())),
79  std::declval<Out>())
80  ))
81 void submit(SD& sd, TP tp, Out out)
82  noexcept(noexcept(sd.submit(std::move(tp), std::move(out)))) {
83  sd.submit(std::move(tp), std::move(out));
84 }
85 
86 //
87 // support methods on a class pointer
88 //
89 
90 PUSHMI_TEMPLATE (class S)
91  (requires requires (std::declval<S&>()->done()))
92 void set_done(S& s) noexcept(noexcept(s->done())) {
93  s->done();
94 }
95 PUSHMI_TEMPLATE (class S, class E)
96  (requires requires (std::declval<S&>()->error(std::declval<E>())))
97 void set_error(S& s, E e) noexcept(noexcept(s->error(std::move(e)))) {
98  s->error(std::move(e));
99 }
100 PUSHMI_TEMPLATE (class S, class... VN)
101  (requires requires (std::declval<S&>()->value(std::declval<VN&&>()...)))
102 void set_value(S& s, VN&&... vn) noexcept(noexcept(s->value((VN&&) vn...))) {
103  s->value((VN&&) vn...);
104 }
105 
106 PUSHMI_TEMPLATE (class S, class Up)
107  (requires requires (std::declval<S&>()->starting(std::declval<Up&&>())))
108 void set_starting(S& s, Up&& up) noexcept(noexcept(s->starting((Up&&) up))) {
109  s->starting((Up&&) up);
110 }
111 
112 PUSHMI_TEMPLATE (class SD)
113  (requires requires (std::declval<SD&>()->executor()))
114 auto executor(SD& sd) noexcept(noexcept(sd->executor())) {
115  return sd->executor();
116 }
117 
118 PUSHMI_TEMPLATE (class SD, class Out)
119  (requires requires (std::declval<SD&>()->submit(std::declval<Out>())))
120 void submit(SD& sd, Out out) noexcept(noexcept(sd->submit(std::move(out)))) {
121  sd->submit(std::move(out));
122 }
123 
124 PUSHMI_TEMPLATE (class SD)
125  (requires requires (std::declval<SD&>()->top()))
126 auto top(SD& sd) noexcept(noexcept(sd->top())) {
127  return sd->top();
128 }
129 
130 PUSHMI_TEMPLATE (class SD, class TP, class Out)
131  (requires requires (
132  std::declval<SD&>()->submit(
133  std::declval<TP(&)(TP)>()(top(std::declval<SD&>())),
134  std::declval<Out>())
135  ))
136 void submit(SD& sd, TP tp, Out out)
137  noexcept(noexcept(sd->submit(std::move(tp), std::move(out)))) {
138  sd->submit(std::move(tp), std::move(out));
139 }
140 
141 //
142 // support a nullary function as a receiver
143 //
144 
145 PUSHMI_TEMPLATE (class S)
146  (requires Invocable<S&>)
147 void set_done(S&) noexcept {
148 }
149 PUSHMI_TEMPLATE (class S, class E)
150  (requires Invocable<S&>)
151 void set_error(S&, E&&) noexcept {
152  std::abort();
153 }
154 PUSHMI_TEMPLATE (class S)
155  (requires Invocable<S&>)
156 void set_value(S& s) noexcept(noexcept(s())) {
157  s();
158 }
159 
160 //
161 // add support for std::promise externally
162 //
163 
164 // std::promise does not support the done signal.
165 // either set_value or set_error must be called
166 template <class T>
167 void set_done(std::promise<T>&) noexcept {}
168 
169 template <class T>
170 void set_error(std::promise<T>& p, std::exception_ptr e) noexcept {
171  p.set_exception(std::move(e));
172 }
173 template <class T, class E>
174 void set_error(std::promise<T>& p, E e) noexcept {
175  p.set_exception(std::make_exception_ptr(std::move(e)));
176 }
177 template <class T>
178 void set_value(std::promise<T>& p, T t) noexcept(noexcept(p.set_value(std::move(t)))) {
179  p.set_value(std::move(t));
180 }
181 inline void set_value(std::promise<void>& p) noexcept(noexcept(p.set_value())) {
182  p.set_value();
183 }
184 
185 //
186 // support reference_wrapper
187 //
188 
189 PUSHMI_TEMPLATE (class S)
190  (requires requires ( set_done(std::declval<S&>()) ))
191 void set_done(std::reference_wrapper<S> s) noexcept(
192  noexcept(set_done(s.get()))) {
193  set_done(s.get());
194 }
195 PUSHMI_TEMPLATE (class S, class E)
196  (requires requires ( set_error(std::declval<S&>(), std::declval<E>()) ))
197 void set_error(std::reference_wrapper<S> s, E e) noexcept {
198  set_error(s.get(), std::move(e));
199 }
200 PUSHMI_TEMPLATE (class S, class... VN)
201  (requires requires ( set_value(std::declval<S&>(), std::declval<VN&&>()...) ))
202 void set_value(std::reference_wrapper<S> s, VN&&... vn) noexcept(
203  noexcept(set_value(s.get(), (VN&&) vn...))) {
204  set_value(s.get(), (VN&&) vn...);
205 }
206 PUSHMI_TEMPLATE (class S, class Up)
207  (requires requires ( set_starting(std::declval<S&>(), std::declval<Up&&>()) ))
208 void set_starting(std::reference_wrapper<S> s, Up&& up) noexcept(
209  noexcept(set_starting(s.get(), (Up&&) up))) {
210  set_starting(s.get(), (Up&&) up);
211 }
212 PUSHMI_TEMPLATE (class SD)
213  (requires requires ( executor(std::declval<SD&>()) ))
214 auto executor(std::reference_wrapper<SD> sd) noexcept(noexcept(executor(sd.get()))) {
215  return executor(sd.get());
216 }
217 PUSHMI_TEMPLATE (class SD, class Out)
218  (requires requires ( submit(std::declval<SD&>(), std::declval<Out>()) ))
219 void submit(std::reference_wrapper<SD> sd, Out out) noexcept(
220  noexcept(submit(sd.get(), std::move(out)))) {
221  submit(sd.get(), std::move(out));
222 }
223 
224 PUSHMI_TEMPLATE (class SD)
225  (requires requires ( top(std::declval<SD&>()) ))
226 auto top(std::reference_wrapper<SD> sd) noexcept(noexcept(top(sd.get()))) {
227  return top(sd.get());
228 }
229 PUSHMI_TEMPLATE (class SD, class TP, class Out)
231  submit(
232  std::declval<SD&>(),
233  std::declval<TP(&)(TP)>()(top(std::declval<SD&>())),
234  std::declval<Out>())
235  ))
236 void submit(std::reference_wrapper<SD> sd, TP tp, Out out)
237  noexcept(noexcept(submit(sd.get(), std::move(tp), std::move(out)))) {
238  submit(sd.get(), std::move(tp), std::move(out));
239 }
240 
241 //
242 // accessors for free functions in this namespace
243 //
244 
245 struct set_done_fn {
246  PUSHMI_TEMPLATE (class S)
248  set_done(std::declval<S&>()),
249  set_error(std::declval<S&>(), std::current_exception())
250  ))
251  void operator()(S&& s) const noexcept(noexcept(set_done(s))) {
252  try {
253  set_done(s);
254  } catch (...) {
255  set_error(s, std::current_exception());
256  }
257  }
258 };
259 struct set_error_fn {
260  PUSHMI_TEMPLATE (class S, class E)
261  (requires requires (
262  set_error(std::declval<S&>(), std::declval<E>())
263  ))
264  void operator()(S&& s, E e) const
266  set_error(s, std::move(e));
267  }
268 };
269 struct set_value_fn {
270  PUSHMI_TEMPLATE (class S, class... VN)
271  (requires requires (
272  set_value(std::declval<S&>(), std::declval<VN&&>()...),
273  set_error(std::declval<S&>(), std::current_exception())
274  ))
275  void operator()(S&& s, VN&&... vn) const
276  noexcept(noexcept(set_value(s, (VN&&) vn...))) {
277  try {
278  set_value(s, (VN&&) vn...);
279  } catch (...) {
280  set_error(s, std::current_exception());
281  }
282  }
283 };
284 
286  PUSHMI_TEMPLATE (class S, class Up)
287  (requires requires (
288  set_starting(std::declval<S&>(), std::declval<Up&&>()),
289  set_error(std::declval<S&>(), std::current_exception())
290  ))
291  void operator()(S&& s, Up&& up) const
292  noexcept(noexcept(set_starting(s, (Up&&) up))) {
293  try {
294  set_starting(s, (Up&&) up);
295  } catch (...) {
296  set_error(s, std::current_exception());
297  }
298  }
299 };
300 
302  PUSHMI_TEMPLATE (class SD)
304  executor(std::declval<SD&>())
305  ))
306  auto operator()(SD&& sd) const noexcept(noexcept(executor(sd))) {
307  return executor(sd);
308  }
309 };
310 
311 struct do_submit_fn {
312  PUSHMI_TEMPLATE (class SD, class Out)
313  (requires requires (
314  submit(std::declval<SD&>(), std::declval<Out>())
315  ))
316  void operator()(SD&& s, Out out) const
318  submit(s, std::move(out));
319  }
320 
321  PUSHMI_TEMPLATE (class SD, class Out)
322  (requires requires (
323  submit(std::declval<SD&>(), top(std::declval<SD&>()), std::declval<Out>())
324  ))
325  void operator()(SD&& s, Out out) const
327  submit(s, top(s), std::move(out));
328  }
329 
330  PUSHMI_TEMPLATE (class SD, class TP, class Out)
331  (requires requires (
332  submit(
333  std::declval<SD&>(),
334  std::declval<TP>(),
335  std::declval<Out>())
336  ))
337  void operator()(SD&& s, TP tp, Out out) const
339  submit(s, std::move(tp), std::move(out));
340  }
341 };
342 
343 struct get_top_fn {
344  PUSHMI_TEMPLATE (class SD)
346  top(std::declval<SD&>())
347  ))
348  auto operator()(SD&& sd) const noexcept(noexcept(top(sd))) {
349  return top(sd);
350  }
351 };
352 
353 } // namespace __adl
354 
363 
364 template<class T>
365 struct property_set_traits<T, std::enable_if_t<(bool)Invocable<T&> &&
366  not Valid<T&, __properties_t>>> {
368 };
369 
370 template <class T>
371 struct property_set_traits<std::promise<T>> {
373 };
374 template <>
375 struct property_set_traits<std::promise<void>> {
377 };
378 
379 } // namespace pushmi
380 } // namespace folly
requires requires(executor(std::declval< SD & >()))) auto operator()(SD &&sd) const noexcept(noexcept(executor(sd)))
requires Tuple && t
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
requires TP Out out const noexcept(noexcept(submit(s, std::move(tp), std::move(out))))
requires Invocable< S & > void set_done(S &) noexcept
folly::std T
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
Definition: error.h:48
requires requires(std::declval< S & >().done())) void set_done(S &s) noexcept(noexcept(s.done()))
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
requires Out out const noexcept(noexcept(submit(s, top(s), std::move(out))))
requires Invocable< S & > void set_value(S &s) noexcept(noexcept(s()))
#define PUSHMI_INLINE_VAR
Definition: concept_def.h:60
requires E e const noexcept(noexcept(set_error(s, std::move(e))))
PUSHMI_INLINE_VAR constexpr __adl::set_starting_fn set_starting
PUSHMI_INLINE_VAR constexpr __adl::get_top_fn now
PUSHMI_TEMPLATE(class E=std::exception_ptr, class Wrapped)(requires Sender< detail
Definition: executor.h:102
PUSHMI_INLINE_VAR constexpr __adl::get_top_fn top
requires VN &&vn const noexcept(noexcept(set_value(s,(VN &&) vn...)))
requires Up &&up const noexcept(noexcept(set_starting(s,(Up &&) up)))
static set< string > s
requires Out out const noexcept(noexcept(submit(s, std::move(out))))
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
PUSHMI_INLINE_VAR constexpr __adl::do_submit_fn submit
requires Invocable< S & > void set_error(S &, E &&) noexcept
requires requires(set_done(std::declval< S & >()), set_error(std::declval< S & >(), std::current_exception()))) void operator()(S &&s) const noexcept(noexcept(set_done(s)))
requires requires(top(std::declval< SD & >()))) auto operator()(SD &&sd) const noexcept(noexcept(top(sd)))