/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include namespace folly { template class FutureExecutor : public ExecutorImpl { public: template explicit FutureExecutor(Args&&... args) : ExecutorImpl(std::forward(args)...) {} /* * Given a function func that returns a Future, adds that function to the * contained Executor and returns a Future which will be fulfilled with * func's result once it has been executed. * * For example: auto f = futureExecutor.addFuture([](){ * return doAsyncWorkAndReturnAFuture(); * }); */ template typename std::enable_if< folly::isFuture>::value, invoke_result_t>::type addFuture(F func) { using T = typename invoke_result_t::value_type; folly::Promise promise; auto future = promise.getFuture(); ExecutorImpl::add([promise = std::move(promise), func = std::move(func)]() mutable { func().then([promise = std::move(promise)](folly::Try&& t) mutable { promise.setTry(std::move(t)); }); }); return future; } /* * Similar to addFuture above, but takes a func that returns some non-Future * type T. * * For example: auto f = futureExecutor.addFuture([]() { * return 42; * }); */ template typename std::enable_if< !folly::isFuture>::value, folly::Future>>>::type addFuture(F func) { using T = folly::lift_unit_t>; folly::Promise promise; auto future = promise.getFuture(); ExecutorImpl::add( [promise = std::move(promise), func = std::move(func)]() mutable { promise.setWith(std::move(func)); }); return future; } }; } // namespace folly