proxygen
Future.h
Go to the documentation of this file.
1 /*
2  * Copyright 2014-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 <algorithm>
19 #include <exception>
20 #include <functional>
21 #include <memory>
22 #include <type_traits>
23 #include <vector>
24 
25 #include <folly/Optional.h>
26 #include <folly/Portability.h>
27 #include <folly/ScopeGuard.h>
28 #include <folly/Try.h>
29 #include <folly/Unit.h>
30 #include <folly/Utility.h>
34 #include <folly/futures/Promise.h>
36 #include <folly/lang/Exception.h>
37 
38 #if FOLLY_HAS_COROUTINES
40 #include <experimental/coroutine>
41 #endif
42 
43 // boring predeclarations and details
45 
46 // not-boring helpers, e.g. all in folly::futures, makeFuture variants, etc.
47 // Needs to be included after Future-pre.h and before Future-inl.h
48 #include <folly/futures/helpers.h>
49 
50 namespace folly {
51 
52 class FOLLY_EXPORT FutureException : public std::logic_error {
53  public:
54  using std::logic_error::logic_error;
55 };
56 
58  public:
59  FutureInvalid() : FutureException("Future invalid") {}
60 };
61 
68  public:
69  FutureAlreadyContinued() : FutureException("Future already continued") {}
70 };
71 
73  public:
74  FutureNotReady() : FutureException("Future not ready") {}
75 };
76 
78  public:
79  FutureCancellation() : FutureException("Future was cancelled") {}
80 };
81 
83  public:
84  FutureTimeout() : FutureException("Timed out") {}
85 };
86 
88  public:
90  : FutureException("Predicate does not obtain") {}
91 };
92 
94  public:
95  FutureNoTimekeeper() : FutureException("No timekeeper available") {}
96 };
97 
99  public:
100  FutureNoExecutor() : FutureException("No executor provided to via") {}
101 };
102 
103 template <class T>
104 class Future;
105 
106 template <class T>
107 class SemiFuture;
108 
109 template <class T>
111 
112 namespace futures {
113 namespace detail {
114 template <class T>
115 class FutureBase {
116  public:
117  typedef T value_type;
118 
126  template <
127  class T2 = T,
128  typename = typename std::enable_if<
131  /* implicit */ FutureBase(T2&& val);
132 
140  template <class T2 = T>
141  /* implicit */ FutureBase(
142  typename std::enable_if<std::is_same<Unit, T2>::value>::type*);
143 
144  template <
145  class... Args,
146  typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
147  type = 0>
148  explicit FutureBase(in_place_t, Args&&... args);
149 
150  FutureBase(FutureBase<T> const&) = delete;
151  FutureBase(SemiFuture<T>&&) noexcept;
152  FutureBase(Future<T>&&) noexcept;
153 
154  // not copyable
155  FutureBase(Future<T> const&) = delete;
156  FutureBase(SemiFuture<T> const&) = delete;
157 
158  ~FutureBase();
159 
162  bool valid() const noexcept {
163  return core_ != nullptr;
164  }
165 
184  T& value() &;
185  T const& value() const&;
186  T&& value() &&;
187  T const&& value() const&&;
188 
205  Try<T>& result() &;
206  Try<T> const& result() const&;
207  Try<T>&& result() &&;
208  Try<T> const&& result() const&&;
209 
215  bool isReady() const;
216 
226  bool hasValue() const;
227 
237  bool hasException() const;
238 
253 
259  template <class F>
260  void setCallback_(F&& func);
261 
262  template <class F>
263  void setCallback_(F&& func, std::shared_ptr<folly::RequestContext> context);
264 
331  void raise(exception_wrapper interrupt);
332 
335  template <class E>
336  void raise(E&& exception) {
338  std::forward<E>(exception)));
339  }
340 
343  void cancel() {
344  raise(FutureCancellation());
345  }
346 
347  // Returns this future's executor priority.
348  int8_t getPriority() const {
349  return getCore().getPriority();
350  }
351 
352  protected:
353  friend class Promise<T>;
354  template <class>
355  friend class SemiFuture;
356  template <class>
357  friend class Future;
358 
360 
361  // Throws FutureInvalid if there is no shared state object; else returns it
362  // by ref.
363  //
364  // Implementation methods should usually use this instead of `this->core_`.
365  // The latter should be used only when you need the possibly-null pointer.
367  return getCoreImpl(*this);
368  }
369  Core const& getCore() const {
370  return getCoreImpl(*this);
371  }
372 
373  template <typename Self>
374  static decltype(auto) getCoreImpl(Self& self) {
375  if (!self.core_) {
376  throw_exception<FutureInvalid>();
377  }
378  return *self.core_;
379  }
380 
382  return getCoreTryChecked(*this);
383  }
384  Try<T> const& getCoreTryChecked() const {
385  return getCoreTryChecked(*this);
386  }
387 
388  template <typename Self>
389  static decltype(auto) getCoreTryChecked(Self& self) {
390  auto& core = self.getCore();
391  if (!core.hasResult()) {
392  throw_exception<FutureNotReady>();
393  }
394  return core.getTry();
395  }
396 
397  // shared core state object
398  // usually you should use `getCore()` instead of directly accessing `core_`.
400 
401  explicit FutureBase(Core* obj) : core_(obj) {}
402 
404 
405  void detach();
406 
407  void throwIfInvalid() const;
408  void throwIfContinued() const;
409 
410  void assign(FutureBase<T>&& other) noexcept;
411 
413  return getCore().getExecutor();
414  }
415 
416  // Sets the Executor within the Core state object of `this`.
417  // Must be called either before attaching a callback or after the callback
418  // has already been invoked, but not concurrently with anything which might
419  // trigger invocation of the callback.
421  getCore().setExecutor(x, priority);
422  }
423 
426  int8_t priority = Executor::MID_PRI) {
427  getCore().setExecutor(std::move(x), priority);
428  }
429 
430  // Variant: returns a value
431  // e.g. f.thenTry([](Try<T> t){ return t.value(); });
432  template <typename F, typename R>
434  thenImplementation(F&& func, R);
435 
436  // Variant: returns a Future
437  // e.g. f.thenTry([](Try<T> t){ return makeFuture<T>(t); });
438  template <typename F, typename R>
440  thenImplementation(F&& func, R);
441 
442  template <typename E>
443  SemiFuture<T> withinImplementation(Duration dur, E e, Timekeeper* tk) &&;
444 };
445 template <class T>
447 
448 class DeferredExecutor;
449 
450 template <typename T>
452 
453 template <typename T>
455  SemiFuture<T>& future);
456 } // namespace detail
457 } // namespace futures
458 
487 template <class T>
488 class SemiFuture : private futures::detail::FutureBase<T> {
489  private:
492  using TimePoint = std::chrono::system_clock::time_point;
493 
494  public:
495  ~SemiFuture();
496 
502  static SemiFuture<T> makeEmpty();
503 
505  using typename Base::value_type;
506 
516  template <
517  class T2 = T,
518  typename = typename std::enable_if<
521  /* implicit */ SemiFuture(T2&& val) : Base(std::forward<T2>(val)) {}
522 
530  template <class T2 = T>
531  /* implicit */ SemiFuture(
532  typename std::enable_if<std::is_same<Unit, T2>::value>::type* p = nullptr)
533  : Base(p) {}
534 
544  template <
545  class... Args,
546  typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
547  type = 0>
548  explicit SemiFuture(in_place_t, Args&&... args)
549  : Base(in_place, std::forward<Args>(args)...) {}
550 
551  SemiFuture(SemiFuture<T> const&) = delete;
552  // movable
554  // safe move-constructabilty from Future
555  /* implicit */ SemiFuture(Future<T>&&) noexcept;
556 
557  using Base::cancel;
558  using Base::getPriority;
559  using Base::hasException;
560  using Base::hasValue;
561  using Base::isReady;
562  using Base::poll;
563  using Base::raise;
564  using Base::result;
565  using Base::setCallback_;
566  using Base::valid;
567  using Base::value;
568 
569  SemiFuture& operator=(SemiFuture const&) = delete;
570  SemiFuture& operator=(SemiFuture&&) noexcept;
571  SemiFuture& operator=(Future<T>&&) noexcept;
572 
584  T get() &&;
585 
586  [[deprecated("must be rvalue-qualified, e.g., std::move(future).get()")]] T
587  get() & = delete;
588 
600  T get(Duration dur) &&;
601 
602  [[deprecated("must be rvalue-qualified, e.g., std::move(future).get(dur)")]] T
603  get(Duration dur) & = delete;
604 
615  Try<T> getTry() &&;
616 
628  Try<T> getTry(Duration dur) &&;
629 
642  SemiFuture<T>& wait() &;
643 
657  SemiFuture<T>&& wait() &&;
658 
669  bool wait(Duration dur) &&;
670 
673 
674  Future<T> via(
675  Executor::KeepAlive<> executor,
676  int8_t priority = Executor::MID_PRI) &&;
677 
696  template <typename F>
698  defer(F&& func) &&;
699 
700  template <typename R, typename... Args>
701  auto defer(R (&func)(Args...)) && {
702  return std::move(*this).defer(&func);
703  }
704 
715  template <typename F>
717  deferValue(F&& func) &&;
718 
719  template <typename R, typename... Args>
720  auto deferValue(R (&func)(Args...)) && {
721  return std::move(*this).deferValue(&func);
722  }
723 
750  template <class ExceptionType, class F>
751  SemiFuture<T> deferError(F&& func) &&;
752 
753  template <class ExceptionType, class R, class... Args>
754  SemiFuture<T> deferError(R (&func)(Args...)) && {
755  return std::move(*this).template deferError<ExceptionType>(&func);
756  }
757 
782  template <class F>
783  SemiFuture<T> deferError(F&& func) &&;
784 
785  template <class R, class... Args>
786  SemiFuture<T> deferError(R (&func)(Args...)) && {
787  return std::move(*this).deferError(&func);
788  }
789 
790  SemiFuture<T> within(Duration dur, Timekeeper* tk = nullptr) && {
791  return std::move(*this).within(dur, FutureTimeout(), tk);
792  }
793 
794  template <class E>
795  SemiFuture<T> within(Duration dur, E e, Timekeeper* tk = nullptr) && {
796  return this->isReady() ? std::move(*this)
797  : std::move(*this).withinImplementation(dur, e, tk);
798  }
799 
811  SemiFuture<T> delayed(Duration dur, Timekeeper* tk = nullptr) &&;
812 
829  Future<T> toUnsafeFuture() &&;
830 
831 #if FOLLY_HAS_COROUTINES
832  class promise_type {
833  public:
834  SemiFuture get_return_object() {
835  return promise_.getSemiFuture();
836  }
837 
838  std::experimental::suspend_never initial_suspend() {
839  return {};
840  }
841 
842  std::experimental::suspend_never final_suspend() {
843  return {};
844  }
845 
846  void return_value(const T& value) {
847  promise_.setValue(value);
848  }
849 
850  void return_value(T&& value) {
851  promise_.setValue(std::move(value));
852  }
853 
854  void unhandled_exception() {
855  try {
856  std::rethrow_exception(std::current_exception());
857  } catch (std::exception& e) {
858  promise_.setException(exception_wrapper(std::current_exception(), e));
859  } catch (...) {
860  promise_.setException(exception_wrapper(std::current_exception()));
861  }
862  }
863 
864  private:
866  };
867 
868  // Customise the co_viaIfAsync() operator so that SemiFuture<T> can be
869  // directly awaited within a folly::coro::Task coroutine.
870  friend Future<T> co_viaIfAsync(
871  folly::Executor* executor,
872  SemiFuture<T>&& future) noexcept {
873  return std::move(future).via(executor);
874  }
875 
876 #endif
877 
878  private:
879  friend class Promise<T>;
880  template <class>
882  template <class>
883  friend class SemiFuture;
884  template <class>
885  friend class Future;
887  futures::detail::stealDeferredExecutor<T>(SemiFuture&);
888  friend DeferredExecutor* futures::detail::getDeferredExecutor<T>(SemiFuture&);
889 
890  using Base::setExecutor;
891  using Base::throwIfInvalid;
892  using typename Base::Core;
893 
894  template <class T2>
896 
897  explicit SemiFuture(Core* obj) : Base(obj) {}
898 
900  : Base(futures::detail::EmptyConstruct{}) {}
901 
902  // Throws FutureInvalid if !this->core_
904 
905  // Throws FutureInvalid if !this->core_
907 
919  SemiFuture<T>& wait(Duration dur) &;
920 
921  static void releaseDeferredExecutor(Core* core);
922 };
923 
924 template <class T>
925 std::pair<Promise<T>, SemiFuture<T>> makePromiseContract() {
926  auto p = Promise<T>();
927  auto f = p.getSemiFuture();
928  return std::make_pair(std::move(p), std::move(f));
929 }
930 
959 template <class T>
960 class Future : private futures::detail::FutureBase<T> {
961  private:
963 
964  public:
966  using typename Base::value_type;
967 
976  template <
977  class T2 = T,
978  typename = typename std::enable_if<
981  /* implicit */ Future(T2&& val) : Base(std::forward<T2>(val)) {}
982 
990  template <class T2 = T>
991  /* implicit */ Future(
992  typename std::enable_if<std::is_same<Unit, T2>::value>::type* p = nullptr)
993  : Base(p) {}
994 
1004  template <
1005  class... Args,
1006  typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
1007  type = 0>
1008  explicit Future(in_place_t, Args&&... args)
1009  : Base(in_place, std::forward<Args>(args)...) {}
1010 
1011  Future(Future<T> const&) = delete;
1012  // movable
1014 
1015  // converting move
1016  template <
1017  class T2,
1018  typename std::enable_if<
1022  int>::type = 0>
1023  /* implicit */ Future(Future<T2>&&);
1024  template <
1025  class T2,
1026  typename std::enable_if<
1029  !std::is_convertible<T2&&, T>::value,
1030  int>::type = 0>
1031  explicit Future(Future<T2>&&);
1032  template <
1033  class T2,
1034  typename std::enable_if<
1037  int>::type = 0>
1038  Future& operator=(Future<T2>&&);
1039 
1040  using Base::cancel;
1041  using Base::getPriority;
1042  using Base::hasException;
1043  using Base::hasValue;
1044  using Base::isReady;
1045  using Base::poll;
1046  using Base::raise;
1047  using Base::result;
1048  using Base::setCallback_;
1049  using Base::valid;
1050  using Base::value;
1051 
1057  static Future<T> makeEmpty();
1058 
1059  // not copyable
1060  Future& operator=(Future const&) = delete;
1061 
1062  // movable
1063  Future& operator=(Future&&) noexcept;
1064 
1070  T getVia(DrivableExecutor* e);
1071 
1077  T getVia(TimedDrivableExecutor* e, Duration dur);
1078 
1082  Try<T>& getTryVia(DrivableExecutor* e);
1083 
1086  Try<T>& getTryVia(TimedDrivableExecutor* e, Duration dur);
1087 
1100  template <class F = T>
1101  typename std::
1103  unwrap() &&;
1104 
1115  Future<T> via(Executor* executor, int8_t priority = Executor::MID_PRI) &&;
1116 
1117  Future<T> via(
1118  Executor::KeepAlive<> executor,
1119  int8_t priority = Executor::MID_PRI) &&;
1120 
1134  Future<T> via(Executor* executor, int8_t priority = Executor::MID_PRI) &;
1135 
1136  Future<T> via(
1137  Executor::KeepAlive<> executor,
1138  int8_t priority = Executor::MID_PRI) &;
1139 
1162  template <typename F, typename R = futures::detail::callableResult<T, F>>
1163  [[deprecated("ERROR: use thenValue instead")]] typename std::enable_if<
1165  typename R::Return>::type
1166  then(F&& func) && {
1167  return std::move(*this).thenValue(std::forward<F>(func));
1168  }
1169 
1170  template <typename F, typename R = futures::detail::callableResult<T, F>>
1171  [[deprecated("ERROR: use thenTry instead")]] typename std::enable_if<
1172  !is_invocable<F, T&&>::value && !is_invocable<F>::value,
1173  typename R::Return>::type
1174  then(F&& func) && {
1175  return std::move(*this).thenTry(std::forward<F>(func));
1176  }
1177 
1178  template <typename F, typename R = futures::detail::callableResult<T, F>>
1179  [[deprecated(
1180  "ERROR: use thenValue with auto&& or folly::Unit parameter instead")]]
1181  typename std::enable_if<is_invocable<F>::value, typename R::Return>::type
1182  then(F&& func) && = delete;
1183 
1184  // clang-format off
1185  template <typename F, typename R = futures::detail::callableResult<T, F>>
1186  [[deprecated(
1187  "must be rvalue-qualified, e.g., std::move(future).thenValue(...)")]]
1188  typename R::Return then(F&& func) & = delete;
1189  // clang-format on
1190 
1211  template <typename R, typename Caller, typename... Args>
1213  R (Caller::*func)(Args...),
1214  Caller* instance) &&;
1215 
1216  // clang-format off
1217  template <typename R, typename Caller, typename... Args>
1218  [[deprecated(
1219  "must be rvalue-qualified, e.g., std::move(future).then(...)")]]
1221  then(R (Caller::*func)(Args...), Caller* instance) & = delete;
1222  // clang-format on
1223 
1246  template <class Arg>
1247  auto then(Executor* x, Arg&& arg) && {
1248  auto oldX = this->getExecutor();
1249  this->setExecutor(x);
1250 
1251  // TODO(T29171940): thenImplementation here is ambiguous
1252  // as then used to be but that is better than keeping then in the public
1253  // API.
1255  return std::move(*this)
1256  .thenImplementation(std::forward<Arg>(arg), R{})
1257  .via(oldX);
1258  }
1259 
1260  template <class R, class Caller, class... Args>
1261  auto then(Executor* x, R (Caller::*func)(Args...), Caller* instance) && {
1262  auto oldX = this->getExecutor();
1263  this->setExecutor(x);
1264 
1265  return std::move(*this).then(func, instance).via(oldX);
1266  }
1267 
1268  template <class Arg, class... Args>
1269  [[deprecated(
1270  "must be rvalue-qualified, e.g., std::move(future).then(...)")]] auto
1271  then(Executor* x, Arg&& arg, Args&&... args) & = delete;
1272 
1294  template <typename F>
1296  F&& func) &&;
1297 
1298  template <typename R, typename... Args>
1299  auto thenTry(R (&func)(Args...)) && {
1300  return std::move(*this).thenTry(&func);
1301  }
1302 
1324  template <typename F>
1326  thenValue(F&& func) &&;
1327 
1328  template <typename R, typename... Args>
1329  auto thenValue(R (&func)(Args...)) && {
1330  return std::move(*this).thenValue(&func);
1331  }
1332 
1357  template <class ExceptionType, class F>
1358  Future<T> thenError(F&& func) &&;
1359 
1360  template <class ExceptionType, class R, class... Args>
1361  Future<T> thenError(R (&func)(Args...)) && {
1362  return std::move(*this).template thenError<ExceptionType>(&func);
1363  }
1364 
1389  template <class F>
1390  Future<T> thenError(F&& func) &&;
1391 
1392  template <class R, class... Args>
1393  Future<T> thenError(R (&func)(Args...)) && {
1394  return std::move(*this).thenError(&func);
1395  }
1396 
1410  Future<Unit> then() &&;
1411 
1412  // clang-format off
1413  [[deprecated(
1414  "must be rvalue-qualified, e.g., std::move(future).thenValue()")]]
1415  Future<Unit> then() & = delete;
1416  // clang-format on
1417 
1432  return std::move(*this).then();
1433  }
1434 
1461  template <class F>
1462  typename std::enable_if<
1465  Future<T>>::type
1466  onError(F&& func) &&;
1467 
1479  template <class F>
1480  typename std::enable_if<
1483  Future<T>>::type
1484  onError(F&& func) &&;
1485 
1497  template <class F>
1498  typename std::enable_if<
1500  futures::detail::Extract<F>::ReturnsFuture::value,
1501  Future<T>>::type
1502  onError(F&& func) &&;
1503 
1515  template <class F>
1516  typename std::enable_if<
1518  !futures::detail::Extract<F>::ReturnsFuture::value,
1519  Future<T>>::type
1520  onError(F&& func) &&;
1521 
1522  // clang-format off
1523  template <class F>
1524  [[deprecated("use rvalue-qualified fn, eg, std::move(future).onError(...)")]]
1525  Future<T> onError(F&& func) & {
1526  return std::move(*this).onError(std::forward<F>(func));
1527  }
1528 
1543  template <class F>
1544  Future<T> ensure(F&& func) &&;
1545  // clang-format on
1546 
1570  template <class F>
1571  Future<T> onTimeout(Duration, F&& func, Timekeeper* = nullptr) &&;
1572 
1585  Future<T> within(Duration dur, Timekeeper* tk = nullptr) &&;
1586 
1600  template <class E>
1601  Future<T> within(Duration dur, E exception, Timekeeper* tk = nullptr) &&;
1602 
1614  Future<T> delayed(Duration, Timekeeper* = nullptr) &&;
1615 
1620  Future<T> delayedUnsafe(Duration, Timekeeper* = nullptr);
1621 
1632  T get() &&;
1633 
1634  [[deprecated("must be rvalue-qualified, e.g., std::move(future).get()")]] T
1635  get() & = delete;
1636 
1648  T get(Duration dur) &&;
1649 
1650  [[deprecated("must be rvalue-qualified, e.g., std::move(future).get(dur)")]] T
1651  get(Duration dur) & = delete;
1652 
1659  Try<T>& getTry();
1660 
1672  Future<T>& wait() &;
1673 
1686  Future<T>&& wait() &&;
1687 
1699  Future<T>& wait(Duration dur) &;
1700 
1713  Future<T>&& wait(Duration dur) &&;
1714 
1728  Future<T>& waitVia(DrivableExecutor* e) &;
1729 
1741  Future<T>&& waitVia(DrivableExecutor* e) &&;
1742 
1753  Future<T>& waitVia(TimedDrivableExecutor* e, Duration dur) &;
1754 
1767  Future<T>&& waitVia(TimedDrivableExecutor* e, Duration dur) &&;
1768 
1773  Future<bool> willEqual(Future<T>&);
1774 
1788  template <class F>
1789  Future<T> filter(F&& predicate) &&;
1790 
1803  template <class I, class F>
1804  Future<I> reduce(I&& initial, F&& func) &&;
1805 
1824  template <class Callback, class... Callbacks>
1825  auto thenMulti(Callback&& fn, Callbacks&&... fns) && {
1826  // thenMulti with two callbacks is just then(a).thenMulti(b, ...)
1827 
1828  // TODO(T29171940): Switch to thenImplementation here. It is ambiguous
1829  // as then used to be but that is better than keeping then in the public
1830  // API.
1832  return std::move(*this)
1833  .thenImplementation(std::forward<Callback>(fn), R{})
1834  .thenMulti(std::forward<Callbacks>(fns)...);
1835  }
1836 
1848  template <class Callback>
1849  auto thenMulti(Callback&& fn) && {
1850  // thenMulti with one callback is just a then
1851 
1852  // TODO(T29171940): Switch to thenImplementation here. It is ambiguous
1853  // as then used to be but that is better than keeping then in the public
1854  // API.
1856  return std::move(*this).thenImplementation(std::forward<Callback>(fn), R{});
1857  }
1858 
1859  template <class Callback>
1860  auto thenMulti(Callback&& fn) & {
1861  return std::move(*this).thenMulti(std::forward<Callback>(fn));
1862  }
1863 
1882  template <class Callback, class... Callbacks>
1883  auto
1884  thenMultiWithExecutor(Executor* x, Callback&& fn, Callbacks&&... fns) && {
1885  // thenMultiExecutor with two callbacks is
1886  // via(x).then(a).thenMulti(b, ...).via(oldX)
1887  auto oldX = this->getExecutor();
1888  this->setExecutor(x);
1889  // TODO(T29171940): Switch to thenImplementation here. It is ambiguous
1890  // as then used to be but that is better than keeping then in the public
1891  // API.
1893  return std::move(*this)
1894  .thenImplementation(std::forward<Callback>(fn), R{})
1895  .thenMulti(std::forward<Callbacks>(fns)...)
1896  .via(oldX);
1897  }
1898 
1899  template <class Callback>
1900  auto thenMultiWithExecutor(Executor* x, Callback&& fn) && {
1901  // thenMulti with one callback is just a then with an executor
1902  return std::move(*this).then(x, std::forward<Callback>(fn));
1903  }
1904 
1913  return SemiFuture<T>{std::move(*this)};
1914  }
1915 
1916 #if FOLLY_HAS_COROUTINES
1917 
1918  // Overload needed to customise behaviour of awaiting a Future<T>
1919  // inside a folly::coro::Task coroutine.
1920  friend Future<T> co_viaIfAsync(
1921  folly::Executor* executor,
1922  Future<T>&& future) noexcept {
1923  return std::move(future).via(executor);
1924  }
1925 
1926 #endif
1927 
1928  protected:
1929  friend class Promise<T>;
1930  template <class>
1932  template <class>
1933  friend class Future;
1934  template <class>
1935  friend class SemiFuture;
1936  template <class>
1937  friend class FutureSplitter;
1938 
1939  using Base::setExecutor;
1940  using Base::throwIfContinued;
1941  using Base::throwIfInvalid;
1942  using typename Base::Core;
1943 
1944  explicit Future(Core* obj) : Base(obj) {}
1945 
1947  : Base(futures::detail::EmptyConstruct{}) {}
1948 
1949  template <class T2>
1950  friend Future<T2> makeFuture(Try<T2>);
1951 
1955  template <class F>
1956  friend Future<Unit> times(int n, F&& thunk);
1957 
1962  template <class F>
1963  friend Future<Unit> when(bool p, F&& thunk);
1964 
1971  template <class P, class F>
1972  friend Future<Unit> whileDo(P&& predicate, F&& thunk);
1973 
1974  template <class FT>
1975  friend void futures::detail::convertFuture(
1976  SemiFuture<FT>&& sf,
1977  Future<FT>& f);
1978 };
1979 
2005 class Timekeeper {
2006  public:
2007  virtual ~Timekeeper() = default;
2008 
2018  virtual Future<Unit> after(Duration dur) = 0;
2019 
2028  template <class Clock>
2029  Future<Unit> at(std::chrono::time_point<Clock> when);
2030 };
2031 
2032 template <class T>
2033 std::pair<Promise<T>, Future<T>> makePromiseContract(Executor* e) {
2034  auto p = Promise<T>();
2035  auto f = p.getSemiFuture().via(e);
2036  return std::make_pair(std::move(p), std::move(f));
2037 }
2038 
2039 } // namespace folly
2040 
2041 #if FOLLY_HAS_COROUTINES
2042 
2043 namespace folly {
2044 namespace detail {
2045 
2046 template <typename T>
2047 class FutureAwaitable {
2048  public:
2049  explicit FutureAwaitable(folly::Future<T>&& future) noexcept
2050  : future_(std::move(future)) {}
2051 
2052  bool await_ready() const {
2053  return future_.isReady();
2054  }
2055 
2056  T await_resume() {
2057  return std::move(future_).value();
2058  }
2059 
2060  void await_suspend(std::experimental::coroutine_handle<> h) {
2061  future_.setCallback_([h](Try<T>&&) mutable {
2062  // Don't std::move() so the try is left in the future for await_resume()
2063  h.resume();
2064  });
2065  }
2066 
2067  private:
2068  folly::Future<T> future_;
2069 };
2070 
2071 } // namespace detail
2072 
2073 template <typename T>
2074 inline detail::FutureAwaitable<T>
2075 /* implicit */ operator co_await(Future<T>&& future) noexcept {
2076  return detail::FutureAwaitable<T>(std::move(future));
2077 }
2078 
2079 namespace coro {
2080 
2086 template <typename Awaitable>
2087 inline auto toSemiFuture(Awaitable awaitable) -> std::enable_if_t<
2088  !std::is_void<folly::coro::await_result_t<Awaitable>>::value,
2090  co_return co_await static_cast<Awaitable&&>(awaitable);
2091 }
2092 
2093 template <typename Awaitable>
2094 inline auto toSemiFuture(Awaitable awaitable) -> std::enable_if_t<
2095  std::is_void<folly::coro::await_result_t<Awaitable>>::value,
2096  SemiFuture<Unit>> {
2097  co_await static_cast<Awaitable&&>(awaitable);
2098  co_return Unit{};
2099 }
2100 
2101 } // namespace coro
2102 
2103 } // namespace folly
2104 #endif
2105 
2106 #include <folly/futures/Future-inl.h>
std::enable_if< !is_invocable< F, T && >::value &&!is_invocable< F >::value, typename R::Return >::type then(F &&func)&&
Definition: Future.h:1174
Definition: InvokeTest.cpp:58
*than *hazptr_holder h
Definition: Hazptr.h:116
auto f
Future< Unit > whileDo(P &&predicate, F &&thunk)
Definition: Future-inl.h:2335
auto thenMulti(Callback &&fn)&
Definition: Future.h:1860
folly::Executor * getExecutor()
Definition: futures.h:32
SemiFuture(futures::detail::EmptyConstruct) noexcept
Definition: Future.h:899
static const int8_t MID_PRI
Definition: Executor.h:49
PUSHMI_INLINE_VAR constexpr detail::filter_fn filter
Definition: filter.h:75
auto then(Executor *x, R(Caller::*func)(Args...), Caller *instance)&&
Definition: Future.h:1261
auto thenTry(R(&func)(Args...))&&
Definition: Future.h:1299
Future< T > thenError(R(&func)(Args...))&&
Definition: Future.h:1361
Future(typename std::enable_if< std::is_same< Unit, T2 >::value >::type *p=nullptr)
Definition: Future.h:991
auto deferValue(R(&func)(Args...))&&
Definition: Future.h:720
PskType type
context
Definition: CMakeCache.txt:563
auto then(Executor *x, Arg &&arg)&&
Definition: Future.h:1247
Executor * getExecutor() const
Definition: Future.h:412
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
auto co_viaIfAsync(folly::Executor *executor, Awaitable &&awaitable) -> ViaIfAsyncAwaitable< Awaitable >
Definition: ViaIfAsync.h:247
double val
Definition: String.cpp:273
void convertFuture(SemiFuture< T > &&sf, Future< T > &f)
Definition: Future-inl.h:2026
SemiFuture(Core *obj)
Definition: Future.h:897
folly::std T
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
Future(in_place_t, Args &&...args)
Definition: Future.h:1008
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::chrono::system_clock::time_point TimePoint
Definition: Future.h:492
SemiFuture(in_place_t, Args &&...args)
Definition: Future.h:548
#define FOLLY_EXPORT
Definition: CPortability.h:133
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::operators::defer_fn defer
in_place_tag in_place(in_place_tag={})
Definition: Utility.h:235
requires E e noexcept(noexcept(s.error(std::move(e))))
in_place_tag(&)(in_place_tag) in_place_t
Definition: Utility.h:229
auto defer(R(&func)(Args...))&&
Definition: Future.h:701
SemiFuture< T > semi()&&
Definition: Future.h:1912
auto thenMultiWithExecutor(Executor *x, Callback &&fn, Callbacks &&...fns)&&
Definition: Future.h:1884
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
SemiFuture(typename std::enable_if< std::is_same< Unit, T2 >::value >::type *p=nullptr)
Definition: Future.h:531
DeferredExecutor * getDeferredExecutor(SemiFuture< T > &future)
Definition: Future-inl.h:1395
Future(futures::detail::EmptyConstruct) noexcept
Definition: Future.h:1946
auto thenMultiWithExecutor(Executor *x, Callback &&fn)&&
Definition: Future.h:1900
auto thenMulti(Callback &&fn)&&
Definition: Future.h:1849
std::chrono::milliseconds Duration
Definition: Types.h:36
SemiFuture< T > within(Duration dur, E e, Timekeeper *tk=nullptr)&&
Definition: Future.h:795
SemiFuture< T > deferError(R(&func)(Args...))&&
Definition: Future.h:754
Future(T2 &&val)
Definition: Future.h:981
void setExecutor(Executor::KeepAlive<> x, int8_t priority=Executor::MID_PRI)
Definition: Future.h:424
SemiFuture< T > within(Duration dur, Timekeeper *tk=nullptr)&&
Definition: Future.h:790
Future< T > reduce(It first, It last, T &&initial, F &&func)
Definition: Future-inl.h:1753
Promise< Unit > promise_
bool wait(Waiter *waiter, bool shouldSleep, Waiter *&next)
Future< Unit > unit()&&
Definition: Future.h:1431
auto thenValue(R(&func)(Args...))&&
Definition: Future.h:1329
static const char *const value
Definition: Conv.cpp:50
Definition: Try.h:51
Future< Unit > when(bool p, F &&thunk)
Definition: Future-inl.h:2330
auto thenMulti(Callback &&fn, Callbacks &&...fns)&&
Definition: Future.h:1825
void setExecutor(Executor *x, int8_t priority=Executor::MID_PRI)
Definition: Future.h:420
std::pair< Promise< T >, SemiFuture< T > > makePromiseContract()
Definition: Future.h:925
SemiFuture(T2 &&val)
Definition: Future.h:521
Try< T > const & getCoreTryChecked() const
Definition: Future.h:384
Future< T > onError(F &&func)&
Definition: Future.h:1525
Core const & getCore() const
Definition: Future.h:369
int poll(PollDescriptor fds[], nfds_t nfds, int timeout)
Definition: NetOps.cpp:141
std::enable_if< !is_invocable< F >::value &&is_invocable< F, T && >::value, typename R::Return >::type then(F &&func)&&
Definition: Future.h:1166
const
Definition: upload.py:398
constexpr detail::Unwrap unwrap
Definition: Base-inl.h:2579
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
auto via(Executor *x, Func &&func) -> Future< typename isFutureOrSemiFuture< decltype(std::declval< Func >()())>::Inner >
Definition: Future-inl.h:1290
folly::Executor::KeepAlive< DeferredExecutor > stealDeferredExecutor(SemiFuture< T > &future)
Definition: Future-inl.h:1400
Future< Unit > times(const int n, F &&thunk)
Definition: Future-inl.h:2348
Future(Core *obj)
Definition: Future.h:1944
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
Future< T > thenError(R(&func)(Args...))&&
Definition: Future.h:1393
SemiFuture< T > deferError(R(&func)(Args...))&&
Definition: Future.h:786
internal::ReturnAction< R > Return(R value)
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712