proxygen
boosters.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 <chrono>
19 #include <cstdint>
20 #include <cstdio>
21 #include <exception>
22 #include <functional>
23 #include <utility>
24 
28 
29 namespace folly {
30 namespace pushmi {
31 
32 template<class T>
33 struct construct {
34  PUSHMI_TEMPLATE(class... AN)
35  (requires Constructible<T, AN...>)
36  auto operator()(AN&&... an) const {
37  return T{std::forward<AN>(an)...};
38  }
39 };
40 
41 template<template <class...> class T>
43 
44 template<>
46 
47 template<>
49 
50 template<>
52 
53 template<>
55 
56 template<>
58 
59 template<>
61 
62 template<>
64 
65 template<>
67 
68 template <template <class...> class T, class... AN>
69 using deduced_type_t =
71 
72 struct ignoreVF {
73  PUSHMI_TEMPLATE(class... VN)
74  (requires And<ConvertibleTo<VN&&, detail::any>...>)
75  void operator()(VN&&...) {}
76 };
77 
78 struct abortEF {
79  [[noreturn]]
81  std::abort();
82  }
83 };
84 
85 struct ignoreDF {
86  void operator()() {}
87 };
88 
89 struct ignoreNF {
91 };
92 
93 struct ignoreStrtF {
95 };
96 
97 struct trampolineEXF;
98 // see trampoline.h
99 // struct trampolineEXF {
100 // auto operator()() { return trampoline(); }
101 // };
102 
103 struct ignoreSF {
106 };
107 
108 struct systemNowF {
110 };
111 
113  auto operator()(){ return 0; }
114 };
115 
116 struct passDVF {
117  PUSHMI_TEMPLATE(class Data, class... VN)
118  (requires requires (
119  set_value(std::declval<Data&>(), std::declval<VN>()...)
120  ) && Receiver<Data>)
121  void operator()(Data& out, VN&&... vn) const {
122  set_value(out, (VN&&) vn...);
123  }
124 };
125 
126 struct passDEF {
127  PUSHMI_TEMPLATE(class E, class Data)
128  (requires ReceiveError<Data, E>)
129  void operator()(Data& out, E e) const noexcept {
130  set_error(out, e);
131  }
132 };
133 
134 struct passDDF {
135  PUSHMI_TEMPLATE(class Data)
136  (requires Receiver<Data>)
137  void operator()(Data& out) const {
138  set_done(out);
139  }
140 };
141 
142 struct passDStrtF {
143  PUSHMI_TEMPLATE(class Up, class Data)
144  (requires requires (
145  set_starting(std::declval<Data&>(), std::declval<Up>())
146  ) && Receiver<Data>)
147  void operator()(Data& out, Up&& up) const {
148  set_starting(out, (Up&&) up);
149  }
150 };
151 
152 struct passDEXF {
153  PUSHMI_TEMPLATE(class Data)
154  (requires Sender<Data>)
155  auto operator()(Data& in) const noexcept {
156  return executor(in);
157  }
158 };
159 
160 struct passDSF {
161  template <class Data, class Out>
162  void operator()(Data& in, Out out) {
163  submit(in, std::move(out));
164  }
165  template <class Data, class TP, class Out>
166  void operator()(Data& in, TP at, Out out) {
167  submit(in, std::move(at), std::move(out));
168  }
169 };
170 
171 struct passDNF {
172  PUSHMI_TEMPLATE(class Data)
173  (requires TimeSender<Data>)
174  auto operator()(Data& in) const noexcept {
176  }
177 };
178 
179 struct passDZF {
180  PUSHMI_TEMPLATE(class Data)
181  (requires ConstrainedSender<Data>)
182  auto operator()(Data& in) const noexcept {
184  }
185 };
186 
187 // inspired by Ovrld - shown in a presentation by Nicolai Josuttis
188 #if __cpp_variadic_using >= 201611 && __cpp_concepts
189 template <PUSHMI_TYPE_CONSTRAINT(SemiMovable)... Fns>
190  requires sizeof...(Fns) > 0
191 struct overload_fn : Fns... {
192  constexpr overload_fn() = default;
193  constexpr explicit overload_fn(Fns... fns) requires sizeof...(Fns) == 1
194  : Fns(std::move(fns))... {}
195  constexpr overload_fn(Fns... fns) requires sizeof...(Fns) > 1
196  : Fns(std::move(fns))... {}
197  using Fns::operator()...;
198 };
199 #else
200 template <PUSHMI_TYPE_CONSTRAINT(SemiMovable)... Fns>
201 #if __cpp_concepts
202  requires sizeof...(Fns) > 0
203 #endif
204 struct overload_fn;
205 template <class Fn>
206 struct overload_fn<Fn> : Fn {
207  constexpr overload_fn() = default;
208  constexpr explicit overload_fn(Fn fn)
209  : Fn(std::move(fn)) {}
210  using Fn::operator();
211 };
212 #if !defined(__GNUC__) || __GNUC__ >= 8
213 template <class Fn, class... Fns>
214 struct overload_fn<Fn, Fns...> : Fn, overload_fn<Fns...> {
215  constexpr overload_fn() = default;
216  constexpr overload_fn(Fn fn, Fns... fns)
217  : Fn(std::move(fn)), overload_fn<Fns...>{std::move(fns)...} {}
218  using Fn::operator();
220 };
221 #else
222 template <class Fn, class... Fns>
223 struct overload_fn<Fn, Fns...> {
224 private:
225  std::pair<Fn, overload_fn<Fns...>> fns_;
226  template <bool B>
227  using _which_t = std::conditional_t<B, Fn, overload_fn<Fns...>>;
228 public:
229  constexpr overload_fn() = default;
230  constexpr overload_fn(Fn fn, Fns... fns)
231  : fns_{std::move(fn), overload_fn<Fns...>{std::move(fns)...}} {}
232  PUSHMI_TEMPLATE (class... Args)
233  (requires lazy::Invocable<Fn&, Args...> ||
234  lazy::Invocable<overload_fn<Fns...>&, Args...>)
235  decltype(auto) operator()(Args &&... args) PUSHMI_NOEXCEPT_AUTO(
236  std::declval<_which_t<Invocable<Fn&, Args...>>&>()(std::declval<Args>()...)) {
237  return std::get<!Invocable<Fn&, Args...>>(fns_)((Args &&) args...);
238  }
239  PUSHMI_TEMPLATE (class... Args)
240  (requires lazy::Invocable<const Fn&, Args...> ||
241  lazy::Invocable<const overload_fn<Fns...>&, Args...>)
242  decltype(auto) operator()(Args &&... args) const PUSHMI_NOEXCEPT_AUTO(
243  std::declval<const _which_t<Invocable<const Fn&, Args...>>&>()(std::declval<Args>()...)) {
244  return std::get<!Invocable<const Fn&, Args...>>(fns_)((Args &&) args...);
245  }
246 };
247 #endif
248 #endif
249 
250 template <class... Fns>
251 auto overload(Fns... fns) -> overload_fn<Fns...> {
252  return overload_fn<Fns...>{std::move(fns)...};
253 }
254 
255 template <class... Fns>
256 struct on_value_fn : overload_fn<Fns...> {
257  constexpr on_value_fn() = default;
258  using overload_fn<Fns...>::overload_fn;
259 };
260 
261 template <class... Fns>
262 auto on_value(Fns... fns) -> on_value_fn<Fns...> {
263  return on_value_fn<Fns...>{std::move(fns)...};
264 }
265 
266 template <class... Fns>
267 struct on_error_fn : overload_fn<Fns...> {
268  constexpr on_error_fn() = default;
269  using overload_fn<Fns...>::overload_fn;
270 };
271 
272 template <class... Fns>
273 auto on_error(Fns... fns) -> on_error_fn<Fns...> {
274  return on_error_fn<Fns...>{std::move(fns)...};
275 }
276 
277 template <class Fn>
278 struct on_done_fn : Fn {
279  constexpr on_done_fn() = default;
280  constexpr explicit on_done_fn(Fn fn) : Fn(std::move(fn)) {}
281  using Fn::operator();
282 };
283 
284 template <class Fn>
285 auto on_done(Fn fn) -> on_done_fn<Fn> {
286  return on_done_fn<Fn>{std::move(fn)};
287 }
288 
289 template <class... Fns>
290 struct on_starting_fn : overload_fn<Fns...> {
291  constexpr on_starting_fn() = default;
292  using overload_fn<Fns...>::overload_fn;
293 };
294 
295 template <class... Fns>
296 auto on_starting(Fns... fns) -> on_starting_fn<Fns...> {
297  return on_starting_fn<Fns...>{std::move(fns)...};
298 }
299 
300 template <class Fn>
302  constexpr on_executor_fn() = default;
304 };
305 
306 template <class Fn>
308  return on_executor_fn<Fn>{std::move(fn)};
309 }
310 
311 template <class... Fns>
312 struct on_submit_fn : overload_fn<Fns...> {
313  constexpr on_submit_fn() = default;
314  using overload_fn<Fns...>::overload_fn;
315 };
316 
317 template <class... Fns>
318 auto on_submit(Fns... fns) -> on_submit_fn<Fns...> {
319  return on_submit_fn<Fns...>{std::move(fns)...};
320 }
321 
322 template <class Fn>
323 struct on_now_fn : overload_fn<Fn> {
324  constexpr on_now_fn() = default;
326 };
327 
328 template <class Fn>
329 auto on_now(Fn fn) -> on_now_fn<Fn> {
330  return on_now_fn<Fn>{std::move(fn)};
331 }
332 
333 } // namespace pushmi
334 } // namespace folly
void operator()(detail::any) noexcept
Definition: boosters.h:80
auto overload(Fns...fns) -> overload_fn< Fns... >
Definition: boosters.h:251
auto on_value(Fns...fns) -> on_value_fn< Fns... >
Definition: boosters.h:262
auto on_submit(Fns...fns) -> on_submit_fn< Fns... >
Definition: boosters.h:318
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::chrono::steady_clock::time_point now()
auto on_executor(Fn fn) -> on_executor_fn< Fn >
Definition: boosters.h:307
STL namespace.
PUSHMI_INLINE_VAR constexpr __adl::set_error_fn set_error
auto on_now(Fn fn) -> on_now_fn< Fn >
Definition: boosters.h:329
void operator()(Data &in, Out out)
Definition: boosters.h:162
auto on_error(Fns...fns) -> on_error_fn< Fns... >
Definition: boosters.h:273
folly::std T
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
void operator()(detail::any)
Definition: boosters.h:90
auto on_starting(Fns...fns) -> on_starting_fn< Fns... >
Definition: boosters.h:296
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
#define PUSHMI_NOEXCEPT_AUTO(...)
Definition: traits.h:23
constexpr overload_fn(Fn fn)
Definition: boosters.h:208
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
void operator()(detail::any)
Definition: boosters.h:104
requires Constructible< T, AN... > auto operator()(AN &&...an) const
Definition: boosters.h:36
void operator()(Data &in, TP at, Out out)
Definition: boosters.h:166
void operator()(detail::any)
Definition: boosters.h:94
void operator()(detail::any, detail::any)
Definition: boosters.h:105
PUSHMI_INLINE_VAR constexpr __adl::set_starting_fn set_starting
::folly::pushmi::invoke_result_t< construct_deduced< T >, AN... > deduced_type_t
Definition: boosters.h:70
requires requires(detail::apply_impl(std::declval< F >(), std::declval< Tuple >(), detail::tupidxs< Tuple >{}))) const expr decltype(auto) apply(F &&f
PUSHMI_TEMPLATE(class E=std::exception_ptr, class Wrapped)(requires Sender< detail
Definition: executor.h:102
constexpr on_done_fn(Fn fn)
Definition: boosters.h:280
PUSHMI_INLINE_VAR constexpr __adl::get_top_fn top
auto on_done(Fn fn) -> on_done_fn< Fn >
Definition: boosters.h:285
PUSHMI_INLINE_VAR constexpr __adl::set_value_fn set_value
const
Definition: upload.py:398
#define PUSHMI_TYPE_CONSTRAINT(...)
Definition: concept_def.h:420
PUSHMI_INLINE_VAR constexpr __adl::do_submit_fn submit
decltype(folly::pushmi::invoke(std::declval< F >(), std::declval< As >()...)) invoke_result_t
Definition: functional.h:47
PUSHMI_INLINE_VAR constexpr detail::get_fn< T > get
Definition: submit.h:391
constexpr overload_fn(Fn fn, Fns...fns)
Definition: boosters.h:216
#define B(name, bit)
Definition: CpuId.h:178
PUSHMI_INLINE_VAR constexpr __adl::set_done_fn set_done