683c3cbbda985aeb1e949f51974be026fa2e53ce
[folly.git] / folly / futures / Future.h
1 /*
2  * Copyright 2015 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/MoveWrapper.h>
28 #include <folly/futures/Deprecated.h>
29 #include <folly/futures/DrivableExecutor.h>
30 #include <folly/futures/Promise.h>
31 #include <folly/futures/Try.h>
32 #include <folly/futures/FutureException.h>
33 #include <folly/futures/detail/Types.h>
34
35 namespace folly {
36
37 template <class> struct Promise;
38
39 template <typename T>
40 struct isFuture : std::false_type {
41   typedef T Inner;
42 };
43
44 template <typename T>
45 struct isFuture<Future<T>> : std::true_type {
46   typedef T Inner;
47 };
48
49 template <typename T>
50 struct isTry : std::false_type {};
51
52 template <typename T>
53 struct isTry<Try<T>> : std::true_type {};
54
55 namespace detail {
56
57 template <class> struct Core;
58 template <class...> struct VariadicContext;
59 template <class> struct CollectContext;
60
61 template<typename F, typename... Args>
62 using resultOf = decltype(std::declval<F>()(std::declval<Args>()...));
63
64 template <typename...>
65 struct ArgType;
66
67 template <typename Arg, typename... Args>
68 struct ArgType<Arg, Args...> {
69   typedef Arg FirstArg;
70 };
71
72 template <>
73 struct ArgType<> {
74   typedef void FirstArg;
75 };
76
77 template <bool isTry, typename F, typename... Args>
78 struct argResult {
79   typedef resultOf<F, Args...> Result;
80 };
81
82 template<typename F, typename... Args>
83 struct callableWith {
84     template<typename T,
85              typename = detail::resultOf<T, Args...>>
86     static constexpr std::true_type
87     check(std::nullptr_t) { return std::true_type{}; };
88
89     template<typename>
90     static constexpr std::false_type
91     check(...) { return std::false_type{}; };
92
93     typedef decltype(check<F>(nullptr)) type;
94     static constexpr bool value = type::value;
95 };
96
97 template<typename T, typename F>
98 struct callableResult {
99   typedef typename std::conditional<
100     callableWith<F>::value,
101     detail::argResult<false, F>,
102     typename std::conditional<
103       callableWith<F, T&&>::value,
104       detail::argResult<false, F, T&&>,
105       typename std::conditional<
106         callableWith<F, T&>::value,
107         detail::argResult<false, F, T&>,
108         typename std::conditional<
109           callableWith<F, Try<T>&&>::value,
110           detail::argResult<true, F, Try<T>&&>,
111           detail::argResult<true, F, Try<T>&>>::type>::type>::type>::type Arg;
112   typedef isFuture<typename Arg::Result> ReturnsFuture;
113   typedef Future<typename ReturnsFuture::Inner> Return;
114 };
115
116 template<typename F>
117 struct callableResult<void, F> {
118   typedef typename std::conditional<
119     callableWith<F>::value,
120     detail::argResult<false, F>,
121     typename std::conditional<
122       callableWith<F, Try<void>&&>::value,
123       detail::argResult<true, F, Try<void>&&>,
124       detail::argResult<true, F, Try<void>&>>::type>::type Arg;
125   typedef isFuture<typename Arg::Result> ReturnsFuture;
126   typedef Future<typename ReturnsFuture::Inner> Return;
127 };
128
129 template <typename L>
130 struct Extract : Extract<decltype(&L::operator())> { };
131
132 template <typename Class, typename R, typename... Args>
133 struct Extract<R(Class::*)(Args...) const> {
134   typedef isFuture<R> ReturnsFuture;
135   typedef Future<typename ReturnsFuture::Inner> Return;
136   typedef typename ReturnsFuture::Inner RawReturn;
137   typedef typename ArgType<Args...>::FirstArg FirstArg;
138 };
139
140 template <typename Class, typename R, typename... Args>
141 struct Extract<R(Class::*)(Args...)> {
142   typedef isFuture<R> ReturnsFuture;
143   typedef Future<typename ReturnsFuture::Inner> Return;
144   typedef typename ReturnsFuture::Inner RawReturn;
145   typedef typename ArgType<Args...>::FirstArg FirstArg;
146 };
147
148 } // detail
149
150 struct Timekeeper;
151
152 /// This namespace is for utility functions that would usually be static
153 /// members of Future, except they don't make sense there because they don't
154 /// depend on the template type (rather, on the type of their arguments in
155 /// some cases). This is the least-bad naming scheme we could think of. Some
156 /// of the functions herein have really-likely-to-collide names, like "map"
157 /// and "sleep".
158 namespace futures {
159   /// Returns a Future that will complete after the specified duration. The
160   /// Duration typedef of a `std::chrono` duration type indicates the
161   /// resolution you can expect to be meaningful (milliseconds at the time of
162   /// writing). Normally you wouldn't need to specify a Timekeeper, we will
163   /// use the global futures timekeeper (we run a thread whose job it is to
164   /// keep time for futures timeouts) but we provide the option for power
165   /// users.
166   ///
167   /// The Timekeeper thread will be lazily created the first time it is
168   /// needed. If your program never uses any timeouts or other time-based
169   /// Futures you will pay no Timekeeper thread overhead.
170   Future<void> sleep(Duration, Timekeeper* = nullptr);
171
172   /// Create a Future chain from a sequence of callbacks. i.e.
173   ///
174   ///   f.then(a).then(b).then(c);
175   ///
176   /// where f is a Future<A> and the result of the chain is a Future<Z>
177   /// becomes
178   ///
179   ///   f.then(chain<A,Z>(a, b, c));
180   // If anyone figures how to get chain to deduce A and Z, I'll buy you a drink.
181   template <class A, class Z, class... Callbacks>
182   std::function<Future<Z>(Try<A>)>
183   chain(Callbacks... fns);
184
185   /**
186    * Set func as the callback for each input Future and return a vector of
187    * Futures containing the results in the input order.
188    */
189   template <class It, class F,
190             class ItT = typename std::iterator_traits<It>::value_type,
191             class Result = decltype(std::declval<ItT>().then(std::declval<F>()))>
192   std::vector<Future<Result>> map(It first, It last, F func);
193
194   // Sugar for the most common case
195   template <class Collection, class F>
196   auto map(Collection&& c, F&& func)
197       -> decltype(map(c.begin(), c.end(), func)) {
198     return map(c.begin(), c.end(), std::forward<F>(func));
199   }
200
201 }
202
203 template <class T>
204 class Future {
205  public:
206   typedef T value_type;
207
208   // not copyable
209   Future(Future const&) = delete;
210   Future& operator=(Future const&) = delete;
211
212   // movable
213   Future(Future&&) noexcept;
214   Future& operator=(Future&&) noexcept;
215
216   /// Construct a Future from a value (perfect forwarding)
217   /* implicit */
218   template <class T2 = T> Future(T2&& val);
219
220   template <class F = T,
221             typename std::enable_if<std::is_void<F>::value, int>::type = 0>
222   Future();
223
224   ~Future();
225
226   /** Return the reference to result. Should not be called if !isReady().
227     Will rethrow the exception if an exception has been
228     captured.
229     */
230   typename std::add_lvalue_reference<T>::type
231   value();
232   typename std::add_lvalue_reference<const T>::type
233   value() const;
234
235   /// Returns an inactive Future which will call back on the other side of
236   /// executor (when it is activated).
237   ///
238   /// NB remember that Futures activate when they destruct. This is good,
239   /// it means that this will work:
240   ///
241   ///   f.via(e).then(a).then(b);
242   ///
243   /// a and b will execute in the same context (the far side of e), because
244   /// the Future (temporary variable) created by via(e) does not call back
245   /// until it destructs, which is after then(a) and then(b) have been wired
246   /// up.
247   ///
248   /// But this is still racy:
249   ///
250   ///   f = f.via(e).then(a);
251   ///   f.then(b);
252   // The ref-qualifier allows for `this` to be moved out so we
253   // don't get access-after-free situations in chaining.
254   // https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/
255   template <typename Executor>
256   Future<T> via(Executor* executor) &&;
257
258   /// This variant creates a new future, where the ref-qualifier && version
259   /// moves `this` out. This one is less efficient but avoids confusing users
260   /// when "return f.via(x);" fails.
261   template <typename Executor>
262   Future<T> via(Executor* executor) &;
263
264   /** True when the result (or exception) is ready. */
265   bool isReady() const;
266
267   /** A reference to the Try of the value */
268   Try<T>& getTry();
269
270   /// If the promise has been fulfilled, return an Optional with the Try<T>.
271   /// Otherwise return an empty Optional.
272   /// Note that this moves the Try<T> out.
273   Optional<Try<T>> poll();
274
275   /// Block until the future is fulfilled. Returns the value (moved out), or
276   /// throws the exception. The future must not already have a callback.
277   T get();
278
279   /// Block until the future is fulfilled, or until timed out. Returns the
280   /// value (moved out), or throws the exception (which might be a TimedOut
281   /// exception).
282   T get(Duration dur);
283
284   /// Call e->drive() repeatedly until the future is fulfilled. Examples
285   /// of DrivableExecutor include EventBase and ManualExecutor. Returns the
286   /// value (moved out), or throws the exception.
287   T getVia(DrivableExecutor* e);
288
289   /// Unwraps the case of a Future<Future<T>> instance, and returns a simple
290   /// Future<T> instance.
291   template <class F = T>
292   typename std::enable_if<isFuture<F>::value,
293                           Future<typename isFuture<T>::Inner>>::type
294   unwrap();
295
296   /** When this Future has completed, execute func which is a function that
297     takes one of:
298       (const) Try<T>&&
299       (const) Try<T>&
300       (const) Try<T>
301       (const) T&&
302       (const) T&
303       (const) T
304       (void)
305
306     Func shall return either another Future or a value.
307
308     A Future for the return type of func is returned.
309
310     Future<string> f2 = f1.then([](Try<T>&&) { return string("foo"); });
311
312     The Future given to the functor is ready, and the functor may call
313     value(), which may rethrow if this has captured an exception. If func
314     throws, the exception will be captured in the Future that is returned.
315     */
316   /* TODO n3428 and other async frameworks have something like then(scheduler,
317      Future), we might want to support a similar API which could be
318      implemented a little more efficiently than
319      f.via(executor).then(callback) */
320   template <typename F, typename R = detail::callableResult<T, F>>
321   typename R::Return then(F func) {
322     typedef typename R::Arg Arguments;
323     return thenImplementation<F, R>(std::move(func), Arguments());
324   }
325
326   /// Variant where func is an member function
327   ///
328   ///   struct Worker { R doWork(Try<T>); }
329   ///
330   ///   Worker *w;
331   ///   Future<R> f2 = f1.then(&Worker::doWork, w);
332   ///
333   /// This is just sugar for
334   ///
335   ///   f1.then(std::bind(&Worker::doWork, w));
336   template <typename R, typename Caller, typename... Args>
337   Future<typename isFuture<R>::Inner>
338   then(R(Caller::*func)(Args...), Caller *instance);
339
340 // TODO(6838553)
341 #ifndef __clang__
342   /// Execute the callback via the given Executor. The executor doesn't stick.
343   ///
344   /// Contrast
345   ///
346   ///   f.via(x).then(b).then(c)
347   ///
348   /// with
349   ///
350   ///   f.then(x, b).then(c)
351   ///
352   /// In the former both b and c execute via x. In the latter, only b executes
353   /// via x, and c executes via the same executor (if any) that f had.
354   template <class... Args>
355   auto then(Executor* x, Args&&... args)
356     -> decltype(this->then(std::forward<Args>(args)...));
357 #endif
358
359   /// Convenience method for ignoring the value and creating a Future<void>.
360   /// Exceptions still propagate.
361   Future<void> then();
362
363   /// Set an error callback for this Future. The callback should take a single
364   /// argument of the type that you want to catch, and should return a value of
365   /// the same type as this Future, or a Future of that type (see overload
366   /// below). For instance,
367   ///
368   /// makeFuture()
369   ///   .then([] {
370   ///     throw std::runtime_error("oh no!");
371   ///     return 42;
372   ///   })
373   ///   .onError([] (std::runtime_error& e) {
374   ///     LOG(INFO) << "std::runtime_error: " << e.what();
375   ///     return -1; // or makeFuture<int>(-1)
376   ///   });
377   template <class F>
378   typename std::enable_if<
379     !detail::callableWith<F, exception_wrapper>::value &&
380     !detail::Extract<F>::ReturnsFuture::value,
381     Future<T>>::type
382   onError(F&& func);
383
384   /// Overload of onError where the error callback returns a Future<T>
385   template <class F>
386   typename std::enable_if<
387     !detail::callableWith<F, exception_wrapper>::value &&
388     detail::Extract<F>::ReturnsFuture::value,
389     Future<T>>::type
390   onError(F&& func);
391
392   /// Overload of onError that takes exception_wrapper and returns Future<T>
393   template <class F>
394   typename std::enable_if<
395     detail::callableWith<F, exception_wrapper>::value &&
396     detail::Extract<F>::ReturnsFuture::value,
397     Future<T>>::type
398   onError(F&& func);
399
400   /// Overload of onError that takes exception_wrapper and returns T
401   template <class F>
402   typename std::enable_if<
403     detail::callableWith<F, exception_wrapper>::value &&
404     !detail::Extract<F>::ReturnsFuture::value,
405     Future<T>>::type
406   onError(F&& func);
407
408   /// func is like std::function<void()> and is executed unconditionally, and
409   /// the value/exception is passed through to the resulting Future.
410   /// func shouldn't throw, but if it does it will be captured and propagated,
411   /// and discard any value/exception that this Future has obtained.
412   template <class F>
413   Future<T> ensure(F func);
414
415   /// Like onError, but for timeouts. example:
416   ///
417   ///   Future<int> f = makeFuture<int>(42)
418   ///     .delayed(long_time)
419   ///     .onTimeout(short_time,
420   ///       []() -> int{ return -1; });
421   ///
422   /// or perhaps
423   ///
424   ///   Future<int> f = makeFuture<int>(42)
425   ///     .delayed(long_time)
426   ///     .onTimeout(short_time,
427   ///       []() { return makeFuture<int>(some_exception); });
428   template <class F>
429   Future<T> onTimeout(Duration, F&& func, Timekeeper* = nullptr);
430
431   /// This is not the method you're looking for.
432   ///
433   /// This needs to be public because it's used by make* and when*, and it's
434   /// not worth listing all those and their fancy template signatures as
435   /// friends. But it's not for public consumption.
436   template <class F>
437   void setCallback_(F&& func);
438
439   /// A Future's callback is executed when all three of these conditions have
440   /// become true: it has a value (set by the Promise), it has a callback (set
441   /// by then), and it is active (active by default).
442   ///
443   /// Inactive Futures will activate upon destruction.
444   Future<T>& activate() & {
445     core_->activate();
446     return *this;
447   }
448   Future<T>& deactivate() & {
449     core_->deactivate();
450     return *this;
451   }
452   Future<T> activate() && {
453     core_->activate();
454     return std::move(*this);
455   }
456   Future<T> deactivate() && {
457     core_->deactivate();
458     return std::move(*this);
459   }
460
461   bool isActive() {
462     return core_->isActive();
463   }
464
465   template <class E>
466   void raise(E&& exception) {
467     raise(make_exception_wrapper<typename std::remove_reference<E>::type>(
468         std::move(exception)));
469   }
470
471   /// Raise an interrupt. If the promise holder has an interrupt
472   /// handler it will be called and potentially stop asynchronous work from
473   /// being done. This is advisory only - a promise holder may not set an
474   /// interrupt handler, or may do anything including ignore. But, if you know
475   /// your future supports this the most likely result is stopping or
476   /// preventing the asynchronous operation (if in time), and the promise
477   /// holder setting an exception on the future. (That may happen
478   /// asynchronously, of course.)
479   void raise(exception_wrapper interrupt);
480
481   void cancel() {
482     raise(FutureCancellation());
483   }
484
485   /// Throw TimedOut if this Future does not complete within the given
486   /// duration from now. The optional Timeekeeper is as with futures::sleep().
487   Future<T> within(Duration, Timekeeper* = nullptr);
488
489   /// Throw the given exception if this Future does not complete within the
490   /// given duration from now. The optional Timeekeeper is as with
491   /// futures::sleep().
492   template <class E>
493   Future<T> within(Duration, E exception, Timekeeper* = nullptr);
494
495   /// Delay the completion of this Future for at least this duration from
496   /// now. The optional Timekeeper is as with futures::sleep().
497   Future<T> delayed(Duration, Timekeeper* = nullptr);
498
499   /// Block until this Future is complete. Returns a reference to this Future.
500   Future<T>& wait() &;
501
502   /// Overload of wait() for rvalue Futures
503   Future<T>&& wait() &&;
504
505   /// Block until this Future is complete or until the given Duration passes.
506   /// Returns a reference to this Future
507   Future<T>& wait(Duration) &;
508
509   /// Overload of wait(Duration) for rvalue Futures
510   Future<T>&& wait(Duration) &&;
511
512   /// Call e->drive() repeatedly until the future is fulfilled. Examples
513   /// of DrivableExecutor include EventBase and ManualExecutor. Returns a
514   /// reference to this Future so that you can chain calls if desired.
515   /// value (moved out), or throws the exception.
516   Future<T>& waitVia(DrivableExecutor* e) &;
517
518   /// Overload of waitVia() for rvalue Futures
519   Future<T>&& waitVia(DrivableExecutor* e) &&;
520
521   /// If the value in this Future is equal to the given Future, when they have
522   /// both completed, the value of the resulting Future<bool> will be true. It
523   /// will be false otherwise (including when one or both Futures have an
524   /// exception)
525   Future<bool> willEqual(Future<T>&);
526
527   /// predicate behaves like std::function<bool(T const&)>
528   /// If the predicate does not obtain with the value, the result
529   /// is a folly::PredicateDoesNotObtain exception
530   template <class F>
531   Future<T> filter(F predicate);
532
533  protected:
534   typedef detail::Core<T>* corePtr;
535
536   // shared core state object
537   corePtr core_;
538
539   explicit
540   Future(corePtr obj) : core_(obj) {}
541
542   void detach();
543
544   void throwIfInvalid() const;
545
546   friend class Promise<T>;
547   template <class> friend class Future;
548
549   // Variant: returns a value
550   // e.g. f.then([](Try<T> t){ return t.value(); });
551   template <typename F, typename R, bool isTry, typename... Args>
552   typename std::enable_if<!R::ReturnsFuture::value, typename R::Return>::type
553   thenImplementation(F func, detail::argResult<isTry, F, Args...>);
554
555   // Variant: returns a Future
556   // e.g. f.then([](Try<T> t){ return makeFuture<T>(t); });
557   template <typename F, typename R, bool isTry, typename... Args>
558   typename std::enable_if<R::ReturnsFuture::value, typename R::Return>::type
559   thenImplementation(F func, detail::argResult<isTry, F, Args...>);
560
561   Executor* getExecutor() { return core_->getExecutor(); }
562   void setExecutor(Executor* x) { core_->setExecutor(x); }
563 };
564
565 /**
566   Make a completed Future by moving in a value. e.g.
567
568     string foo = "foo";
569     auto f = makeFuture(std::move(foo));
570
571   or
572
573     auto f = makeFuture<string>("foo");
574 */
575 template <class T>
576 Future<typename std::decay<T>::type> makeFuture(T&& t);
577
578 /** Make a completed void Future. */
579 Future<void> makeFuture();
580
581 /** Make a completed Future by executing a function. If the function throws
582   we capture the exception, otherwise we capture the result. */
583 template <class F>
584 auto makeFutureWith(
585   F&& func,
586   typename std::enable_if<
587     !std::is_reference<F>::value, bool>::type sdf = false)
588   -> Future<decltype(func())>;
589
590 template <class F>
591 auto makeFutureWith(
592   F const& func)
593   -> Future<decltype(func())>;
594
595 /// Make a failed Future from an exception_ptr.
596 /// Because the Future's type cannot be inferred you have to specify it, e.g.
597 ///
598 ///   auto f = makeFuture<string>(std::current_exception());
599 template <class T>
600 Future<T> makeFuture(std::exception_ptr const& e) DEPRECATED;
601
602 /// Make a failed Future from an exception_wrapper.
603 template <class T>
604 Future<T> makeFuture(exception_wrapper ew);
605
606 /** Make a Future from an exception type E that can be passed to
607   std::make_exception_ptr(). */
608 template <class T, class E>
609 typename std::enable_if<std::is_base_of<std::exception, E>::value,
610                         Future<T>>::type
611 makeFuture(E const& e);
612
613 /** Make a Future out of a Try */
614 template <class T>
615 Future<T> makeFuture(Try<T>&& t);
616
617 /*
618  * Return a new Future that will call back on the given Executor.
619  * This is just syntactic sugar for makeFuture().via(executor)
620  *
621  * @param executor the Executor to call back on
622  *
623  * @returns a void Future that will call back on the given executor
624  */
625 template <typename Executor>
626 Future<void> via(Executor* executor);
627
628 /** When all the input Futures complete, the returned Future will complete.
629   Errors do not cause early termination; this Future will always succeed
630   after all its Futures have finished (whether successfully or with an
631   error).
632
633   The Futures are moved in, so your copies are invalid. If you need to
634   chain further from these Futures, use the variant with an output iterator.
635
636   This function is thread-safe for Futures running on different threads. But
637   if you are doing anything non-trivial after, you will probably want to
638   follow with `via(executor)` because it will complete in whichever thread the
639   last Future completes in.
640
641   The return type for Future<T> input is a Future<std::vector<Try<T>>>
642   */
643 template <class InputIterator>
644 Future<std::vector<Try<
645   typename std::iterator_traits<InputIterator>::value_type::value_type>>>
646 collectAll(InputIterator first, InputIterator last);
647
648 // Sugar for the most common case
649 template <class Collection>
650 auto collectAll(Collection&& c) -> decltype(collectAll(c.begin(), c.end())) {
651   return collectAll(c.begin(), c.end());
652 }
653
654 /// This version takes a varying number of Futures instead of an iterator.
655 /// The return type for (Future<T1>, Future<T2>, ...) input
656 /// is a Future<std::tuple<Try<T1>, Try<T2>, ...>>.
657 /// The Futures are moved in, so your copies are invalid.
658 template <typename... Fs>
659 typename detail::VariadicContext<
660   typename std::decay<Fs>::type::value_type...>::type
661 collectAll(Fs&&... fs);
662
663 /// Like collectAll, but will short circuit on the first exception. Thus, the
664 /// type of the returned Future is std::vector<T> instead of
665 /// std::vector<Try<T>>
666 template <class InputIterator>
667 Future<typename detail::CollectContext<
668   typename std::iterator_traits<InputIterator>::value_type::value_type
669 >::result_type>
670 collect(InputIterator first, InputIterator last);
671
672 // Sugar for the most common case
673 template <class Collection>
674 auto collect(Collection&& c) -> decltype(collect(c.begin(), c.end())) {
675   return collect(c.begin(), c.end());
676 }
677
678 /** The result is a pair of the index of the first Future to complete and
679   the Try. If multiple Futures complete at the same time (or are already
680   complete when passed in), the "winner" is chosen non-deterministically.
681
682   This function is thread-safe for Futures running on different threads.
683   */
684 template <class InputIterator>
685 Future<std::pair<
686   size_t,
687   Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
688 collectAny(InputIterator first, InputIterator last);
689
690 // Sugar for the most common case
691 template <class Collection>
692 auto collectAny(Collection&& c) -> decltype(collectAny(c.begin(), c.end())) {
693   return collectAny(c.begin(), c.end());
694 }
695
696 /** when n Futures have completed, the Future completes with a vector of
697   the index and Try of those n Futures (the indices refer to the original
698   order, but the result vector will be in an arbitrary order)
699
700   Not thread safe.
701   */
702 template <class InputIterator>
703 Future<std::vector<std::pair<
704   size_t,
705   Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>>
706 collectN(InputIterator first, InputIterator last, size_t n);
707
708 // Sugar for the most common case
709 template <class Collection>
710 auto collectN(Collection&& c, size_t n)
711     -> decltype(collectN(c.begin(), c.end(), n)) {
712   return collectN(c.begin(), c.end(), n);
713 }
714
715 template <typename F, typename T, typename ItT>
716 using MaybeTryArg = typename std::conditional<
717   detail::callableWith<F, T&&, Try<ItT>&&>::value, Try<ItT>, ItT>::type;
718
719 template<typename F, typename T, typename Arg>
720 using isFutureResult = isFuture<typename std::result_of<F(T&&, Arg&&)>::type>;
721
722 /** repeatedly calls func on every result, e.g.
723     reduce(reduce(reduce(T initial, result of first), result of second), ...)
724
725     The type of the final result is a Future of the type of the initial value.
726
727     Func can either return a T, or a Future<T>
728   */
729 template <class It, class T, class F,
730           class ItT = typename std::iterator_traits<It>::value_type::value_type,
731           class Arg = MaybeTryArg<F, T, ItT>>
732 typename std::enable_if<!isFutureResult<F, T, Arg>::value, Future<T>>::type
733 reduce(It first, It last, T initial, F func);
734
735 template <class It, class T, class F,
736           class ItT = typename std::iterator_traits<It>::value_type::value_type,
737           class Arg = MaybeTryArg<F, T, ItT>>
738 typename std::enable_if<isFutureResult<F, T, Arg>::value, Future<T>>::type
739 reduce(It first, It last, T initial, F func);
740
741 // Sugar for the most common case
742 template <class Collection, class T, class F>
743 auto reduce(Collection&& c, T&& initial, F&& func)
744     -> decltype(reduce(c.begin(), c.end(), initial, func)) {
745   return reduce(
746       c.begin(),
747       c.end(),
748       std::forward<T>(initial),
749       std::forward<F>(func));
750 }
751
752 } // folly
753
754 #include <folly/futures/Future-inl.h>