- /// 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));
- });
- }
-
- /// Variant where func is an member function
- ///
- /// struct Worker {
- /// R doWork(Try<T>&&); }
- ///
- /// Worker *w;
- /// Future<R> f2 = f1.then(w, &Worker::doWork);
- template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
- typename std::enable_if<!isFuture<R>::value, Future<R>>::type
- inline then(Caller *instance, R(Caller::*func)(Try<T>&&)) {
- return then([instance, func](Try<T>&& t) {
- return (instance->*func)(std::move(t));
- });
- }
-
- // Same as above, but func takes void instead of Try<void>&&
- template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
- typename std::enable_if<
- std::is_same<T, void>::value && !isFuture<R>::value, Future<R>>::type
- inline then(Caller *instance, R(Caller::*func)()) {
- return then([instance, func]() {
- return (instance->*func)();
- });
- }
-
- // Same as above, but func takes T&& instead of Try<T>&&
- template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
- typename std::enable_if<
- !std::is_same<T, void>::value && !isFuture<R>::value, Future<R>>::type
- inline then(
- Caller *instance,
- R(Caller::*func)(typename detail::AliasIfVoid<T>::type&&)) {
- return then([instance, func](T&& t) {
- return (instance->*func)(std::move(t));
- });
- }
-
- /// Variant where func returns a Future<R> instead of a R. e.g.
- ///
- /// struct Worker {
- /// Future<R> doWork(Try<T>&&); }
- ///
- /// Worker *w;
- /// Future<R> f2 = f1.then(w, &Worker::doWork);
- template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
- typename std::enable_if<isFuture<R>::value, R>::type
- inline then(Caller *instance, R(Caller::*func)(Try<T>&&)) {
- return then([instance, func](Try<T>&& t) {
- return (instance->*func)(std::move(t));
- });
- }
-
- // Same as above, but func takes void instead of Try<void>&&
- template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
- typename std::enable_if<
- std::is_same<T, void>::value && isFuture<R>::value, R>::type
- inline then(Caller *instance, R(Caller::*func)()) {
- return then([instance, func]() {
- return (instance->*func)();
- });
- }
-
- // Same as above, but func takes T&& instead of Try<T>&&
- template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
- typename std::enable_if<
- !std::is_same<T, void>::value && isFuture<R>::value, R>::type
- inline then(
- Caller *instance,
- R(Caller::*func)(typename detail::AliasIfVoid<T>::type&&)) {
- return then([instance, func](T&& t) {
- return (instance->*func)(std::move(t));
- });
- }
-
- /// Convenience method for ignoring the value and creating a Future<void>.