From: Yedidya Feldblum Date: Sun, 9 Jul 2017 03:59:42 +0000 (-0700) Subject: In-place construction for Future X-Git-Tag: v2017.07.10.00^0 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e8527d2e4bfa7dc4538155f38f3374d997dd2f9b;p=folly.git In-place construction for Future Summary: [Folly] In-place construction for `Future`. Using `in_place` as the first argument. Avoid constructing a contained object and then moving it into the `Future`, which may be more expensive, by providing an unambiguous way to specify perfect forwarding. And a matching overload of `makeFuture` for no particularly good reason. Differential Revision: D5362324 fbshipit-source-id: e612965f34ed0fae5fac17db631f7eab9984c696 --- diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index ab70c38d..84bf33a1 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -184,6 +184,14 @@ template Future::Future(typename std::enable_if::value>::type*) : core_(new detail::Core(Try(T()))) {} +template +template < + class... Args, + typename std::enable_if::value, int>:: + type> +Future::Future(in_place_t, Args&&... args) + : core_(new detail::Core(in_place, std::forward(args)...)) {} + template Future::~Future() { detach(); diff --git a/folly/futures/Future.h b/folly/futures/Future.h index e5e1fbe8..f4959ba7 100644 --- a/folly/futures/Future.h +++ b/folly/futures/Future.h @@ -25,10 +25,11 @@ #include #include -#include -#include #include +#include +#include #include +#include #include // boring predeclarations and details @@ -90,6 +91,12 @@ class Future { /* implicit */ Future( typename std::enable_if::value>::type* = nullptr); + template < + class... Args, + typename std::enable_if::value, int>:: + type = 0> + explicit Future(in_place_t, Args&&... args); + ~Future(); /** Return the reference to result. Should not be called if !isReady(). diff --git a/folly/futures/detail/Core.h b/folly/futures/detail/Core.h index 30d421c0..dc91729f 100644 --- a/folly/futures/detail/Core.h +++ b/folly/futures/detail/Core.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include @@ -87,6 +89,13 @@ class Core final { fsm_(State::OnlyResult), attached_(1) {} + template + explicit Core(in_place_t, Args&&... args) noexcept( + noexcept(::new (nullptr) T(std::declval()...))) + : result_(in_place, in_place, std::forward(args)...), + fsm_(State::OnlyResult), + attached_(1) {} + ~Core() { DCHECK(attached_ == 0); } diff --git a/folly/futures/test/FutureTest.cpp b/folly/futures/test/FutureTest.cpp index e886a21a..4dd3f2dc 100644 --- a/folly/futures/test/FutureTest.cpp +++ b/folly/futures/test/FutureTest.cpp @@ -810,6 +810,11 @@ TEST(Future, ImplicitConstructor) { //auto f2 = []() -> Future { }(); } +TEST(Future, InPlaceConstructor) { + auto f = Future>(in_place, 5, 3.2); + EXPECT_EQ(5, f.value().first); +} + TEST(Future, thenDynamic) { // folly::dynamic has a constructor that takes any T, this test makes // sure that we call the then lambda with folly::dynamic and not