proxygen
extension_operators.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 
34 #include <tuple>
35 
36 namespace folly {
37 namespace pushmi {
38 
39 #if __cpp_lib_apply >= 201603
40 using std::apply;
41 #else
42 namespace detail {
43 PUSHMI_TEMPLATE(class F, class Tuple, std::size_t... Is)
45  std::declval<F>(),
46  std::get<Is>(std::declval<Tuple>())...)))
47 constexpr decltype(auto) apply_impl(
48  F&& f, Tuple&& t, std::index_sequence<Is...>) {
49  return ::folly::pushmi::invoke((F &&) f, std::get<Is>((Tuple &&) t)...);
50 }
51 template <class Tuple_, class Tuple = std::remove_reference_t<Tuple_>>
53 } // namespace detail
54 
55 PUSHMI_TEMPLATE(class F, class Tuple)
56 (requires requires(detail::apply_impl(
57  std::declval<F>(),
58  std::declval<Tuple>(),
60 constexpr decltype(auto) apply(F&& f, Tuple&& t) {
61  return detail::apply_impl((F &&) f, (Tuple &&) t, detail::tupidxs<Tuple>{});
62 }
63 #endif
64 
65 namespace detail {
66 
67 template <class Cardinality, bool IsFlow = false>
69 template <>
70 struct make_receiver<is_single<>> : construct_deduced<receiver> {};
71 template <>
72 struct make_receiver<is_many<>> : construct_deduced<receiver> {};
73 template <>
74 struct make_receiver<is_single<>, true> : construct_deduced<flow_receiver> {};
75 template <>
76 struct make_receiver<is_many<>, true> : construct_deduced<flow_receiver> {};
77 
78 template <class Cardinality, bool IsFlow>
81  template <class... AN>
83  PUSHMI_TEMPLATE(class... Ts)
84  (requires Invocable<MakeReceiver, Ts...>)
85  auto operator()(
86  std::tuple<Ts...> args) const {
87  return ::folly::pushmi::apply(MakeReceiver(), std::move(args));
88  }
90  class... Ts,
91  class... Fns,
92  class This = std::enable_if_t<sizeof...(Fns) != 0, receiver_from_impl>)
93  (requires And<SemiMovable<Fns>...>&& Invocable<MakeReceiver, Ts...>&&
94  Invocable<
95  This,
96  ::folly::pushmi::invoke_result_t<MakeReceiver, Ts...>,
97  Fns...>)
98  auto operator()(std::tuple<Ts...> args, Fns... fns) const {
99  return This()(This()(std::move(args)), std::move(fns)...);
100  }
101  PUSHMI_TEMPLATE(class Out, class... Fns)
102  (requires Receiver<Out>&& And<SemiMovable<Fns>...>)
103  auto operator()(
104  Out out,
105  Fns... fns) const {
106  return MakeReceiver()(std::move(out), std::move(fns)...);
107  }
108 };
109 
110 template <PUSHMI_TYPE_CONSTRAINT(Sender) In>
113  property_query_v<properties_t<In>, is_flow<>>>;
114 
115 template <PUSHMI_TYPE_CONSTRAINT(Sender) In, class... AN>
116 using receiver_type_t =
117  typename receiver_from_fn<In>::template receiver_type<AN...>;
118 
119 template <class In, class FN>
121  FN fn_;
122  PUSHMI_TEMPLATE(class Out)
123  (requires Receiver<Out>&& Invocable<FN, Out>&&
124  SenderTo<In, ::folly::pushmi::invoke_result_t<const FN&, Out>>)
125  void operator()(In& in, Out out) const {
126  submit(in, fn_(std::move(out)));
127  }
128 };
129 template <class In, class FN>
131  FN fn_;
132  PUSHMI_TEMPLATE(class CV, class Out)
133  (requires Receiver<Out>&& Invocable<FN, Out>&&
134  ConstrainedSenderTo<In, ::folly::pushmi::invoke_result_t<const FN&, Out>>)
135  void operator()(In& in, CV cv, Out out) const {
136  submit(in, cv, fn_(std::move(out)));
137  }
138 };
139 template <class In, class SDSF>
141  SDSF sdsf_;
142  PUSHMI_TEMPLATE(class Out)
143  (requires Receiver<Out>&& Invocable<const SDSF&, In&, Out>)
144  void operator()(In& in, Out out) const {
145  sdsf_(in, std::move(out));
146  }
147 };
148 template <class In, class TSDSF>
150  TSDSF tsdsf_;
151  PUSHMI_TEMPLATE(class CV, class Out)
152  (requires Receiver<Out>&& Invocable<const TSDSF&, In&, CV, Out>)
153  void operator()(In& in, CV cv, Out out) const {
154  tsdsf_(in, cv, std::move(out));
155  }
156 };
157 
158 PUSHMI_TEMPLATE(class In, class FN)
159 (requires Sender<In>&& SemiMovable<FN> PUSHMI_BROKEN_SUBSUMPTION(
160  &&not ConstrainedSender<In>))
161 auto submit_transform_out(FN fn) {
163 }
164 
165 PUSHMI_TEMPLATE(class In, class FN)
166 (requires ConstrainedSender<In>&& SemiMovable<FN>)
168  FN fn) {
170 }
171 
172 PUSHMI_TEMPLATE(class In, class SDSF, class TSDSF)
173 (requires Sender<In>&& SemiMovable<SDSF>&& SemiMovable<TSDSF>
175  &&not ConstrainedSender<
176  In>))
177 auto submit_transform_out(SDSF sdsf, TSDSF) {
179 }
180 
181 PUSHMI_TEMPLATE(class In, class SDSF, class TSDSF)
182 (requires ConstrainedSender<In>&& SemiMovable<SDSF>&&
183  SemiMovable<TSDSF>)
184 auto submit_transform_out(SDSF, TSDSF tsdsf) {
186 }
187 
188 template <
189  class Cardinality,
190  bool IsConstrained = false,
191  bool IsTime = false,
192  bool IsFlow = false>
193 struct make_sender;
194 template <>
195 struct make_sender<is_single<>> : construct_deduced<single_sender> {};
196 template <>
197 struct make_sender<is_many<>> : construct_deduced<many_sender> {};
198 template <>
199 struct make_sender<is_single<>, false, false, true>
200  : construct_deduced<flow_single_sender> {};
201 template <>
202 struct make_sender<is_many<>, false, false, true>
203  : construct_deduced<flow_many_sender> {};
204 template <>
205 struct make_sender<is_single<>, true, true, false>
206  : construct_deduced<time_single_sender> {};
207 template <>
208 struct make_sender<is_single<>, true, false, false>
209  : construct_deduced<constrained_single_sender> {};
210 
212  PUSHMI_TEMPLATE(class In, class... FN)
213  (requires Sender<In>)
214  auto operator()(In in, FN&&... fn) const {
215  using MakeSender = make_sender<
216  property_set_index_t<properties_t<In>, is_single<>>,
217  property_query_v<properties_t<In>, is_constrained<>>,
218  property_query_v<properties_t<In>, is_time<>>,
219  property_query_v<properties_t<In>, is_flow<>>>;
220  return MakeSender{}(std::move(in), (FN &&) fn...);
221  }
222 } const sender_from{};
223 
225  class In,
226  class Out,
227  bool SenderRequires,
228  bool SingleSenderRequires,
229  bool TimeSingleSenderRequires)
230 (requires Sender<In>&& Receiver<Out>)constexpr bool sender_requires_from() {
231  PUSHMI_IF_CONSTEXPR_RETURN(((bool)TimeSenderTo<In, Out>)(
232  return TimeSingleSenderRequires;
233  ) else (
234  PUSHMI_IF_CONSTEXPR_RETURN(((bool)SenderTo<In, Out>)(
235  return SingleSenderRequires;
236  ) else (
237  PUSHMI_IF_CONSTEXPR_RETURN(((bool) SenderTo<In, Out>)(
238  return SenderRequires;
239  ) else (
240 
241  ))
242  ))
243  ))
244 }
245 
246 struct set_value_fn {
247  private:
248  template <class... VN>
249  struct impl {
250  std::tuple<VN...> vn_;
251  PUSHMI_TEMPLATE(class Out)
252  (requires ReceiveValue<Out, VN...>)
253  void operator()(Out out) {
256  std::tuple_cat(std::tuple<Out>{std::move(out)}, std::move(vn_)));
257  }
258  };
259 
260  public:
261  template <class... VN>
262  auto operator()(VN&&... vn) const {
263  return impl<std::decay_t<VN>...>{(VN &&) vn...};
264  }
265 };
266 
267 struct set_error_fn {
268  private:
269  template <class E>
270  struct impl {
271  E e_;
272  PUSHMI_TEMPLATE(class Out)
273  (requires ReceiveError<Out, E>)
274  void operator()(Out out) {
275  set_error(out, std::move(e_));
276  }
277  };
278 
279  public:
280  PUSHMI_TEMPLATE(class E)
281  (requires SemiMovable<E>)
282  auto operator()(E e) const {
283  return impl<E>{std::move(e)};
284  }
285 };
286 
287 struct set_done_fn {
288  private:
289  struct impl {
290  PUSHMI_TEMPLATE(class Out)
291  (requires Receiver<Out>)
292  void operator()(Out out) {
293  set_done(out);
294  }
295  };
296 
297  public:
298  auto operator()() const {
299  return impl{};
300  }
301 };
302 
304  private:
305  template <class Up>
306  struct impl {
307  Up up_;
308  PUSHMI_TEMPLATE(class Out)
309  (requires Receiver<Out>)
310  void operator()(Out out) {
311  set_starting(out, std::move(up_));
312  }
313  };
314 
315  public:
316  PUSHMI_TEMPLATE(class Up)
317  (requires Receiver<Up>)
318  auto operator()(Up up) const {
319  return impl<Up>{std::move(up)};
320  }
321 };
322 
323 struct executor_fn {
324  private:
325  struct impl {
326  PUSHMI_TEMPLATE(class In)
327  (requires Sender<In>)
328  auto operator()(In& in) const {
329  return executor(in);
330  }
331  };
332 
333  public:
334  auto operator()() const {
335  return impl{};
336  }
337 };
338 
339 struct do_submit_fn {
340  private:
341  template <class Out>
342  struct impl {
343  Out out_;
344  PUSHMI_TEMPLATE(class In)
345  (requires SenderTo<In, Out>)
346  void operator()(In& in) {
347  submit(in, std::move(out_));
348  }
349  };
350  template <class TP, class Out>
351  struct time_impl {
352  TP tp_;
353  Out out_;
354  PUSHMI_TEMPLATE(class In)
355  (requires TimeSenderTo<In, Out>)
356  void operator()(In& in) {
357  submit(in, std::move(tp_), std::move(out_));
358  }
359  };
360 
361  public:
362  PUSHMI_TEMPLATE(class Out)
363  (requires Receiver<Out>)
364  auto operator()(Out out) const {
365  return impl<Out>{std::move(out)};
366  }
367  PUSHMI_TEMPLATE(class TP, class Out)
368  (requires Receiver<Out>)
369  auto operator()(TP tp, Out out) const {
370  return time_impl<TP, Out>{std::move(tp), std::move(out)};
371  }
372 };
373 
374 struct top_fn {
375  private:
376  struct impl {
377  PUSHMI_TEMPLATE(class In)
378  (requires ConstrainedSender<In>)
379  auto operator()(In& in) const {
381  }
382  };
383 
384  public:
385  auto operator()() const {
386  return impl{};
387  }
388 };
389 
390 struct now_fn {
391  private:
392  struct impl {
393  PUSHMI_TEMPLATE(class In)
394  (requires TimeSender<In>)
395  auto operator()(In& in) const {
397  }
398  };
399 
400  public:
401  auto operator()() const {
402  return impl{};
403  }
404 };
405 
406 } // namespace detail
407 
408 namespace extension_operators {
409 
418 
419 } // namespace extension_operators
420 
421 } // namespace pushmi
422 } // namespace folly
::folly::pushmi::invoke_result_t< MakeReceiver &, AN... > receiver_type
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::invoke_fn invoke
auto f
requires Sender< In > &&SemiMovable< FN > PUSHMI_BROKEN_SUBSUMPTION not auto submit_transform_out(FN fn)
auto on_submit(Fns...fns) -> on_submit_fn< Fns... >
Definition: boosters.h:318
typename receiver_from_fn< In >::template receiver_type< AN... > receiver_type_t
std::chrono::steady_clock::time_point now()
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
PUSHMI_INLINE_VAR constexpr __adl::set_error_fn set_error
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
PUSHMI_INLINE_VAR constexpr detail::top_fn top
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
std::make_index_sequence< std::tuple_size< Tuple >::value > tupidxs
requires requires(::folly::pushmi::invoke(std::declval< F >(), std::get< Is >(std::declval< Tuple >())...))) const expr decltype(auto) apply_impl(F &&f
std::enable_if_t< PropertySet< PS > &&Property< P >, decltype(detail::__property_set_index_fn< P >(PS{}))> property_set_index_t
Definition: properties.h:148
static const char *const value
Definition: Conv.cpp:50
#define PUSHMI_INLINE_VAR
Definition: concept_def.h:60
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::detail::sender_from_fn sender_from
PUSHMI_INLINE_VAR constexpr __adl::set_starting_fn set_starting
#define PUSHMI_IF_CONSTEXPR_RETURN(LIST)
Definition: if_constexpr.h:135
PUSHMI_INLINE_VAR constexpr __adl::get_top_fn now
PUSHMI_INLINE_VAR constexpr __adl::get_top_fn top
PUSHMI_INLINE_VAR constexpr __adl::set_value_fn set_value
#define PUSHMI_TYPE_CONSTRAINT(...)
Definition: concept_def.h:420
PUSHMI_INLINE_VAR constexpr __adl::do_submit_fn submit
PUSHMI_TEMPLATE(class In, class Out, bool SenderRequires, bool SingleSenderRequires, bool TimeSingleSenderRequires)(requires Sender< In > &&Receiver< Out >) constexpr bool sender_requires_from()
decltype(folly::pushmi::invoke(std::declval< F >(), std::declval< As >()...)) invoke_result_t
Definition: functional.h:47
#define PUSHMI_BROKEN_SUBSUMPTION(...)
Definition: concept_def.h:419
decltype(auto) constexpr apply(F &&func, Tuple &&tuple)
Definition: ApplyTuple.h:87
PUSHMI_INLINE_VAR constexpr __adl::set_done_fn set_done