proxygen
tap.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 
19 #include <cassert>
20 
21 namespace folly {
22 namespace pushmi {
23 
24 namespace detail {
25 
26 PUSHMI_TEMPLATE(class SideEffects, class Out)
27 (requires Receiver<SideEffects>&& Receiver<Out>)
28 struct tap_ {
29  SideEffects sideEffects;
30  Out out;
31 
32  // side effect has no effect on the properties.
34 
35  PUSHMI_TEMPLATE(class... VN)
36  (requires ReceiveValue<SideEffects, const std::remove_reference_t<VN>...>&&
37  ReceiveValue<
38  Out,
39  std::remove_reference_t<VN>...>)
40  void value(VN&&... vn) {
41  set_value(sideEffects, as_const(vn)...);
42  set_value(out, (VN &&) vn...);
43  }
44  PUSHMI_TEMPLATE(class E)
45  (requires ReceiveError<SideEffects, const E>&&
46  ReceiveError<Out, E>)
47  void error(E e) noexcept {
48  set_error(sideEffects, as_const(e));
49  set_error(out, std::move(e));
50  }
51  void done() {
52  set_done(sideEffects);
53  set_done(out);
54  }
55  PUSHMI_TEMPLATE(class Up, class UUp = std::remove_reference_t<Up>)
56  (requires FlowReceiver<SideEffects>&& FlowReceiver<Out>)
57  void starting(
58  Up&& up) {
59  // up is not made const because sideEffects is allowed to call methods on up
60  set_starting(sideEffects, up);
61  set_starting(out, (Up &&) up);
62  }
63 };
64 
65 PUSHMI_INLINE_VAR constexpr struct make_tap_fn {
66  PUSHMI_TEMPLATE(class SideEffects, class Out)
67  (requires Receiver<SideEffects>&& Receiver<Out>&&
68  Receiver<tap_<SideEffects, Out>>)
69  auto operator()(SideEffects se, Out out) const {
70  return tap_<SideEffects, Out>{std::move(se), std::move(out)};
71  }
72 } const make_tap{};
73 
74 struct tap_fn {
75  private:
76  PUSHMI_TEMPLATE(class In, class SideEffects)
77  (requires Sender<In>&& Receiver<SideEffects>)
78  static auto impl(
79  In in,
80  SideEffects sideEffects) {
82  std::move(in),
83  ::folly::pushmi::detail::submit_transform_out<In>(
84  out_impl<In, SideEffects>{std::move(sideEffects)}));
85  }
86 
87  template <class... AN>
88  struct in_impl {
89  std::tuple<AN...> args_;
90  PUSHMI_TEMPLATE(class In)
91  (requires Sender<In>)
92  auto operator()(In in) {
93  return tap_fn::impl(
94  std::move(in),
96  }
97  };
98  PUSHMI_TEMPLATE(class In, class SideEffects)
99  (requires Sender<In>&& Receiver<SideEffects>)
100  struct out_impl {
101  SideEffects sideEffects_;
102  PUSHMI_TEMPLATE(class Out)
103  (requires Receiver<Out>&& SenderTo<In, Out>&& SenderTo<
104  In,
105  decltype(
107  std::declval<SideEffects>(),
108  std::declval<Out>())))>)
109  auto operator()(Out out) const {
111  detail::make_tap(sideEffects_, std::move(out)))};
112  return gang;
113  }
114  };
115 
116  public:
117  template <class... AN>
118  auto operator()(AN... an) const {
119  return in_impl<AN...>{std::tuple<AN...>{std::move(an)...}};
120  }
121 };
122 
123 } // namespace detail
124 
125 namespace operators {
127 } // namespace operators
128 
129 } // namespace pushmi
130 } // namespace folly
requires FlowReceiver< SideEffects > &&FlowReceiver< Out > void starting(Up &&up)
Definition: tap.h:57
requires ReceiveValue< SideEffects, const std::remove_reference_t< VN >... > &&ReceiveValue< Out, std::remove_reference_t< VN >... > void value(VN &&...vn)
Definition: tap.h:40
PUSHMI_INLINE_VAR constexpr detail::tap_fn tap
Definition: tap.h:126
std::enable_if_t< PropertySet< __properties_t< property_set_traits< T >>>, __properties_t< property_set_traits< T >>> properties_t
Definition: properties.h:105
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
requires E e noexcept(noexcept(s.error(std::move(e))))
auto operator()(AN...an) const
Definition: tap.h:118
properties_t< Out > properties
Definition: tap.h:33
SideEffects sideEffects
Definition: tap.h:29
requires requires(::folly::pushmi::invoke(std::declval< F >(), std::get< Is >(std::declval< Tuple >())...))) const expr decltype(auto) apply_impl(F &&f
requires ReceiveError< SideEffects, const E > &&ReceiveError< Out, E > void error(E e) noexcept
Definition: tap.h:47
#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
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::detail::make_tap_fn make_tap
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::detail::as_const_fn as_const
PUSHMI_INLINE_VAR constexpr __adl::set_value_fn set_value
requires Sender< In > &&static Receiver< SideEffects > auto impl(In in, SideEffects sideEffects)
Definition: tap.h:78
PUSHMI_TEMPLATE(class In, class Out, bool SenderRequires, bool SingleSenderRequires, bool TimeSingleSenderRequires)(requires Sender< In > &&Receiver< Out >) constexpr bool sender_requires_from()
std::tuple< AN... > args_
Definition: tap.h:89
PUSHMI_INLINE_VAR constexpr __adl::set_done_fn set_done