include/boost/capy/ex/immediate.hpp

100.0% Lines (22/0/22) 84.0% List of functions (21/0/25)
immediate.hpp
f(x) Functions (25)
Function Calls Lines Blocks
boost::capy::immediate<int>::await_ready() const :59 3x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, int, double> >::await_ready() const :59 2x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, int, int, int> >::await_ready() const :59 2x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, unsigned long> >::await_ready() const :59 9x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code> >::await_ready() const :59 5x 100.0% 100.0% boost::capy::immediate<int>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) const :76 1x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, int, double> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) const :76 0 0.0% 0.0% boost::capy::immediate<std::tuple<std::error_code, int, int, int> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) const :76 0 0.0% 0.0% boost::capy::immediate<std::tuple<std::error_code, unsigned long> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) const :76 0 0.0% 0.0% boost::capy::immediate<std::tuple<std::error_code> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) const :76 0 0.0% 0.0% boost::capy::immediate<boost::capy::immediate_test::testMoveSemantics()::move_only>::await_resume() :90 1x 100.0% 100.0% boost::capy::immediate<int>::await_resume() :90 2x 100.0% 100.0% boost::capy::immediate<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::await_resume() :90 1x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, int, double> >::await_resume() :90 3x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, int, int, int> >::await_resume() :90 3x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, unsigned long> >::await_resume() :90 9x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code> >::await_resume() :90 5x 100.0% 100.0% boost::capy::ready() :122 3x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, unsigned long> > boost::capy::ready<unsigned long>(unsigned long) :135 4x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, int, double> > boost::capy::ready<int, double>(int, double) :149 2x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, int, int, int> > boost::capy::ready<int, int, int>(int, int, int) :164 2x 100.0% 100.0% boost::capy::ready(std::error_code) :186 1x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, unsigned long> > boost::capy::ready<unsigned long>(std::error_code, unsigned long) :200 2x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, int, double> > boost::capy::ready<int, double>(std::error_code, int, double) :215 1x 100.0% 100.0% boost::capy::immediate<std::tuple<std::error_code, int, int, int> > boost::capy::ready<int, int, int>(std::error_code, int, int, int) :231 1x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2026 Michael Vandeberg
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/capy
9 //
10
11 #ifndef BOOST_CAPY_EX_IMMEDIATE_HPP
12 #define BOOST_CAPY_EX_IMMEDIATE_HPP
13
14 #include <boost/capy/detail/config.hpp>
15 #include <boost/capy/ex/io_env.hpp>
16 #include <boost/capy/io_result.hpp>
17
18 #include <coroutine>
19 #include <stop_token>
20 #include <utility>
21
22 namespace boost {
23 namespace capy {
24
25 /** An awaitable that completes immediately with a value.
26
27 This awaitable wraps a synchronous result so it can be used in
28 contexts that require an awaitable type. It never suspends -
29 `await_ready()` always returns `true`, so the coroutine machinery
30 is optimized away by the compiler.
31
32 Use this to adapt synchronous operations to satisfy async concepts
33 like @ref IoAwaitable without the overhead of a full coroutine frame.
34
35 @tparam T The result type to wrap.
36
37 @par Example
38 @par !example example_1
39
40
41 @par Building synchronous I/O operations
42 @par !example example_2
43
44
45 @see ready, io_result
46 */
47 template<class T>
48 struct immediate
49 {
50 /** The wrapped value. */
51 T value_;
52
53 /** Always returns true - this awaitable never suspends.
54
55 @return Always `true`, so the awaiting coroutine does not suspend
56 and `await_suspend` is never called.
57 */
58 constexpr bool
59 21x await_ready() const noexcept
60 {
61 21x return true;
62 }
63
64 /** IoAwaitable protocol overload.
65
66 This overload allows `immediate` to satisfy the @ref IoAwaitable
67 concept. Since the result is already available, the environment
68 is unused.
69
70 @param h The coroutine handle (unused).
71 @param env The execution environment (unused).
72
73 @return `std::noop_coroutine()` to indicate no suspension.
74 */
75 std::coroutine_handle<>
76 1x await_suspend(
77 std::coroutine_handle<> h,
78 io_env const* env) const noexcept
79 {
80 (void)h;
81 (void)env;
82 1x return std::noop_coroutine();
83 }
84
85 /** Returns the wrapped value.
86
87 @return The stored value, moved if non-const.
88 */
89 [[nodiscard]] constexpr T
90 24x await_resume() noexcept
91 {
92 24x return std::move(value_);
93 }
94
95 /** Returns the wrapped value (const overload).
96
97 @return A reference to the stored value. Nothing is moved, so the
98 reference is valid only while the `immediate` is alive.
99 */
100 [[nodiscard]] constexpr T const&
101 await_resume() const noexcept
102 {
103 return value_;
104 }
105 };
106
107 /** Create an immediate awaitable for a successful io_result.
108
109 This helper creates an @ref immediate wrapping an @ref io_result
110 with no error and the provided values.
111
112 @par Example
113 @par !example example_1
114
115
116 @return An immediate awaitable containing a successful io_result.
117
118 @see immediate, io_result
119 */
120 inline
121 immediate<io_result<>>
122 3x ready() noexcept
123 {
124 3x return {{}};
125 }
126
127 /** Create an immediate awaitable for a successful io_result with one value.
128
129 @param t1 The result value.
130
131 @return An immediate awaitable containing `io_result<T1>{std::error_code(), t1}`.
132 */
133 template<class T1>
134 immediate<io_result<T1>>
135 4x ready(T1 t1)
136 {
137 4x return {{std::error_code(), std::move(t1)}};
138 }
139
140 /** Create an immediate awaitable for a successful io_result with two values.
141
142 @param t1 The first result value.
143 @param t2 The second result value.
144
145 @return An immediate awaitable containing `io_result<T1,T2>{std::error_code(), t1, t2}`.
146 */
147 template<class T1, class T2>
148 immediate<io_result<T1, T2>>
149 2x ready(T1 t1, T2 t2)
150 {
151 2x return {{std::error_code(), std::move(t1), std::move(t2)}};
152 }
153
154 /** Create an immediate awaitable for a successful io_result with three values.
155
156 @param t1 The first result value.
157 @param t2 The second result value.
158 @param t3 The third result value.
159
160 @return An immediate awaitable containing `io_result<T1,T2,T3>{std::error_code(), t1, t2, t3}`.
161 */
162 template<class T1, class T2, class T3>
163 immediate<io_result<T1, T2, T3>>
164 2x ready(T1 t1, T2 t2, T3 t3)
165 {
166 2x return {{std::error_code(), std::move(t1), std::move(t2), std::move(t3)}};
167 }
168
169 /** Create an immediate awaitable for a failed io_result.
170
171 This helper creates an @ref immediate wrapping an @ref io_result
172 with an error code.
173
174 @par Example
175 @par !example example_2
176
177
178 @param ec The error code.
179
180 @return An immediate awaitable containing a failed io_result.
181
182 @see immediate, io_result
183 */
184 inline
185 immediate<io_result<>>
186 1x ready(std::error_code ec) noexcept
187 {
188 1x return {{ec}};
189 }
190
191 /** Create an immediate awaitable for an io_result with error and one value.
192
193 @param ec The error code.
194 @param t1 The result value.
195
196 @return An immediate awaitable containing `io_result<T1>{ec, t1}`.
197 */
198 template<class T1>
199 immediate<io_result<T1>>
200 2x ready(std::error_code ec, T1 t1)
201 {
202 2x return {{ec, std::move(t1)}};
203 }
204
205 /** Create an immediate awaitable for an io_result with error and two values.
206
207 @param ec The error code.
208 @param t1 The first result value.
209 @param t2 The second result value.
210
211 @return An immediate awaitable containing `io_result<T1,T2>{ec, t1, t2}`.
212 */
213 template<class T1, class T2>
214 immediate<io_result<T1, T2>>
215 1x ready(std::error_code ec, T1 t1, T2 t2)
216 {
217 1x return {{ec, std::move(t1), std::move(t2)}};
218 }
219
220 /** Create an immediate awaitable for an io_result with error and three values.
221
222 @param ec The error code.
223 @param t1 The first result value.
224 @param t2 The second result value.
225 @param t3 The third result value.
226
227 @return An immediate awaitable containing `io_result<T1,T2,T3>{ec, t1, t2, t3}`.
228 */
229 template<class T1, class T2, class T3>
230 immediate<io_result<T1, T2, T3>>
231 1x ready(std::error_code ec, T1 t1, T2 t2, T3 t3)
232 {
233 1x return {{ec, std::move(t1), std::move(t2), std::move(t3)}};
234 }
235
236 } // namespace capy
237 } // namespace boost
238
239 #endif
240