Commit 7dc11fbd authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Shrink the implementations of then and onError

Summary:
[Folly] Shrink the implementations of `then` and `onError`.

Just a small refactor.

Reviewed By: spacedentist

Differential Revision: D5180784

fbshipit-source-id: a399d18500a2b4c5d8f24dee54891cca802b4461
parent 717713f2
...@@ -85,6 +85,11 @@ class CoreCallbackState { ...@@ -85,6 +85,11 @@ class CoreCallbackState {
return std::move(func_)(std::forward<Args>(args)...); return std::move(func_)(std::forward<Args>(args)...);
} }
template <typename... Args>
auto tryInvoke(Args&&... args) noexcept {
return makeTryWith([&] { return invoke(std::forward<Args>(args)...); });
}
void setTry(Try<T>&& t) { void setTry(Try<T>&& t) {
stealPromise().setTry(std::move(t)); stealPromise().setTry(std::move(t));
} }
...@@ -263,26 +268,17 @@ Future<T>::thenImplementation(F&& func, detail::argResult<isTry, F, Args...>) { ...@@ -263,26 +268,17 @@ Future<T>::thenImplementation(F&& func, detail::argResult<isTry, F, Args...>) {
setCallback_( setCallback_(
[state = detail::makeCoreCallbackState( [state = detail::makeCoreCallbackState(
std::move(p), std::forward<F>(func))](Try<T> && t) mutable { std::move(p), std::forward<F>(func))](Try<T> && t) mutable {
auto ew = [&] {
if (!isTry && t.hasException()) { if (!isTry && t.hasException()) {
return std::move(t.exception()); state.setException(std::move(t.exception()));
} else { } else {
try { auto tf2 = state.tryInvoke(t.template get<isTry, Args>()...);
auto f2 = state.invoke(t.template get<isTry, Args>()...); if (tf2.hasException()) {
// that didn't throw, now we can steal p state.setException(std::move(tf2.exception()));
f2.setCallback_([p = state.stealPromise()](Try<B> && b) mutable { } else {
tf2->setCallback_([p = state.stealPromise()](Try<B> && b) mutable {
p.setTry(std::move(b)); p.setTry(std::move(b));
}); });
return exception_wrapper();
} catch (const std::exception& e) {
return exception_wrapper(std::current_exception(), e);
} catch (...) {
return exception_wrapper(std::current_exception());
}
} }
}();
if (ew) {
state.setException(std::move(ew));
} }
}); });
...@@ -326,7 +322,7 @@ typename std::enable_if< ...@@ -326,7 +322,7 @@ typename std::enable_if<
!detail::Extract<F>::ReturnsFuture::value, !detail::Extract<F>::ReturnsFuture::value,
Future<T>>::type Future<T>>::type
Future<T>::onError(F&& func) { Future<T>::onError(F&& func) {
typedef typename detail::Extract<F>::FirstArg Exn; typedef std::remove_reference_t<typename detail::Extract<F>::FirstArg> Exn;
static_assert( static_assert(
std::is_same<typename detail::Extract<F>::RawReturn, T>::value, std::is_same<typename detail::Extract<F>::RawReturn, T>::value,
"Return type of onError callback must be T or Future<T>"); "Return type of onError callback must be T or Future<T>");
...@@ -338,9 +334,9 @@ Future<T>::onError(F&& func) { ...@@ -338,9 +334,9 @@ Future<T>::onError(F&& func) {
setCallback_( setCallback_(
[state = detail::makeCoreCallbackState( [state = detail::makeCoreCallbackState(
std::move(p), std::forward<F>(func))](Try<T> && t) mutable { std::move(p), std::forward<F>(func))](Try<T> && t) mutable {
if (!t.template withException<Exn>([&](Exn& e) { if (auto e = t.template tryGetExceptionObject<Exn>()) {
state.setTry(makeTryWith([&] { return state.invoke(e); })); state.setTry(makeTryWith([&] { return state.invoke(*e); }));
})) { } else {
state.setTry(std::move(t)); state.setTry(std::move(t));
} }
}); });
...@@ -359,7 +355,7 @@ Future<T>::onError(F&& func) { ...@@ -359,7 +355,7 @@ Future<T>::onError(F&& func) {
static_assert( static_assert(
std::is_same<typename detail::Extract<F>::Return, Future<T>>::value, std::is_same<typename detail::Extract<F>::Return, Future<T>>::value,
"Return type of onError callback must be T or Future<T>"); "Return type of onError callback must be T or Future<T>");
typedef typename detail::Extract<F>::FirstArg Exn; typedef std::remove_reference_t<typename detail::Extract<F>::FirstArg> Exn;
Promise<T> p; Promise<T> p;
auto f = p.getFuture(); auto f = p.getFuture();
...@@ -367,23 +363,16 @@ Future<T>::onError(F&& func) { ...@@ -367,23 +363,16 @@ Future<T>::onError(F&& func) {
setCallback_( setCallback_(
[state = detail::makeCoreCallbackState( [state = detail::makeCoreCallbackState(
std::move(p), std::forward<F>(func))](Try<T> && t) mutable { std::move(p), std::forward<F>(func))](Try<T> && t) mutable {
if (!t.template withException<Exn>([&](Exn& e) { if (auto e = t.template tryGetExceptionObject<Exn>()) {
auto ew = [&] { auto tf2 = state.tryInvoke(*e);
try { if (tf2.hasException()) {
auto f2 = state.invoke(e); state.setException(std::move(tf2.exception()));
f2.setCallback_([p = state.stealPromise()]( } else {
Try<T> && t2) mutable { p.setTry(std::move(t2)); }); tf2->setCallback_([p = state.stealPromise()](Try<T> && t3) mutable {
return exception_wrapper(); p.setTry(std::move(t3));
} catch (const std::exception& e2) { });
return exception_wrapper(std::current_exception(), e2);
} catch (...) {
return exception_wrapper(std::current_exception());
}
}();
if (ew) {
state.setException(std::move(ew));
} }
})) { } else {
state.setTry(std::move(t)); state.setTry(std::move(t));
} }
}); });
...@@ -423,21 +412,13 @@ Future<T>::onError(F&& func) { ...@@ -423,21 +412,13 @@ Future<T>::onError(F&& func) {
[state = detail::makeCoreCallbackState( [state = detail::makeCoreCallbackState(
std::move(p), std::forward<F>(func))](Try<T> t) mutable { std::move(p), std::forward<F>(func))](Try<T> t) mutable {
if (t.hasException()) { if (t.hasException()) {
auto ew = [&] { auto tf2 = state.tryInvoke(std::move(t.exception()));
try { if (tf2.hasException()) {
auto f2 = state.invoke(std::move(t.exception())); state.setException(std::move(tf2.exception()));
f2.setCallback_([p = state.stealPromise()](Try<T> t2) mutable { } else {
p.setTry(std::move(t2)); tf2->setCallback_([p = state.stealPromise()](Try<T> t3) mutable {
p.setTry(std::move(t3));
}); });
return exception_wrapper();
} catch (const std::exception& e2) {
return exception_wrapper(std::current_exception(), e2);
} catch (...) {
return exception_wrapper(std::current_exception());
}
}();
if (ew) {
state.setException(std::move(ew));
} }
} else { } else {
state.setTry(std::move(t)); state.setTry(std::move(t));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment