GCC Code Coverage Report


Directory: ./
File: libs/capy/include/boost/capy/ex/run_on.hpp
Date: 2026-01-23 03:27:33
Exec Total Coverage
Lines: 21 21 100.0%
Functions: 10 10 100.0%
Branches: 0 0 -%

Line Branch Exec Source
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/io_awaitable.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 4 run_on_awaitable(Ex ex, Task inner)
42 4 : ex_(std::move(ex))
43 4 , inner_(std::move(inner))
44 {
45 4 }
46
47 4 bool await_ready() const noexcept
48 {
49 4 return inner_.await_ready();
50 }
51
52 4 auto await_resume()
53 {
54 4 return inner_.await_resume();
55 }
56
57 // IoAwaitable: receives caller's executor and stop_token for completion dispatch
58 template<typename Caller>
59 4 coro await_suspend(coro cont, Caller const& caller_ex, std::stop_token token)
60 {
61 4 auto h = inner_.handle();
62 4 auto& p = h.promise();
63 4 p.set_executor(ex_);
64 4 p.set_continuation(cont, caller_ex);
65 4 p.set_stop_token(token);
66 4 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 4 run_on_awaitable(run_on_awaitable&& other) noexcept
75 4 : ex_(std::move(other.ex_))
76 4 , inner_(std::move(other.inner_))
77 {
78 4 }
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