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