File indexing completed on 2024-05-19 04:25:08

0001 /*
0002  *  SPDX-FileCopyrightText: 2023 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef KISFUTUREUTILS_H
0007 #define KISFUTUREUTILS_H
0008 
0009 namespace kismpl {
0010 
0011 /**
0012  * Create a future whose value has already been evaluated
0013  *
0014  * See rejected C++ proposal for details:
0015  * https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3721.pdf
0016  */
0017 template <typename T>
0018 std::future<std::decay_t<T>> make_ready_future(T &&value) {
0019     std::promise<T> promise;
0020     promise.set_value(std::forward<T>(value));
0021     return promise.get_future();
0022 }
0023 
0024 std::future<void> make_ready_future() {
0025     std::promise<void> promise;
0026     promise.set_value();
0027     return promise.get_future();
0028 }
0029 
0030 /**
0031  * Execute a given function \p func when the provided
0032  * future \p future is completed. The future is not
0033  * deferefenced outside the passed function to avoid
0034  * spilling the exceptions.
0035  *
0036  * See rejected C++ proposal for details:
0037  * https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3721.pdf
0038  */
0039 template<class T, class Function>
0040 auto then(std::future<T>&& future, Function&& func)
0041     -> std::future<decltype(func(std::move(future)))>
0042 {
0043     return std::async(std::launch::deferred,
0044         [](std::future<T>&& future, Function&& func)
0045         {
0046             future.wait();
0047             return std::forward<Function>(func)(std::move(future));
0048         },
0049         std::move(future),
0050         std::forward<Function>(func)
0051         );
0052 }
0053 
0054 }
0055 
0056 #endif // KISFUTUREUTILS_H