2c2f0aa68e6843129afded6fcfca2d5599028986
[folly.git] / folly / wangle / futures / Future-inl.h
1 /*
2  * Copyright 2014 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 <chrono>
20 #include <thread>
21
22 #include <folly/Baton.h>
23 #include <folly/wangle/futures/detail/Core.h>
24 #include <folly/wangle/futures/Timekeeper.h>
25
26 namespace folly { namespace wangle {
27
28 class Timekeeper;
29
30 namespace detail {
31   Timekeeper* getTimekeeperSingleton();
32 }
33
34 template <typename T>
35 struct isFuture {
36   static const bool value = false;
37 };
38
39 template <typename T>
40 struct isFuture<Future<T> > {
41   static const bool value = true;
42 };
43
44 template <class T>
45 Future<T>::Future(Future<T>&& other) noexcept : core_(nullptr) {
46   *this = std::move(other);
47 }
48
49 template <class T>
50 Future<T>& Future<T>::operator=(Future<T>&& other) {
51   std::swap(core_, other.core_);
52   return *this;
53 }
54
55 template <class T>
56 Future<T>::~Future() {
57   detach();
58 }
59
60 template <class T>
61 void Future<T>::detach() {
62   if (core_) {
63     core_->detachFuture();
64     core_ = nullptr;
65   }
66 }
67
68 template <class T>
69 void Future<T>::throwIfInvalid() const {
70   if (!core_)
71     throw NoState();
72 }
73
74 template <class T>
75 template <class F>
76 void Future<T>::setCallback_(F&& func) {
77   throwIfInvalid();
78   core_->setCallback(std::move(func));
79 }
80
81 // Variant: f.then([](Try<T>&& t){ return t.value(); });
82 template <class T>
83 template <class F>
84 typename std::enable_if<
85   !isFuture<typename std::result_of<F(Try<T>&&)>::type>::value,
86   Future<typename std::result_of<F(Try<T>&&)>::type> >::type
87 Future<T>::then(F&& func) {
88   typedef typename std::result_of<F(Try<T>&&)>::type B;
89
90   throwIfInvalid();
91
92   // wrap these so we can move them into the lambda
93   folly::MoveWrapper<Promise<B>> p;
94   folly::MoveWrapper<F> funcm(std::forward<F>(func));
95
96   // grab the Future now before we lose our handle on the Promise
97   auto f = p->getFuture();
98
99   /* This is a bit tricky.
100
101      We can't just close over *this in case this Future gets moved. So we
102      make a new dummy Future. We could figure out something more
103      sophisticated that avoids making a new Future object when it can, as an
104      optimization. But this is correct.
105
106      core_ can't be moved, it is explicitly disallowed (as is copying). But
107      if there's ever a reason to allow it, this is one place that makes that
108      assumption and would need to be fixed. We use a standard shared pointer
109      for core_ (by copying it in), which means in essence obj holds a shared
110      pointer to itself.  But this shouldn't leak because Promise will not
111      outlive the continuation, because Promise will setException() with a
112      broken Promise if it is destructed before completed. We could use a
113      weak pointer but it would have to be converted to a shared pointer when
114      func is executed (because the Future returned by func may possibly
115      persist beyond the callback, if it gets moved), and so it is an
116      optimization to just make it shared from the get-go.
117
118      We have to move in the Promise and func using the MoveWrapper
119      hack. (func could be copied but it's a big drag on perf).
120
121      Two subtle but important points about this design. detail::Core has no
122      back pointers to Future or Promise, so if Future or Promise get moved
123      (and they will be moved in performant code) we don't have to do
124      anything fancy. And because we store the continuation in the
125      detail::Core, not in the Future, we can execute the continuation even
126      after the Future has gone out of scope. This is an intentional design
127      decision. It is likely we will want to be able to cancel a continuation
128      in some circumstances, but I think it should be explicit not implicit
129      in the destruction of the Future used to create it.
130      */
131   setCallback_(
132     [p, funcm](Try<T>&& t) mutable {
133       p->fulfil([&]() {
134           return (*funcm)(std::move(t));
135         });
136     });
137
138   return std::move(f);
139 }
140
141 // Variant: f.then([](T&& t){ return t; });
142 template <class T>
143 template <class F>
144 typename std::enable_if<
145   !std::is_same<T, void>::value &&
146   !isFuture<typename std::result_of<
147     F(typename detail::AliasIfVoid<T>::type&&)>::type>::value,
148   Future<typename std::result_of<
149     F(typename detail::AliasIfVoid<T>::type&&)>::type> >::type
150 Future<T>::then(F&& func) {
151   typedef typename std::result_of<F(T&&)>::type B;
152
153   throwIfInvalid();
154
155   folly::MoveWrapper<Promise<B>> p;
156   folly::MoveWrapper<F> funcm(std::forward<F>(func));
157   auto f = p->getFuture();
158
159   setCallback_(
160     [p, funcm](Try<T>&& t) mutable {
161       if (t.hasException()) {
162         p->setException(t.getException());
163       } else {
164         p->fulfil([&]() {
165           return (*funcm)(std::move(t.value()));
166         });
167       }
168     });
169
170   return std::move(f);
171 }
172
173 // Variant: f.then([](){ return; });
174 template <class T>
175 template <class F>
176 typename std::enable_if<
177   std::is_same<T, void>::value &&
178   !isFuture<typename std::result_of<F()>::type>::value,
179   Future<typename std::result_of<F()>::type> >::type
180 Future<T>::then(F&& func) {
181   typedef typename std::result_of<F()>::type B;
182
183   throwIfInvalid();
184
185   folly::MoveWrapper<Promise<B>> p;
186   folly::MoveWrapper<F> funcm(std::forward<F>(func));
187   auto f = p->getFuture();
188
189   setCallback_(
190     [p, funcm](Try<T>&& t) mutable {
191       if (t.hasException()) {
192         p->setException(t.getException());
193       } else {
194         p->fulfil([&]() {
195           return (*funcm)();
196         });
197       }
198     });
199
200   return std::move(f);
201 }
202
203 // Variant: f.then([](Try<T>&& t){ return makeFuture<T>(t.value()); });
204 template <class T>
205 template <class F>
206 typename std::enable_if<
207   isFuture<typename std::result_of<F(Try<T>&&)>::type>::value,
208   Future<typename std::result_of<F(Try<T>&&)>::type::value_type> >::type
209 Future<T>::then(F&& func) {
210   typedef typename std::result_of<F(Try<T>&&)>::type::value_type B;
211
212   throwIfInvalid();
213
214   // wrap these so we can move them into the lambda
215   folly::MoveWrapper<Promise<B>> p;
216   folly::MoveWrapper<F> funcm(std::forward<F>(func));
217
218   // grab the Future now before we lose our handle on the Promise
219   auto f = p->getFuture();
220
221   setCallback_(
222     [p, funcm](Try<T>&& t) mutable {
223       try {
224         auto f2 = (*funcm)(std::move(t));
225         // that didn't throw, now we can steal p
226         f2.setCallback_([p](Try<B>&& b) mutable {
227             p->fulfilTry(std::move(b));
228           });
229       } catch (...) {
230         p->setException(std::current_exception());
231       }
232     });
233
234   return std::move(f);
235 }
236
237 // Variant: f.then([](T&& t){ return makeFuture<T>(t); });
238 template <class T>
239 template <class F>
240 typename std::enable_if<
241   !std::is_same<T, void>::value &&
242   isFuture<typename std::result_of<
243     F(typename detail::AliasIfVoid<T>::type&&)>::type>::value,
244   Future<typename std::result_of<
245     F(typename detail::AliasIfVoid<T>::type&&)>::type::value_type> >::type
246 Future<T>::then(F&& func) {
247   typedef typename std::result_of<F(T&&)>::type::value_type B;
248
249   throwIfInvalid();
250
251   folly::MoveWrapper<Promise<B>> p;
252   folly::MoveWrapper<F> funcm(std::forward<F>(func));
253   auto f = p->getFuture();
254
255   setCallback_(
256     [p, funcm](Try<T>&& t) mutable {
257       if (t.hasException()) {
258         p->setException(t.getException());
259       } else {
260         try {
261           auto f2 = (*funcm)(std::move(t.value()));
262           f2.setCallback_([p](Try<B>&& b) mutable {
263               p->fulfilTry(std::move(b));
264             });
265         } catch (...) {
266           p->setException(std::current_exception());
267         }
268       }
269     });
270
271   return std::move(f);
272 }
273
274 // Variant: f.then([](){ return makeFuture(); });
275 template <class T>
276 template <class F>
277 typename std::enable_if<
278   std::is_same<T, void>::value &&
279   isFuture<typename std::result_of<F()>::type>::value,
280   Future<typename std::result_of<F()>::type::value_type> >::type
281 Future<T>::then(F&& func) {
282   typedef typename std::result_of<F()>::type::value_type B;
283
284   throwIfInvalid();
285
286   folly::MoveWrapper<Promise<B>> p;
287   folly::MoveWrapper<F> funcm(std::forward<F>(func));
288
289   auto f = p->getFuture();
290
291   setCallback_(
292     [p, funcm](Try<T>&& t) mutable {
293       if (t.hasException()) {
294         p->setException(t.getException());
295       } else {
296         try {
297           auto f2 = (*funcm)();
298           f2.setCallback_([p](Try<B>&& b) mutable {
299               p->fulfilTry(std::move(b));
300             });
301         } catch (...) {
302           p->setException(std::current_exception());
303         }
304       }
305     });
306
307   return std::move(f);
308 }
309
310 template <class T>
311 Future<void> Future<T>::then() {
312   return then([] (Try<T>&& t) {});
313 }
314
315 // onError where the callback returns T
316 template <class T>
317 template <class F>
318 typename std::enable_if<
319   !detail::Extract<F>::ReturnsFuture::value,
320   Future<T>>::type
321 Future<T>::onError(F&& func) {
322   typedef typename detail::Extract<F>::FirstArg Exn;
323   static_assert(
324       std::is_same<typename detail::Extract<F>::RawReturn, T>::value,
325       "Return type of onError callback must be T or Future<T>");
326
327   Promise<T> p;
328   auto f = p.getFuture();
329   auto pm = folly::makeMoveWrapper(std::move(p));
330   auto funcm = folly::makeMoveWrapper(std::move(func));
331   setCallback_([pm, funcm](Try<T>&& t) mutable {
332     try {
333       t.throwIfFailed();
334     } catch (Exn& e) {
335       pm->fulfil([&]{
336         return (*funcm)(e);
337       });
338       return;
339     } catch (...) {
340       // fall through
341     }
342     pm->fulfilTry(std::move(t));
343   });
344
345   return f;
346 }
347
348 // onError where the callback returns Future<T>
349 template <class T>
350 template <class F>
351 typename std::enable_if<
352   detail::Extract<F>::ReturnsFuture::value,
353   Future<T>>::type
354 Future<T>::onError(F&& func) {
355   static_assert(
356       std::is_same<typename detail::Extract<F>::Return, Future<T>>::value,
357       "Return type of onError callback must be T or Future<T>");
358   typedef typename detail::Extract<F>::FirstArg Exn;
359
360   Promise<T> p;
361   auto f = p.getFuture();
362   auto pm = folly::makeMoveWrapper(std::move(p));
363   auto funcm = folly::makeMoveWrapper(std::move(func));
364   setCallback_([pm, funcm](Try<T>&& t) mutable {
365     try {
366       t.throwIfFailed();
367     } catch (Exn& e) {
368       try {
369         auto f2 = (*funcm)(e);
370         f2.setCallback_([pm](Try<T>&& t2) mutable {
371           pm->fulfilTry(std::move(t2));
372         });
373       } catch (...) {
374         pm->setException(std::current_exception());
375       }
376       return;
377     } catch (...) {
378       // fall through
379     }
380     pm->fulfilTry(std::move(t));
381   });
382
383   return f;
384 }
385
386 template <class T>
387 typename std::add_lvalue_reference<T>::type Future<T>::value() {
388   throwIfInvalid();
389
390   return core_->getTry().value();
391 }
392
393 template <class T>
394 typename std::add_lvalue_reference<const T>::type Future<T>::value() const {
395   throwIfInvalid();
396
397   return core_->getTry().value();
398 }
399
400 template <class T>
401 Try<T>& Future<T>::getTry() {
402   throwIfInvalid();
403
404   return core_->getTry();
405 }
406
407 template <class T>
408 template <typename Executor>
409 inline Future<T> Future<T>::via(Executor* executor) && {
410   throwIfInvalid();
411
412   this->deactivate();
413   core_->setExecutor(executor);
414
415   return std::move(*this);
416 }
417
418 template <class T>
419 template <typename Executor>
420 inline Future<T> Future<T>::via(Executor* executor) & {
421   throwIfInvalid();
422
423   MoveWrapper<Promise<T>> p;
424   auto f = p->getFuture();
425   then([p](Try<T>&& t) mutable { p->fulfilTry(std::move(t)); });
426   return std::move(f).via(executor);
427 }
428
429 template <class T>
430 bool Future<T>::isReady() const {
431   throwIfInvalid();
432   return core_->ready();
433 }
434
435 template <class T>
436 void Future<T>::raise(std::exception_ptr exception) {
437   core_->raise(exception);
438 }
439
440 // makeFuture
441
442 template <class T>
443 Future<typename std::decay<T>::type> makeFuture(T&& t) {
444   Promise<typename std::decay<T>::type> p;
445   auto f = p.getFuture();
446   p.setValue(std::forward<T>(t));
447   return std::move(f);
448 }
449
450 inline // for multiple translation units
451 Future<void> makeFuture() {
452   Promise<void> p;
453   auto f = p.getFuture();
454   p.setValue();
455   return std::move(f);
456 }
457
458 template <class F>
459 auto makeFutureTry(
460     F&& func,
461     typename std::enable_if<!std::is_reference<F>::value, bool>::type sdf)
462     -> Future<decltype(func())> {
463   Promise<decltype(func())> p;
464   auto f = p.getFuture();
465   p.fulfil(
466     [&func]() {
467       return (func)();
468     });
469   return std::move(f);
470 }
471
472 template <class F>
473 auto makeFutureTry(F const& func) -> Future<decltype(func())> {
474   F copy = func;
475   return makeFutureTry(std::move(copy));
476 }
477
478 template <class T>
479 Future<T> makeFuture(std::exception_ptr const& e) {
480   Promise<T> p;
481   auto f = p.getFuture();
482   p.setException(e);
483   return std::move(f);
484 }
485
486 template <class T, class E>
487 typename std::enable_if<std::is_base_of<std::exception, E>::value,
488                         Future<T>>::type
489 makeFuture(E const& e) {
490   Promise<T> p;
491   auto f = p.getFuture();
492   p.fulfil([&]() -> T { throw e; });
493   return std::move(f);
494 }
495
496 template <class T>
497 Future<T> makeFuture(Try<T>&& t) {
498   try {
499     return makeFuture<T>(std::move(t.value()));
500   } catch (...) {
501     return makeFuture<T>(std::current_exception());
502   }
503 }
504
505 template <>
506 inline Future<void> makeFuture(Try<void>&& t) {
507   try {
508     t.throwIfFailed();
509     return makeFuture();
510   } catch (...) {
511     return makeFuture<void>(std::current_exception());
512   }
513 }
514
515 // via
516 template <typename Executor>
517 Future<void> via(Executor* executor) {
518   return makeFuture().via(executor);
519 }
520
521 // when (variadic)
522
523 template <typename... Fs>
524 typename detail::VariadicContext<
525   typename std::decay<Fs>::type::value_type...>::type
526 whenAll(Fs&&... fs)
527 {
528   auto ctx =
529     new detail::VariadicContext<typename std::decay<Fs>::type::value_type...>();
530   ctx->total = sizeof...(fs);
531   auto f_saved = ctx->p.getFuture();
532   detail::whenAllVariadicHelper(ctx,
533     std::forward<typename std::decay<Fs>::type>(fs)...);
534   return std::move(f_saved);
535 }
536
537 // when (iterator)
538
539 template <class InputIterator>
540 Future<
541   std::vector<
542   Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
543 whenAll(InputIterator first, InputIterator last)
544 {
545   typedef
546     typename std::iterator_traits<InputIterator>::value_type::value_type T;
547
548   auto n = std::distance(first, last);
549   if (n == 0) {
550     return makeFuture(std::vector<Try<T>>());
551   }
552
553   auto ctx = new detail::WhenAllContext<T>();
554
555   ctx->results.resize(n);
556
557   auto f_saved = ctx->p.getFuture();
558
559   for (size_t i = 0; first != last; ++first, ++i) {
560      assert(i < n);
561      auto& f = *first;
562      f.setCallback_([ctx, i, n](Try<T>&& t) {
563          ctx->results[i] = std::move(t);
564          if (++ctx->count == n) {
565            ctx->p.setValue(std::move(ctx->results));
566            delete ctx;
567          }
568        });
569   }
570
571   return std::move(f_saved);
572 }
573
574 template <class InputIterator>
575 Future<
576   std::pair<size_t,
577             Try<
578               typename
579               std::iterator_traits<InputIterator>::value_type::value_type> > >
580 whenAny(InputIterator first, InputIterator last) {
581   typedef
582     typename std::iterator_traits<InputIterator>::value_type::value_type T;
583
584   auto ctx = new detail::WhenAnyContext<T>(std::distance(first, last));
585   auto f_saved = ctx->p.getFuture();
586
587   for (size_t i = 0; first != last; first++, i++) {
588     auto& f = *first;
589     f.setCallback_([i, ctx](Try<T>&& t) {
590       if (!ctx->done.exchange(true)) {
591         ctx->p.setValue(std::make_pair(i, std::move(t)));
592       }
593       ctx->decref();
594     });
595   }
596
597   return std::move(f_saved);
598 }
599
600 template <class InputIterator>
601 Future<std::vector<std::pair<size_t, Try<typename
602   std::iterator_traits<InputIterator>::value_type::value_type>>>>
603 whenN(InputIterator first, InputIterator last, size_t n) {
604   typedef typename
605     std::iterator_traits<InputIterator>::value_type::value_type T;
606   typedef std::vector<std::pair<size_t, Try<T>>> V;
607
608   struct ctx_t {
609     V v;
610     size_t completed;
611     Promise<V> p;
612   };
613   auto ctx = std::make_shared<ctx_t>();
614   ctx->completed = 0;
615
616   // for each completed Future, increase count and add to vector, until we
617   // have n completed futures at which point we fulfil our Promise with the
618   // vector
619   auto it = first;
620   size_t i = 0;
621   while (it != last) {
622     it->then([ctx, n, i](Try<T>&& t) {
623       auto& v = ctx->v;
624       auto c = ++ctx->completed;
625       if (c <= n) {
626         assert(ctx->v.size() < n);
627         v.push_back(std::make_pair(i, std::move(t)));
628         if (c == n) {
629           ctx->p.fulfilTry(Try<V>(std::move(v)));
630         }
631       }
632     });
633
634     it++;
635     i++;
636   }
637
638   if (i < n) {
639     ctx->p.setException(std::runtime_error("Not enough futures"));
640   }
641
642   return ctx->p.getFuture();
643 }
644
645 template <typename T>
646 Future<T>
647 waitWithSemaphore(Future<T>&& f) {
648   Baton<> baton;
649   auto done = f.then([&](Try<T> &&t) {
650     baton.post();
651     return std::move(t.value());
652   });
653   baton.wait();
654   while (!done.isReady()) {
655     // There's a race here between the return here and the actual finishing of
656     // the future. f is completed, but the setup may not have finished on done
657     // after the baton has posted.
658     std::this_thread::yield();
659   }
660   return done;
661 }
662
663 template<>
664 inline Future<void> waitWithSemaphore<void>(Future<void>&& f) {
665   Baton<> baton;
666   auto done = f.then([&](Try<void> &&t) {
667     baton.post();
668     t.value();
669   });
670   baton.wait();
671   while (!done.isReady()) {
672     // There's a race here between the return here and the actual finishing of
673     // the future. f is completed, but the setup may not have finished on done
674     // after the baton has posted.
675     std::this_thread::yield();
676   }
677   return done;
678 }
679
680 template <typename T, class Dur>
681 Future<T>
682 waitWithSemaphore(Future<T>&& f, Dur timeout) {
683   auto baton = std::make_shared<Baton<>>();
684   auto done = f.then([baton](Try<T> &&t) {
685     baton->post();
686     return std::move(t.value());
687   });
688   baton->timed_wait(std::chrono::system_clock::now() + timeout);
689   return done;
690 }
691
692 template <class Dur>
693 Future<void>
694 waitWithSemaphore(Future<void>&& f, Dur timeout) {
695   auto baton = std::make_shared<Baton<>>();
696   auto done = f.then([baton](Try<void> &&t) {
697     baton->post();
698     t.value();
699   });
700   baton->timed_wait(std::chrono::system_clock::now() + timeout);
701   return done;
702 }
703
704 namespace {
705   template <class T>
706   void getWaitHelper(Future<T>* f) {
707     // If we already have a value do the cheap thing
708     if (f->isReady()) {
709       return;
710     }
711
712     folly::Baton<> baton;
713     f->then([&](Try<T> const&) {
714       baton.post();
715     });
716     baton.wait();
717   }
718
719   template <class T>
720   Future<T> getWaitTimeoutHelper(Future<T>* f, Duration dur) {
721     // TODO make and use variadic whenAny #5877971
722     Promise<T> p;
723     auto token = std::make_shared<std::atomic<bool>>();
724     folly::Baton<> baton;
725
726     folly::wangle::detail::getTimekeeperSingleton()->after(dur)
727       .then([&,token](Try<void> const& t) {
728         if (token->exchange(true) == false) {
729           try {
730             t.value();
731             p.setException(TimedOut());
732           } catch (std::exception const& e) {
733             p.setException(std::current_exception());
734           }
735           baton.post();
736         }
737       });
738
739     f->then([&, token](Try<T>&& t) {
740       if (token->exchange(true) == false) {
741         p.fulfilTry(std::move(t));
742         baton.post();
743       }
744     });
745
746     baton.wait();
747     return p.getFuture();
748   }
749 }
750
751 template <class T>
752 T Future<T>::get() {
753   getWaitHelper(this);
754
755   // Big assumption here: the then() call above, since it doesn't move out
756   // the value, leaves us with a value to return here. This would be a big
757   // no-no in user code, but I'm invoking internal developer privilege. This
758   // is slightly more efficient (save a move()) especially if there's an
759   // exception (save a throw).
760   return std::move(value());
761 }
762
763 template <>
764 inline void Future<void>::get() {
765   getWaitHelper(this);
766   value();
767 }
768
769 template <class T>
770 T Future<T>::get(Duration dur) {
771   return std::move(getWaitTimeoutHelper(this, dur).value());
772 }
773
774 template <>
775 inline void Future<void>::get(Duration dur) {
776   getWaitTimeoutHelper(this, dur).value();
777 }
778
779 template <class T>
780 Future<T> Future<T>::within(Duration dur, Timekeeper* tk) {
781   return within(dur, TimedOut(), tk);
782 }
783
784 template <class T>
785 template <class E>
786 Future<T> Future<T>::within(Duration dur, E e, Timekeeper* tk) {
787
788   struct Context {
789     Context(E ex) : exception(std::move(ex)), promise(), token(false) {}
790     E exception;
791     Promise<T> promise;
792     std::atomic<bool> token;
793   };
794   auto ctx = std::make_shared<Context>(std::move(e));
795
796   if (!tk) {
797     tk = folly::wangle::detail::getTimekeeperSingleton();
798   }
799
800   tk->after(dur)
801     .then([ctx](Try<void> const& t) {
802       if (ctx->token.exchange(true) == false) {
803         try {
804           t.throwIfFailed();
805           ctx->promise.setException(std::move(ctx->exception));
806         } catch (std::exception const&) {
807           ctx->promise.setException(std::current_exception());
808         }
809       }
810     });
811
812   this->then([ctx](Try<T>&& t) {
813     if (ctx->token.exchange(true) == false) {
814       ctx->promise.fulfilTry(std::move(t));
815     }
816   });
817
818   return ctx->promise.getFuture();
819 }
820
821 template <class T>
822 Future<T> Future<T>::delayed(Duration dur, Timekeeper* tk) {
823   return whenAll(*this, futures::sleep(dur, tk))
824     .then([](Try<std::tuple<Try<T>, Try<void>>>&& tup) {
825       Try<T>& t = std::get<0>(tup.value());
826       return makeFuture<T>(std::move(t));
827     });
828 }
829
830 }}
831
832 // I haven't included a Future<T&> specialization because I don't forsee us
833 // using it, however it is not difficult to add when needed. Refer to
834 // Future<void> for guidance. std::future and boost::future code would also be
835 // instructive.