libs/capy/include/boost/capy/ex/run_on.hpp
100.0% Lines (21/21)
100.0% Functions (10/10)
-% Branches (0/0)
libs/capy/include/boost/capy/ex/run_on.hpp
| Line | Hits | Source Code |
|---|---|---|
| 1 | // | |
| 2 | // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com) | |
| 3 | // | |
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
| 6 | // | |
| 7 | // Official repository: https://github.com/cppalliance/capy | |
| 8 | // | |
| 9 | ||
| 10 | #ifndef BOOST_CAPY_RUN_ON_HPP | |
| 11 | #define BOOST_CAPY_RUN_ON_HPP | |
| 12 | ||
| 13 | #include <boost/capy/detail/config.hpp> | |
| 14 | #include <boost/capy/concept/executor.hpp> | |
| 15 | #include <boost/capy/concept/io_launchable_task.hpp> | |
| 16 | #include <boost/capy/ex/executor_ref.hpp> | |
| 17 | ||
| 18 | #include <stop_token> | |
| 19 | #include <utility> | |
| 20 | ||
| 21 | namespace boost { | |
| 22 | namespace capy { | |
| 23 | namespace detail { | |
| 24 | ||
| 25 | /** Awaitable that binds an IoAwaitableTask to a specific executor. | |
| 26 | ||
| 27 | Stores the executor and inner task by value. When co_awaited, the | |
| 28 | co_await expression's lifetime extension keeps both alive for the | |
| 29 | duration of the operation. | |
| 30 | ||
| 31 | @tparam Task The IoAwaitableTask type | |
| 32 | @tparam Ex The executor type | |
| 33 | */ | |
| 34 | template<IoLaunchableTask Task, Executor Ex> | |
| 35 | struct [[nodiscard]] | |
| 36 | run_on_awaitable | |
| 37 | { | |
| 38 | Ex ex_; | |
| 39 | Task inner_; | |
| 40 | ||
| 41 | 2 | run_on_awaitable(Ex ex, Task inner) |
| 42 | 2 | : ex_(std::move(ex)) |
| 43 | 2 | , inner_(std::move(inner)) |
| 44 | { | |
| 45 | 2 | } |
| 46 | ||
| 47 | 2 | bool await_ready() const noexcept |
| 48 | { | |
| 49 | 2 | return inner_.await_ready(); |
| 50 | } | |
| 51 | ||
| 52 | 2 | decltype(auto) await_resume() |
| 53 | { | |
| 54 | 2 | return inner_.await_resume(); |
| 55 | } | |
| 56 | ||
| 57 | // IoAwaitable: receives caller's executor and stop_token for completion dispatch | |
| 58 | template<typename Caller> | |
| 59 | 2 | coro await_suspend(coro cont, Caller const& caller_ex, std::stop_token token) |
| 60 | { | |
| 61 | 2 | auto h = inner_.handle(); |
| 62 | 2 | auto& p = h.promise(); |
| 63 | 2 | p.set_executor(ex_); |
| 64 | 2 | p.set_continuation(cont, caller_ex); |
| 65 | 2 | p.set_stop_token(token); |
| 66 | 2 | return h; |
| 67 | } | |
| 68 | ||
| 69 | // Non-copyable | |
| 70 | run_on_awaitable(run_on_awaitable const&) = delete; | |
| 71 | run_on_awaitable& operator=(run_on_awaitable const&) = delete; | |
| 72 | ||
| 73 | // Movable | |
| 74 | 2 | run_on_awaitable(run_on_awaitable&& other) noexcept |
| 75 | 2 | : ex_(std::move(other.ex_)) |
| 76 | 2 | , inner_(std::move(other.inner_)) |
| 77 | { | |
| 78 | 2 | } |
| 79 | ||
| 80 | run_on_awaitable& operator=(run_on_awaitable&& other) noexcept | |
| 81 | { | |
| 82 | if(this != &other) | |
| 83 | { | |
| 84 | ex_ = std::move(other.ex_); | |
| 85 | inner_ = std::move(other.inner_); | |
| 86 | } | |
| 87 | return *this; | |
| 88 | } | |
| 89 | }; | |
| 90 | ||
| 91 | } // namespace detail | |
| 92 | ||
| 93 | /** Binds a task to execute on a specific executor. | |
| 94 | ||
| 95 | The executor is stored by value in the returned awaitable. | |
| 96 | When co_awaited, the inner task receives this executor through | |
| 97 | direct promise configuration. | |
| 98 | ||
| 99 | @param ex The executor on which the task should run (copied by value). | |
| 100 | @param t The IoAwaitableTask to bind to the executor. | |
| 101 | ||
| 102 | @return An awaitable that runs t on the specified executor. | |
| 103 | */ | |
| 104 | template<Executor Ex, IoLaunchableTask Task> | |
| 105 | 2 | [[nodiscard]] auto run_on(Ex ex, Task t) |
| 106 | { | |
| 107 | return detail::run_on_awaitable<Task, Ex>{ | |
| 108 | 2 | std::move(ex), std::move(t)}; |
| 109 | } | |
| 110 | ||
| 111 | } // namespace capy | |
| 112 | } // namespace boost | |
| 113 | ||
| 114 | #endif | |
| 115 |