time_single_sender.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #pragma once
  2. /*
  3. * Copyright 2018-present Facebook, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include <folly/experimental/pushmi/receiver.h>
  18. #include <folly/experimental/pushmi/executor.h>
  19. #include <folly/experimental/pushmi/inline.h>
  20. #include <folly/experimental/pushmi/constrained_single_sender.h>
  21. namespace pushmi {
  22. template <class E, class TP, class... VN>
  23. class any_time_single_sender
  24. : public any_constrained_single_sender<E, TP, VN...> {
  25. public:
  26. using properties = property_set<is_time<>, is_single<>>;
  27. constexpr any_time_single_sender() = default;
  28. template <class T>
  29. constexpr explicit any_time_single_sender(T t)
  30. : any_constrained_single_sender<E, TP, VN...>(std::move(t)) {}
  31. template <class T0, class T1, class... TN>
  32. constexpr any_time_single_sender(T0 t0, T1 t1, TN... tn)
  33. : any_constrained_single_sender<E, TP, VN...>(
  34. std::move(t0),
  35. std::move(t1),
  36. std::move(tn)...) {}
  37. any_time_executor<E, TP> executor() {
  38. return any_time_executor<E, TP>{
  39. any_constrained_single_sender<E, TP, VN...>::executor()};
  40. }
  41. };
  42. template <class SF, class NF, class EXF>
  43. class time_single_sender<SF, NF, EXF>
  44. : public constrained_single_sender<SF, NF, EXF> {
  45. public:
  46. using properties = property_set<is_time<>, is_single<>>;
  47. constexpr time_single_sender() = default;
  48. template <class T>
  49. constexpr explicit time_single_sender(T t)
  50. : constrained_single_sender<SF, NF, EXF>(std::move(t)) {}
  51. template <class T0, class T1, class... TN>
  52. constexpr time_single_sender(T0 t0, T1 t1, TN... tn)
  53. : constrained_single_sender<SF, NF, EXF>(
  54. std::move(t0),
  55. std::move(t1),
  56. std::move(tn)...) {}
  57. };
  58. template <PUSHMI_TYPE_CONSTRAINT(SemiMovable)... TN>
  59. class time_single_sender : public constrained_single_sender<TN...> {
  60. public:
  61. constexpr time_single_sender() = default;
  62. template <class T>
  63. constexpr explicit time_single_sender(T t)
  64. : constrained_single_sender<TN...>(std::move(t)) {}
  65. template <class C0, class C1, class... CN>
  66. constexpr time_single_sender(C0 c0, C1 c1, CN... cn)
  67. : constrained_single_sender<TN...>(
  68. std::move(c0),
  69. std::move(c1),
  70. std::move(cn)...) {}
  71. };
  72. template <>
  73. class time_single_sender<>
  74. : public time_single_sender<ignoreSF, systemNowF, inlineTimeEXF> {
  75. public:
  76. time_single_sender() = default;
  77. };
  78. ////////////////////////////////////////////////////////////////////////////////
  79. // make_time_single_sender
  80. PUSHMI_INLINE_VAR constexpr struct make_time_single_sender_fn {
  81. inline auto operator()() const {
  82. return time_single_sender<ignoreSF, systemNowF, inlineTimeEXF>{};
  83. }
  84. PUSHMI_TEMPLATE(class SF)
  85. (requires True<> PUSHMI_BROKEN_SUBSUMPTION(&& not Sender<SF>))
  86. auto operator()(SF sf) const {
  87. return time_single_sender<SF, systemNowF, inlineTimeEXF>{std::move(sf)};
  88. }
  89. PUSHMI_TEMPLATE (class SF, class EXF)
  90. (requires Invocable<EXF&> PUSHMI_BROKEN_SUBSUMPTION(&& not Sender<SF>))
  91. auto operator()(SF sf, EXF exf) const {
  92. return time_single_sender<SF, systemNowF, EXF>{
  93. std::move(sf), std::move(exf)};
  94. }
  95. PUSHMI_TEMPLATE (class SF, class NF, class EXF)
  96. (requires Invocable<NF&> && Invocable<EXF&> PUSHMI_BROKEN_SUBSUMPTION(&& not Sender<SF>))
  97. auto operator()(SF sf, EXF exf, NF nf) const {
  98. return time_single_sender<SF, NF, EXF>{
  99. std::move(sf), std::move(exf), std::move(nf)};
  100. }
  101. PUSHMI_TEMPLATE (class Data)
  102. (requires TimeSender<Data, is_single<>>)
  103. auto operator()(Data d) const {
  104. return time_single_sender<Data, passDSF, passDNF, passDEXF>{std::move(d)};
  105. }
  106. PUSHMI_TEMPLATE (class Data, class DSF)
  107. (requires TimeSender<Data, is_single<>>)
  108. auto operator()(Data d, DSF sf) const {
  109. return time_single_sender<Data, DSF, passDNF, passDEXF>{
  110. std::move(d), std::move(sf)};
  111. }
  112. PUSHMI_TEMPLATE (class Data, class DSF, class DEXF)
  113. (requires TimeSender<Data, is_single<>> && Invocable<DEXF&, Data&>)
  114. auto operator()(Data d, DSF sf, DEXF exf) const {
  115. return time_single_sender<Data, DSF, passDNF, DEXF>{
  116. std::move(d), std::move(sf), std::move(exf)};
  117. }
  118. PUSHMI_TEMPLATE (class Data, class DSF, class DNF, class DEXF)
  119. (requires TimeSender<Data, is_single<>> && Invocable<DNF&, Data&> &&
  120. Invocable<DEXF&, Data&>)
  121. auto operator()(Data d, DSF sf, DEXF exf, DNF nf) const {
  122. return time_single_sender<Data, DSF, DNF, DEXF>{
  123. std::move(d), std::move(sf), std::move(exf), std::move(nf)};
  124. }
  125. } const make_time_single_sender {};
  126. ////////////////////////////////////////////////////////////////////////////////
  127. // deduction guides
  128. #if __cpp_deduction_guides >= 201703
  129. time_single_sender() -> time_single_sender<ignoreSF, systemNowF, inlineTimeEXF>;
  130. PUSHMI_TEMPLATE(class SF)
  131. (requires True<> PUSHMI_BROKEN_SUBSUMPTION(&& not Sender<SF>))
  132. time_single_sender(SF) -> time_single_sender<SF, systemNowF, inlineTimeEXF>;
  133. PUSHMI_TEMPLATE (class SF, class EXF)
  134. (requires Invocable<EXF&> PUSHMI_BROKEN_SUBSUMPTION(&& not Sender<SF>))
  135. time_single_sender(SF, EXF) -> time_single_sender<SF, systemNowF, EXF>;
  136. PUSHMI_TEMPLATE (class SF, class NF, class EXF)
  137. (requires Invocable<NF&> && Invocable<EXF&>
  138. PUSHMI_BROKEN_SUBSUMPTION(&& not Sender<SF>))
  139. time_single_sender(SF, EXF, NF) -> time_single_sender<SF, NF, EXF>;
  140. PUSHMI_TEMPLATE (class Data, class DSF)
  141. (requires TimeSender<Data, is_single<>>)
  142. time_single_sender(Data, DSF) ->
  143. time_single_sender<Data, DSF, passDNF, passDEXF>;
  144. PUSHMI_TEMPLATE (class Data, class DSF, class DEXF)
  145. (requires TimeSender<Data, is_single<>> && Invocable<DEXF&, Data&>)
  146. time_single_sender(Data, DSF, DEXF) ->
  147. time_single_sender<Data, DSF, passDNF, DEXF>;
  148. PUSHMI_TEMPLATE (class Data, class DSF, class DNF, class DEXF)
  149. (requires TimeSender<Data, is_single<>> && Invocable<DNF&, Data&> &&
  150. Invocable<DEXF&, Data&>)
  151. time_single_sender(Data, DSF, DEXF, DNF) ->
  152. time_single_sender<Data, DSF, DNF, DEXF>;
  153. #endif
  154. template<>
  155. struct construct_deduced<time_single_sender>
  156. : make_time_single_sender_fn {};
  157. } //namespace pushmi