399574701f0104de12055b39aecd32b35d07208f
[folly.git] / folly / futures / Future.h
1 /*
2  * Copyright 2017 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
17 #pragma once
18
19 #include <algorithm>
20 #include <exception>
21 #include <functional>
22 #include <memory>
23 #include <type_traits>
24 #include <vector>
25
26 #include <folly/Optional.h>
27 #include <folly/Portability.h>
28 #include <folly/Try.h>
29 #include <folly/Utility.h>
30 #include <folly/executors/DrivableExecutor.h>
31 #include <folly/futures/FutureException.h>
32 #include <folly/futures/Promise.h>
33 #include <folly/futures/detail/Types.h>
34
35 // boring predeclarations and details
36 #include <folly/futures/Future-pre.h>
37
38 // not-boring helpers, e.g. all in folly::futures, makeFuture variants, etc.
39 // Needs to be included after Future-pre.h and before Future-inl.h
40 #include <folly/futures/helpers.h>
41
42 namespace folly {
43
44 template <class T>
45 class Future;
46
47 template <class T>
48 class SemiFuture;
49
50 namespace futures {
51 namespace detail {
52 template <class T>
53 class FutureBase {
54  public:
55   typedef T value_type;
56
57   /// Construct a Future from a value (perfect forwarding)
58   template <
59       class T2 = T,
60       typename = typename std::enable_if<
61           !isFuture<typename std::decay<T2>::type>::value>::type>
62   /* implicit */ FutureBase(T2&& val);
63
64   template <class T2 = T>
65   /* implicit */ FutureBase(
66       typename std::enable_if<std::is_same<Unit, T2>::value>::type*);
67
68   template <
69       class... Args,
70       typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
71           type = 0>
72   explicit FutureBase(in_place_t, Args&&... args);
73
74   FutureBase(FutureBase<T> const&) = delete;
75   FutureBase(SemiFuture<T>&&) noexcept;
76   FutureBase(Future<T>&&) noexcept;
77
78   // not copyable
79   FutureBase(Future<T> const&) = delete;
80   FutureBase(SemiFuture<T> const&) = delete;
81
82   ~FutureBase();
83
84   /// Returns a reference to the result, with a reference category and const-
85   /// qualification equivalent to the reference category and const-qualification
86   /// of the receiver.
87   ///
88   /// If moved-from, throws NoState.
89   ///
90   /// If !isReady(), throws FutureNotReady.
91   ///
92   /// If an exception has been captured, throws that exception.
93   T& value() &;
94   T const& value() const&;
95   T&& value() &&;
96   T const&& value() const&&;
97
98   /// Returns an inactive Future which will call back on the other side of
99   /// executor (when it is activated).
100   ///
101   /// NB remember that Futures activate when they destruct. This is good,
102   /// it means that this will work:
103   ///
104   ///   f.via(e).then(a).then(b);
105   ///
106   /// a and b will execute in the same context (the far side of e), because
107   /// the Future (temporary variable) created by via(e) does not call back
108   /// until it destructs, which is after then(a) and then(b) have been wired
109   /// up.
110   ///
111   /// But this is still racy:
112   ///
113   ///   f = f.via(e).then(a);
114   ///   f.then(b);
115   // The ref-qualifier allows for `this` to be moved out so we
116   // don't get access-after-free situations in chaining.
117   // https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/
118   inline Future<T> via(
119       Executor* executor,
120       int8_t priority = Executor::MID_PRI) &&;
121
122   /** True when the result (or exception) is ready. */
123   bool isReady() const;
124
125   /// sugar for getTry().hasValue()
126   bool hasValue();
127
128   /// sugar for getTry().hasException()
129   bool hasException();
130
131   /** A reference to the Try of the value */
132   Try<T>& getTry();
133
134   /// If the promise has been fulfilled, return an Optional with the Try<T>.
135   /// Otherwise return an empty Optional.
136   /// Note that this moves the Try<T> out.
137   Optional<Try<T>> poll();
138
139   /// This is not the method you're looking for.
140   ///
141   /// This needs to be public because it's used by make* and when*, and it's
142   /// not worth listing all those and their fancy template signatures as
143   /// friends. But it's not for public consumption.
144   template <class F>
145   void setCallback_(F&& func);
146
147   bool isActive() {
148     return core_->isActive();
149   }
150
151   template <class E>
152   void raise(E&& exception) {
153     raise(make_exception_wrapper<typename std::remove_reference<E>::type>(
154         std::forward<E>(exception)));
155   }
156
157   /// Raise an interrupt. If the promise holder has an interrupt
158   /// handler it will be called and potentially stop asynchronous work from
159   /// being done. This is advisory only - a promise holder may not set an
160   /// interrupt handler, or may do anything including ignore. But, if you know
161   /// your future supports this the most likely result is stopping or
162   /// preventing the asynchronous operation (if in time), and the promise
163   /// holder setting an exception on the future. (That may happen
164   /// asynchronously, of course.)
165   void raise(exception_wrapper interrupt);
166
167   void cancel() {
168     raise(FutureCancellation());
169   }
170
171  protected:
172   friend class Promise<T>;
173   template <class>
174   friend class SemiFuture;
175   template <class>
176   friend class Future;
177
178   using corePtr = futures::detail::Core<T>*;
179
180   // shared core state object
181   corePtr core_;
182
183   explicit FutureBase(corePtr obj) : core_(obj) {}
184
185   explicit FutureBase(futures::detail::EmptyConstruct) noexcept;
186
187   void detach();
188
189   void throwIfInvalid() const;
190
191   template <class FutureType>
192   void assign(FutureType&) noexcept;
193
194   Executor* getExecutor() {
195     return core_->getExecutor();
196   }
197
198   void setExecutor(Executor* x, int8_t priority = Executor::MID_PRI) {
199     core_->setExecutor(x, priority);
200   }
201
202   // Variant: returns a value
203   // e.g. f.then([](Try<T> t){ return t.value(); });
204   template <typename F, typename R, bool isTry, typename... Args>
205   typename std::enable_if<!R::ReturnsFuture::value, typename R::Return>::type
206   thenImplementation(F&& func, futures::detail::argResult<isTry, F, Args...>);
207
208   // Variant: returns a Future
209   // e.g. f.then([](Try<T> t){ return makeFuture<T>(t); });
210   template <typename F, typename R, bool isTry, typename... Args>
211   typename std::enable_if<R::ReturnsFuture::value, typename R::Return>::type
212   thenImplementation(F&& func, futures::detail::argResult<isTry, F, Args...>);
213 };
214 } // namespace detail
215 } // namespace futures
216
217 template <class T>
218 class SemiFuture : private futures::detail::FutureBase<T> {
219  private:
220   using Base = futures::detail::FutureBase<T>;
221
222  public:
223   static SemiFuture<T> makeEmpty(); // equivalent to moved-from
224
225   // Export public interface of FutureBase
226   // FutureBase is inherited privately to avoid subclasses being cast to
227   // a FutureBase pointer
228   using typename Base::value_type;
229
230   /// Construct a Future from a value (perfect forwarding)
231   template <
232       class T2 = T,
233       typename = typename std::enable_if<
234           !isFuture<typename std::decay<T2>::type>::value>::type>
235   /* implicit */ SemiFuture(T2&& val) : Base(std::forward<T2>(val)) {}
236
237   template <class T2 = T>
238   /* implicit */ SemiFuture(
239       typename std::enable_if<std::is_same<Unit, T2>::value>::type* p = nullptr)
240       : Base(p) {}
241
242   template <
243       class... Args,
244       typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
245           type = 0>
246   explicit SemiFuture(in_place_t, Args&&... args)
247       : Base(in_place, std::forward<Args>(args)...) {}
248
249   SemiFuture(SemiFuture<T> const&) = delete;
250   // movable
251   SemiFuture(SemiFuture<T>&&) noexcept;
252   // safe move-constructabilty from Future
253   /* implicit */ SemiFuture(Future<T>&&) noexcept;
254
255   using Base::cancel;
256   using Base::getTry;
257   using Base::hasException;
258   using Base::hasValue;
259   using Base::isActive;
260   using Base::isReady;
261   using Base::poll;
262   using Base::raise;
263   using Base::setCallback_;
264   using Base::value;
265   using Base::via;
266
267   SemiFuture& operator=(SemiFuture const&) = delete;
268   SemiFuture& operator=(SemiFuture&&) noexcept;
269   SemiFuture& operator=(Future<T>&&) noexcept;
270
271   /// Block until the future is fulfilled. Returns the value (moved out), or
272   /// throws the exception. The future must not already have a callback.
273   T get() &&;
274
275   /// Block until the future is fulfilled, or until timed out. Returns the
276   /// value (moved out), or throws the exception (which might be a TimedOut
277   /// exception).
278   T get(Duration dur) &&;
279
280   /// Block until this Future is complete. Returns a reference to this Future.
281   SemiFuture<T>& wait() &;
282
283   /// Overload of wait() for rvalue Futures
284   SemiFuture<T>&& wait() &&;
285
286   /// Block until this Future is complete or until the given Duration passes.
287   /// Returns a reference to this Future
288   SemiFuture<T>& wait(Duration) &;
289
290   /// Overload of wait(Duration) for rvalue Futures
291   SemiFuture<T>&& wait(Duration) &&;
292
293  private:
294   template <class>
295   friend class futures::detail::FutureBase;
296
297   using typename Base::corePtr;
298
299   template <class T2>
300   friend SemiFuture<T2> makeSemiFuture(Try<T2>&&);
301
302   explicit SemiFuture(corePtr obj) : Base(obj) {}
303
304   explicit SemiFuture(futures::detail::EmptyConstruct) noexcept
305       : Base(futures::detail::EmptyConstruct{}) {}
306 };
307
308 template <class T>
309 class Future : private futures::detail::FutureBase<T> {
310  private:
311   using Base = futures::detail::FutureBase<T>;
312
313  public:
314   // Export public interface of FutureBase
315   // FutureBase is inherited privately to avoid subclasses being cast to
316   // a FutureBase pointer
317   using typename Base::value_type;
318
319   /// Construct a Future from a value (perfect forwarding)
320   template <
321       class T2 = T,
322       typename = typename std::enable_if<
323           !isFuture<typename std::decay<T2>::type>::value>::type>
324   /* implicit */ Future(T2&& val) : Base(std::forward<T2>(val)) {}
325
326   template <class T2 = T>
327   /* implicit */ Future(
328       typename std::enable_if<std::is_same<Unit, T2>::value>::type* p = nullptr)
329       : Base(p) {}
330
331   template <
332       class... Args,
333       typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
334           type = 0>
335   explicit Future(in_place_t, Args&&... args)
336       : Base(in_place, std::forward<Args>(args)...) {}
337
338   Future(Future<T> const&) = delete;
339   // movable
340   Future(Future<T>&&) noexcept;
341
342   // converting move
343   template <
344       class T2,
345       typename std::enable_if<
346           !std::is_same<T, typename std::decay<T2>::type>::value &&
347               std::is_constructible<T, T2&&>::value &&
348               std::is_convertible<T2&&, T>::value,
349           int>::type = 0>
350   /* implicit */ Future(Future<T2>&&);
351   template <
352       class T2,
353       typename std::enable_if<
354           !std::is_same<T, typename std::decay<T2>::type>::value &&
355               std::is_constructible<T, T2&&>::value &&
356               !std::is_convertible<T2&&, T>::value,
357           int>::type = 0>
358   explicit Future(Future<T2>&&);
359   template <
360       class T2,
361       typename std::enable_if<
362           !std::is_same<T, typename std::decay<T2>::type>::value &&
363               std::is_constructible<T, T2&&>::value,
364           int>::type = 0>
365   Future& operator=(Future<T2>&&);
366
367   using Base::cancel;
368   using Base::getTry;
369   using Base::hasException;
370   using Base::hasValue;
371   using Base::isActive;
372   using Base::isReady;
373   using Base::poll;
374   using Base::raise;
375   using Base::setCallback_;
376   using Base::value;
377   using Base::via;
378
379   static Future<T> makeEmpty(); // equivalent to moved-from
380
381   // not copyable
382   Future& operator=(Future const&) = delete;
383
384   // movable
385   Future& operator=(Future&&) noexcept;
386
387   /// Call e->drive() repeatedly until the future is fulfilled. Examples
388   /// of DrivableExecutor include EventBase and ManualExecutor. Returns a
389   /// reference to the Try of the value.
390   Try<T>& getTryVia(DrivableExecutor* e);
391
392   /// Call e->drive() repeatedly until the future is fulfilled. Examples
393   /// of DrivableExecutor include EventBase and ManualExecutor. Returns the
394   /// value (moved out), or throws the exception.
395   T getVia(DrivableExecutor* e);
396
397   /// Unwraps the case of a Future<Future<T>> instance, and returns a simple
398   /// Future<T> instance.
399   template <class F = T>
400   typename std::
401       enable_if<isFuture<F>::value, Future<typename isFuture<T>::Inner>>::type
402       unwrap();
403
404   /// This variant creates a new future, where the ref-qualifier && version
405   /// moves `this` out. This one is less efficient but avoids confusing users
406   /// when "return f.via(x);" fails.
407   inline Future<T> via(
408       Executor* executor,
409       int8_t priority = Executor::MID_PRI) &;
410
411   /** When this Future has completed, execute func which is a function that
412     takes one of:
413       (const) Try<T>&&
414       (const) Try<T>&
415       (const) Try<T>
416       (const) T&&
417       (const) T&
418       (const) T
419       (void)
420
421     Func shall return either another Future or a value.
422
423     A Future for the return type of func is returned.
424
425     Future<string> f2 = f1.then([](Try<T>&&) { return string("foo"); });
426
427     The Future given to the functor is ready, and the functor may call
428     value(), which may rethrow if this has captured an exception. If func
429     throws, the exception will be captured in the Future that is returned.
430     */
431   template <typename F, typename R = futures::detail::callableResult<T, F>>
432   typename R::Return then(F&& func) {
433     return this->template thenImplementation<F, R>(
434         std::forward<F>(func), typename R::Arg());
435   }
436
437   /// Variant where func is an member function
438   ///
439   ///   struct Worker { R doWork(Try<T>); }
440   ///
441   ///   Worker *w;
442   ///   Future<R> f2 = f1.then(&Worker::doWork, w);
443   ///
444   /// This is just sugar for
445   ///
446   ///   f1.then(std::bind(&Worker::doWork, w));
447   template <typename R, typename Caller, typename... Args>
448   Future<typename isFuture<R>::Inner> then(
449       R (Caller::*func)(Args...),
450       Caller* instance);
451
452   /// Execute the callback via the given Executor. The executor doesn't stick.
453   ///
454   /// Contrast
455   ///
456   ///   f.via(x).then(b).then(c)
457   ///
458   /// with
459   ///
460   ///   f.then(x, b).then(c)
461   ///
462   /// In the former both b and c execute via x. In the latter, only b executes
463   /// via x, and c executes via the same executor (if any) that f had.
464   template <class Executor, class Arg, class... Args>
465   auto then(Executor* x, Arg&& arg, Args&&... args) {
466     auto oldX = this->getExecutor();
467     this->setExecutor(x);
468     return this->then(std::forward<Arg>(arg), std::forward<Args>(args)...)
469         .via(oldX);
470   }
471
472   /// Convenience method for ignoring the value and creating a Future<Unit>.
473   /// Exceptions still propagate.
474   /// This function is identical to .unit().
475   Future<Unit> then();
476
477   /// Convenience method for ignoring the value and creating a Future<Unit>.
478   /// Exceptions still propagate.
479   /// This function is identical to parameterless .then().
480   Future<Unit> unit() {
481     return then();
482   }
483
484   /// Set an error callback for this Future. The callback should take a single
485   /// argument of the type that you want to catch, and should return a value of
486   /// the same type as this Future, or a Future of that type (see overload
487   /// below). For instance,
488   ///
489   /// makeFuture()
490   ///   .then([] {
491   ///     throw std::runtime_error("oh no!");
492   ///     return 42;
493   ///   })
494   ///   .onError([] (std::runtime_error& e) {
495   ///     LOG(INFO) << "std::runtime_error: " << e.what();
496   ///     return -1; // or makeFuture<int>(-1)
497   ///   });
498   template <class F>
499   typename std::enable_if<
500       !futures::detail::callableWith<F, exception_wrapper>::value &&
501           !futures::detail::callableWith<F, exception_wrapper&>::value &&
502           !futures::detail::Extract<F>::ReturnsFuture::value,
503       Future<T>>::type
504   onError(F&& func);
505
506   /// Overload of onError where the error callback returns a Future<T>
507   template <class F>
508   typename std::enable_if<
509       !futures::detail::callableWith<F, exception_wrapper>::value &&
510           !futures::detail::callableWith<F, exception_wrapper&>::value &&
511           futures::detail::Extract<F>::ReturnsFuture::value,
512       Future<T>>::type
513   onError(F&& func);
514
515   /// Overload of onError that takes exception_wrapper and returns Future<T>
516   template <class F>
517   typename std::enable_if<
518       futures::detail::callableWith<F, exception_wrapper>::value &&
519           futures::detail::Extract<F>::ReturnsFuture::value,
520       Future<T>>::type
521   onError(F&& func);
522
523   /// Overload of onError that takes exception_wrapper and returns T
524   template <class F>
525   typename std::enable_if<
526       futures::detail::callableWith<F, exception_wrapper>::value &&
527           !futures::detail::Extract<F>::ReturnsFuture::value,
528       Future<T>>::type
529   onError(F&& func);
530
531   /// func is like std::function<void()> and is executed unconditionally, and
532   /// the value/exception is passed through to the resulting Future.
533   /// func shouldn't throw, but if it does it will be captured and propagated,
534   /// and discard any value/exception that this Future has obtained.
535   template <class F>
536   Future<T> ensure(F&& func);
537
538   /// Like onError, but for timeouts. example:
539   ///
540   ///   Future<int> f = makeFuture<int>(42)
541   ///     .delayed(long_time)
542   ///     .onTimeout(short_time,
543   ///       []() -> int{ return -1; });
544   ///
545   /// or perhaps
546   ///
547   ///   Future<int> f = makeFuture<int>(42)
548   ///     .delayed(long_time)
549   ///     .onTimeout(short_time,
550   ///       []() { return makeFuture<int>(some_exception); });
551   template <class F>
552   Future<T> onTimeout(Duration, F&& func, Timekeeper* = nullptr);
553
554   /// A Future's callback is executed when all three of these conditions have
555   /// become true: it has a value (set by the Promise), it has a callback (set
556   /// by then), and it is active (active by default).
557   ///
558   /// Inactive Futures will activate upon destruction.
559   FOLLY_DEPRECATED("do not use") Future<T>& activate() & {
560     this->core_->activate();
561     return *this;
562   }
563   FOLLY_DEPRECATED("do not use") Future<T>& deactivate() & {
564     this->core_->deactivate();
565     return *this;
566   }
567   FOLLY_DEPRECATED("do not use") Future<T> activate() && {
568     this->core_->activate();
569     return std::move(*this);
570   }
571   FOLLY_DEPRECATED("do not use") Future<T> deactivate() && {
572     this->core_->deactivate();
573     return std::move(*this);
574   }
575
576   /// Throw TimedOut if this Future does not complete within the given
577   /// duration from now. The optional Timeekeeper is as with futures::sleep().
578   Future<T> within(Duration, Timekeeper* = nullptr);
579
580   /// Throw the given exception if this Future does not complete within the
581   /// given duration from now. The optional Timeekeeper is as with
582   /// futures::sleep().
583   template <class E>
584   Future<T> within(Duration, E exception, Timekeeper* = nullptr);
585
586   /// Delay the completion of this Future for at least this duration from
587   /// now. The optional Timekeeper is as with futures::sleep().
588   Future<T> delayed(Duration, Timekeeper* = nullptr);
589
590   /// Block until the future is fulfilled. Returns the value (moved out), or
591   /// throws the exception. The future must not already have a callback.
592   T get();
593
594   /// Block until the future is fulfilled, or until timed out. Returns the
595   /// value (moved out), or throws the exception (which might be a TimedOut
596   /// exception).
597   T get(Duration dur);
598
599   /// Block until this Future is complete. Returns a reference to this Future.
600   Future<T>& wait() &;
601
602   /// Overload of wait() for rvalue Futures
603   Future<T>&& wait() &&;
604
605   /// Block until this Future is complete or until the given Duration passes.
606   /// Returns a reference to this Future
607   Future<T>& wait(Duration) &;
608
609   /// Overload of wait(Duration) for rvalue Futures
610   Future<T>&& wait(Duration) &&;
611
612   /// Call e->drive() repeatedly until the future is fulfilled. Examples
613   /// of DrivableExecutor include EventBase and ManualExecutor. Returns a
614   /// reference to this Future so that you can chain calls if desired.
615   /// value (moved out), or throws the exception.
616   Future<T>& waitVia(DrivableExecutor* e) &;
617
618   /// Overload of waitVia() for rvalue Futures
619   Future<T>&& waitVia(DrivableExecutor* e) &&;
620
621   /// If the value in this Future is equal to the given Future, when they have
622   /// both completed, the value of the resulting Future<bool> will be true. It
623   /// will be false otherwise (including when one or both Futures have an
624   /// exception)
625   Future<bool> willEqual(Future<T>&);
626
627   /// predicate behaves like std::function<bool(T const&)>
628   /// If the predicate does not obtain with the value, the result
629   /// is a folly::PredicateDoesNotObtain exception
630   template <class F>
631   Future<T> filter(F&& predicate);
632
633   /// Like reduce, but works on a Future<std::vector<T / Try<T>>>, for example
634   /// the result of collect or collectAll
635   template <class I, class F>
636   Future<I> reduce(I&& initial, F&& func);
637
638   /// Create a Future chain from a sequence of callbacks. i.e.
639   ///
640   ///   f.then(a).then(b).then(c)
641   ///
642   /// where f is a Future<A> and the result of the chain is a Future<D>
643   /// becomes
644   ///
645   ///   f.thenMulti(a, b, c);
646   template <class Callback, class... Callbacks>
647   auto thenMulti(Callback&& fn, Callbacks&&... fns) {
648     // thenMulti with two callbacks is just then(a).thenMulti(b, ...)
649     return then(std::forward<Callback>(fn))
650         .thenMulti(std::forward<Callbacks>(fns)...);
651   }
652
653   template <class Callback>
654   auto thenMulti(Callback&& fn) {
655     // thenMulti with one callback is just a then
656     return then(std::forward<Callback>(fn));
657   }
658
659   /// Create a Future chain from a sequence of callbacks. i.e.
660   ///
661   ///   f.via(executor).then(a).then(b).then(c).via(oldExecutor)
662   ///
663   /// where f is a Future<A> and the result of the chain is a Future<D>
664   /// becomes
665   ///
666   ///   f.thenMultiWithExecutor(executor, a, b, c);
667   template <class Callback, class... Callbacks>
668   auto thenMultiWithExecutor(Executor* x, Callback&& fn, Callbacks&&... fns) {
669     // thenMultiExecutor with two callbacks is
670     // via(x).then(a).thenMulti(b, ...).via(oldX)
671     auto oldX = this->getExecutor();
672     this->setExecutor(x);
673     return then(std::forward<Callback>(fn))
674         .thenMulti(std::forward<Callbacks>(fns)...)
675         .via(oldX);
676   }
677
678   template <class Callback>
679   auto thenMultiWithExecutor(Executor* x, Callback&& fn) {
680     // thenMulti with one callback is just a then with an executor
681     return then(x, std::forward<Callback>(fn));
682   }
683
684   // Convert this Future to a SemiFuture to safely export from a library
685   // without exposing a continuation interface
686   SemiFuture<T> semi() {
687     return SemiFuture<T>{std::move(*this)};
688   }
689
690  protected:
691   friend class Promise<T>;
692   template <class>
693   friend class futures::detail::FutureBase;
694   template <class>
695   friend class Future;
696
697   using typename Base::corePtr;
698
699   explicit Future(corePtr obj) : Base(obj) {}
700
701   explicit Future(futures::detail::EmptyConstruct) noexcept
702       : Base(futures::detail::EmptyConstruct{}) {}
703
704   template <class T2>
705   friend Future<T2> makeFuture(Try<T2>&&);
706
707   /// Repeat the given future (i.e., the computation it contains)
708   /// n times.
709   ///
710   /// thunk behaves like std::function<Future<T2>(void)>
711   template <class F>
712   friend Future<Unit> times(int n, F&& thunk);
713
714   /// Carry out the computation contained in the given future if
715   /// the predicate holds.
716   ///
717   /// thunk behaves like std::function<Future<T2>(void)>
718   template <class F>
719   friend Future<Unit> when(bool p, F&& thunk);
720
721   /// Carry out the computation contained in the given future if
722   /// while the predicate continues to hold.
723   ///
724   /// thunk behaves like std::function<Future<T2>(void)>
725   ///
726   /// predicate behaves like std::function<bool(void)>
727   template <class P, class F>
728   friend Future<Unit> whileDo(P&& predicate, F&& thunk);
729 };
730
731 } // namespace folly
732
733 #include <folly/futures/Future-inl.h>