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