GCC Code Coverage Report


Directory: ./
File: libs/capy/include/boost/capy/ex/run_sync.hpp
Date: 2026-01-17 14:56:58
Exec Total Coverage
Lines: 25 25 100.0%
Functions: 5 5 100.0%
Branches: 8 8 100.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_SYNC_HPP
11 #define BOOST_CAPY_RUN_SYNC_HPP
12
13 #include <boost/capy/detail/config.hpp>
14 #include <boost/capy/ex/any_coro.hpp>
15 #include <boost/capy/task.hpp>
16
17 #include <coroutine>
18 #include <exception>
19 #include <type_traits>
20 #include <utility>
21
22 namespace boost {
23 namespace capy {
24
25 namespace detail {
26
27 /** Trivial dispatcher for synchronous execution.
28
29 Returns the coroutine handle directly for symmetric transfer,
30 enabling inline execution without scheduling.
31 */
32 struct sync_dispatcher
33 {
34 23 any_coro operator()(any_coro h) const
35 {
36 23 return h;
37 }
38 };
39
40 /** Synchronous task runner.
41
42 Runs a coroutine task to completion on the caller's thread,
43 returning the result directly or rethrowing any exception.
44
45 This class is not intended for direct use. Use the `run_sync()`
46 factory function instead.
47
48 @par Thread Safety
49 Not thread-safe. The task runs entirely on the calling thread.
50
51 @see run_sync
52 */
53 class sync_runner
54 {
55 public:
56 sync_runner() = default;
57
58 sync_runner(sync_runner const&) = delete;
59 sync_runner& operator=(sync_runner const&) = delete;
60 sync_runner(sync_runner&&) = default;
61 sync_runner& operator=(sync_runner&&) = default;
62
63 /** Run a task to completion and return the result.
64
65 Executes the task synchronously on the calling thread. The task
66 runs to completion before this function returns.
67
68 @par Exception Safety
69 If the task throws an exception, it is rethrown to the caller.
70
71 @param t The task to execute.
72
73 @return The value returned by the task.
74
75 @throws Any exception thrown by the task.
76 */
77 template<typename T>
78 46 T operator()(task<T> t) &&
79 {
80 46 auto h = t.release();
81 sync_dispatcher d;
82
83 46 h.promise().continuation_ = std::noop_coroutine();
84 46 h.promise().ex_ = d;
85 46 h.promise().caller_ex_ = d;
86 46 h.promise().needs_dispatch_ = false;
87
88
1/1
✓ Branch 3 taken 23 times.
46 d(any_coro{h}).resume();
89
90 46 std::exception_ptr ep = h.promise().ep_;
91
92 if constexpr (std::is_void_v<T>)
93 {
94
1/1
✓ Branch 1 taken 7 times.
14 h.destroy();
95
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
14 if (ep)
96 4 std::rethrow_exception(ep);
97 }
98 else
99 {
100
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 13 times.
32 if (ep)
101 {
102
1/1
✓ Branch 1 taken 3 times.
6 h.destroy();
103 12 std::rethrow_exception(ep);
104 }
105 26 auto& result_base = static_cast<detail::task_return_base<T>&>(
106 26 h.promise());
107 26 auto result = std::move(*result_base.result_);
108
1/1
✓ Branch 1 taken 13 times.
26 h.destroy();
109 30 return result;
110 4 }
111 46 }
112 };
113
114 } // namespace detail
115
116 /** Create a synchronous task runner.
117
118 Returns a runner that executes a coroutine task to completion
119 on the caller's thread. The task completes before this function
120 returns, and the result is returned directly.
121
122 @par Usage
123 @code
124 // Run a task and get the result
125 int value = run_sync()(compute_value());
126
127 // Run a void task
128 run_sync()(do_work());
129
130 // Exceptions propagate normally
131 try {
132 run_sync()(failing_task());
133 } catch (std::exception const& e) {
134 // handle error
135 }
136 @endcode
137
138 @par Thread Safety
139 The task runs entirely on the calling thread. No dispatcher or
140 execution context is required.
141
142 @return A runner object with `operator()(task<T>)` that returns `T`.
143
144 @see task
145 @see run_async
146 @see run_on
147 */
148 inline
149 detail::sync_runner
150 23 run_sync()
151 {
152 23 return detail::sync_runner{};
153 }
154
155 } // namespace capy
156 } // namespace boost
157
158 #endif
159