From: Adam Simpkins Date: Thu, 22 Jun 2017 20:39:56 +0000 (-0700) Subject: allow passing function pointers to Future::onError() X-Git-Tag: v2017.06.26.00~15 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=commitdiff_plain;h=49f2f8b170dfee4871a84c57d6e149623126a2d3;ds=sidebyside allow passing function pointers to Future::onError() Summary: Add appropriate specializations for detail::Extract() so that you can pass a plain function pointer to `onError()`. Previously the code only worked with member function pointers and functor-style objects. Reviewed By: yfeldblum, wez Differential Revision: D5286773 fbshipit-source-id: 67b44d1d7573eb1da501475045fd24ad4ab1c074 --- diff --git a/folly/futures/Future-pre.h b/folly/futures/Future-pre.h index e3f5021e..bcae5b08 100644 --- a/folly/futures/Future-pre.h +++ b/folly/futures/Future-pre.h @@ -119,6 +119,22 @@ struct Extract { typedef typename ArgType::FirstArg FirstArg; }; +template +struct Extract { + typedef isFuture ReturnsFuture; + typedef Future Return; + typedef typename ReturnsFuture::Inner RawReturn; + typedef typename ArgType::FirstArg FirstArg; +}; + +template +struct Extract { + typedef isFuture ReturnsFuture; + typedef Future Return; + typedef typename ReturnsFuture::Inner RawReturn; + typedef typename ArgType::FirstArg FirstArg; +}; + // gcc-4.8 refuses to capture a function reference in a lambda. This can be // mitigated by casting them to function pointer types first. The following // helper is used in Future.h to achieve that where necessary. diff --git a/folly/futures/test/FutureTest.cpp b/folly/futures/test/FutureTest.cpp index 3bfb8e33..3322d2f4 100644 --- a/folly/futures/test/FutureTest.cpp +++ b/folly/futures/test/FutureTest.cpp @@ -76,6 +76,15 @@ TEST(Future, makeFutureWithUnit) { EXPECT_EQ(1, count); } +namespace { +Future onErrorHelperEggs(const eggs_t&) { + return makeFuture(10); +} +Future onErrorHelperGeneric(const std::exception&) { + return makeFuture(20); +} +} + TEST(Future, onError) { bool theFlag = false; auto flag = [&]{ theFlag = true; }; @@ -191,6 +200,28 @@ TEST(Future, onError) { EXPECT_NO_THROW(f.value()); } + // Function pointer + { + auto f = makeFuture() + .then([]() -> int { throw eggs; }) + .onError(onErrorHelperEggs) + .onError(onErrorHelperGeneric); + EXPECT_EQ(10, f.value()); + } + { + auto f = makeFuture() + .then([]() -> int { throw std::runtime_error("test"); }) + .onError(onErrorHelperEggs) + .onError(onErrorHelperGeneric); + EXPECT_EQ(20, f.value()); + } + { + auto f = makeFuture() + .then([]() -> int { throw std::runtime_error("test"); }) + .onError(onErrorHelperEggs); + EXPECT_THROW(f.value(), std::runtime_error); + } + // No throw { auto f = makeFuture()