- template <class F>
- typename std::enable_if<
- !isFuture<typename std::result_of<F(Try<T>&&)>::type>::value,
- Future<typename std::result_of<F(Try<T>&&)>::type> >::type
- then(F&& func);
-
- /// Variant where func takes a T directly, bypassing a try. Any exceptions
- /// will be implicitly passed on to the resultant Future.
- ///
- /// Future<int> f = makeFuture<int>(42).then([](int i) { return i+1; });
- template <class F>
- typename std::enable_if<
- !std::is_same<T, void>::value &&
- !isFuture<typename std::result_of<
- F(typename detail::AliasIfVoid<T>::type&&)>::type>::value,
- Future<typename std::result_of<
- F(typename detail::AliasIfVoid<T>::type&&)>::type> >::type
- then(F&& func);
-
- /// Like the above variant, but for void futures. That is, func takes no
- /// argument.
- ///
- /// Future<int> f = makeFuture().then([] { return 42; });
- template <class F>
- typename std::enable_if<
- std::is_same<T, void>::value &&
- !isFuture<typename std::result_of<F()>::type>::value,
- Future<typename std::result_of<F()>::type> >::type
- then(F&& func);
-
- /// Variant where func returns a Future<T> instead of a T. e.g.
- ///
- /// Future<string> f2 = f1.then(
- /// [](Try<T>&&) { return makeFuture<string>("foo"); });
- template <class F>
- typename std::enable_if<
- isFuture<typename std::result_of<F(Try<T>&&)>::type>::value,
- Future<typename std::result_of<F(Try<T>&&)>::type::value_type> >::type
- then(F&& func);
-
- /// Variant where func returns a Future<T2> and takes a T directly, bypassing
- /// a Try. Any exceptions will be implicitly passed on to the resultant
- /// Future. For example,
- ///
- /// Future<int> f = makeFuture<int>(42).then(
- /// [](int i) { return makeFuture<int>(i+1); });
- template <class F>
- typename std::enable_if<
- !std::is_same<T, void>::value &&
- isFuture<typename std::result_of<
- F(typename detail::AliasIfVoid<T>::type&&)>::type>::value,
- Future<typename std::result_of<
- F(typename detail::AliasIfVoid<T>::type&&)>::type::value_type> >::type
- then(F&& func);
-
- /// Like the above variant, but for void futures. That is, func takes no
- /// argument and returns a future.
- ///
- /// Future<int> f = makeFuture().then(
- /// [] { return makeFuture<int>(42); });
- template <class F>
- typename std::enable_if<
- std::is_same<T, void>::value &&
- isFuture<typename std::result_of<F()>::type>::value,
- Future<typename std::result_of<F()>::type::value_type> >::type
- then(F&& func);
-
- /// Variant where func is an ordinary function (static method, method)
- ///
- /// R doWork(Try<T>&&);
- ///
- /// Future<R> f2 = f1.then(doWork);
- ///
- /// or
- ///
- /// struct Worker {
- /// static R doWork(Try<T>&&); }
- ///
- /// Future<R> f2 = f1.then(&Worker::doWork);
- template <class = T, class R = std::nullptr_t>
- typename std::enable_if<!isFuture<R>::value, Future<R>>::type
- inline then(R(*func)(Try<T>&&)) {
- return then([func](Try<T>&& t) {
- return (*func)(std::move(t));
- });
- }
-
- /// Variant where func returns a Future<R> instead of a R. e.g.
- ///
- /// struct Worker {
- /// Future<R> doWork(Try<T>&&); }
- ///
- /// Future<R> f2 = f1.then(&Worker::doWork);
- template <class = T, class R = std::nullptr_t>
- typename std::enable_if<isFuture<R>::value, R>::type
- inline then(R(*func)(Try<T>&&)) {
- return then([func](Try<T>&& t) {
- return (*func)(std::move(t));
- });