folly/futures: use folly::Function to store callback
Summary:This diff makes it possible to pass callables (such as lambdas) to folly::Future::then that are not copy-constructible. As a consequence, move-only types (such as folly::Promise or std::unique_ptr) can now be captured in lambdas passed to folly::Future::then. Using C++14 notation, the following is now possible: Future<Unit>().then([promise = std::move(promise)]() mutable { promise.setValue(123); }); See folly/futures/test/NonCopyableLambdaTest.cpp for more examples. folly::Future uses std::function to store callback functions. (More precisely, the callback function is stored in a std::function in folly::detail::Core.) std::function is a copy-constructible type and it requires that the callable that it stores is copy constructible as well. This diff changes the implementation of folly::detail::Core to use folly::Function instead of std::function. It also simplifies the code in folly::detail::Core a little bit: Core had a reserved space of size 8*sizeof(void*) to store callbacks in-place. Only larger callbacks (capturing more data) would be stored in the std::function, which puts those on the heap. folly::Function has a template parameter to set the size of the in-place callable storage. In Core, it is set to 8*sizeof(void*), so all callbacks that used to be stored in-place inside Core, are now stored in-place inside folly::Function. This even reduces the size of a Core object: the folly::Function object occupies 80 bytes, which is 16 bytes less than what was used before for a std::function (32 bytes) and the callback storage (64 bytes). The resulting size of a Core<Unit> goes down from 192 to 176 bytes (on x86_64). Reviewed By: fugalh Differential Revision: D2884868 fb-gh-sync-id: 35548890c392f80e6c680676b0f98e711bc03ca3 fbshipit-source-id: 35548890c392f80e6c680676b0f98e711bc03ca3
Showing
Please register or sign in to comment