Skip to content

Commit 66beb19

Browse files
committed
io_result is not bool convertible, and fixes
1 parent b914c41 commit 66beb19

File tree

8 files changed

+69
-103
lines changed

8 files changed

+69
-103
lines changed

CMakePresets.json

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +0,0 @@
1-
{
2-
"version": 8,
3-
"configurePresets": [
4-
{
5-
"name": "Custom configure preset",
6-
"displayName": "Custom configure preset",
7-
"description": "Sets Ninja generator, build and install directory",
8-
"generator": "Ninja",
9-
"binaryDir": "${sourceDir}/out/build/${presetName}",
10-
"cacheVariables": {
11-
"CMAKE_BUILD_TYPE": "Debug",
12-
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
13-
}
14-
}
15-
]
16-
}

include/boost/corosio/io_result.hpp

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,6 @@ struct io_result<>
6363
/** The error code from the operation. */
6464
system::error_code ec;
6565

66-
/** Check if the operation succeeded.
67-
68-
@return `true` if no error occurred.
69-
*/
70-
explicit operator bool() const noexcept
71-
{
72-
return !ec;
73-
}
74-
7566
/** Throw if an error occurred.
7667
7768
@throws system::system_error if `ec` is set.
@@ -113,15 +104,6 @@ struct io_result<std::size_t>
113104
/** The number of bytes transferred. */
114105
std::size_t n = 0;
115106

116-
/** Check if the operation succeeded.
117-
118-
@return `true` if no error occurred.
119-
*/
120-
explicit operator bool() const noexcept
121-
{
122-
return !ec;
123-
}
124-
125107
/** Get bytes transferred, throwing on error.
126108
127109
@return The number of bytes transferred.
@@ -158,15 +140,6 @@ struct io_result<T>
158140
/** The result value. */
159141
T value_ = {};
160142

161-
/** Check if the operation succeeded.
162-
163-
@return `true` if no error occurred.
164-
*/
165-
explicit operator bool() const noexcept
166-
{
167-
return !ec;
168-
}
169-
170143
/** Get the value, throwing on error.
171144
172145
@return The result value.
@@ -205,15 +178,6 @@ struct io_result<T, U, Args...>
205178
/** The result values. */
206179
std::tuple<T, U, Args...> values;
207180

208-
/** Check if the operation succeeded.
209-
210-
@return `true` if no error occurred.
211-
*/
212-
explicit operator bool() const noexcept
213-
{
214-
return !ec;
215-
}
216-
217181
/** Get the values, throwing on error.
218182
219183
@return The result values as a tuple.

include/boost/corosio/tcp_server.hpp

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include <boost/capy/task.hpp>
1919
#include <boost/capy/concept/io_awaitable.hpp>
2020
#include <boost/capy/concept/executor.hpp>
21-
#include <boost/capy/ex/any_executor_ref.hpp>
21+
#include <boost/capy/ex/any_executor.hpp>
2222
#include <boost/capy/ex/get_stop_token.hpp>
2323
#include <boost/capy/ex/run_async.hpp>
2424

@@ -44,16 +44,33 @@ class BOOST_COROSIO_DECL
4444
struct waiter;
4545

4646
io_context& ctx_;
47-
capy::any_executor_ref dispatch_;
48-
capy::any_executor_ref post_;
47+
capy::any_executor ex_;
4948
waiter* waiters_ = nullptr;
5049
std::vector<acceptor> ports_;
5150

51+
template<capy::Executor Ex>
5252
struct launch_wrapper
5353
{
5454
struct promise_type
5555
{
56-
capy::any_executor_ref d;
56+
Ex ex; // Stored directly in frame, no allocation
57+
58+
// For regular coroutines: first arg is the executor
59+
template<class E, class... Args>
60+
requires capy::Executor<std::decay_t<E>>
61+
promise_type(E e, Args&&...)
62+
: ex(std::move(e))
63+
{
64+
}
65+
66+
// For lambda coroutines: first arg is lambda closure, second is executor
67+
template<class Closure, class E, class... Args>
68+
requires (!capy::Executor<std::decay_t<Closure>> &&
69+
capy::Executor<std::decay_t<E>>)
70+
promise_type(Closure&&, E e, Args&&...)
71+
: ex(std::move(e))
72+
{
73+
}
5774

5875
launch_wrapper get_return_object() noexcept {
5976
return {std::coroutine_handle<promise_type>::from_promise(*this)};
@@ -70,21 +87,18 @@ class BOOST_COROSIO_DECL
7087
struct adapter
7188
{
7289
std::decay_t<Awaitable> aw;
73-
capy::any_executor_ref d;
90+
Ex* ex_ptr;
7491

7592
bool await_ready() { return aw.await_ready(); }
7693
auto await_resume() { return aw.await_resume(); }
7794

7895
auto await_suspend(std::coroutine_handle<promise_type> h)
7996
{
80-
if constexpr (capy::IoAwaitable<
81-
std::decay_t<Awaitable>, capy::any_executor_ref>)
82-
return aw.await_suspend(h, d, std::stop_token{});
83-
else
84-
return aw.await_suspend(h);
97+
static_assert(capy::IoAwaitable<std::decay_t<Awaitable>, Ex>);
98+
return aw.await_suspend(h, *ex_ptr, std::stop_token{});
8599
}
86100
};
87-
return adapter{std::forward<Awaitable>(a), d};
101+
return adapter{std::forward<Awaitable>(a), &ex};
88102
}
89103
};
90104

@@ -126,8 +140,18 @@ class BOOST_COROSIO_DECL
126140
public:
127141
push_aw(tcp_server& self, worker_base& w) noexcept;
128142
bool await_ready() const noexcept;
129-
std::coroutine_handle<> await_suspend(std::coroutine_handle<> h) noexcept;
143+
144+
template<class Handle, class Ex>
145+
std::coroutine_handle<> await_suspend(
146+
Handle h, Ex&, std::stop_token) noexcept
147+
{
148+
return await_suspend_impl(h);
149+
}
150+
130151
void await_resume() noexcept;
152+
153+
private:
154+
std::coroutine_handle<> await_suspend_impl(std::coroutine_handle<> h) noexcept;
131155
};
132156

133157
class BOOST_COROSIO_DECL pop_aw
@@ -138,8 +162,17 @@ class BOOST_COROSIO_DECL
138162
public:
139163
pop_aw(tcp_server& self) noexcept;
140164
bool await_ready() const noexcept;
141-
bool await_suspend(std::coroutine_handle<> h) noexcept;
165+
166+
template<class Handle, class Ex>
167+
bool await_suspend(Handle h, Ex&, std::stop_token) noexcept
168+
{
169+
return await_suspend_impl(h);
170+
}
171+
142172
system::result<worker_base&> await_resume() noexcept;
173+
174+
private:
175+
bool await_suspend_impl(std::coroutine_handle<> h) noexcept;
143176
};
144177

145178
push_aw push(worker_base& w);
@@ -159,17 +192,9 @@ class BOOST_COROSIO_DECL
159192
friend class workers;
160193

161194
public:
162-
socket sock;
163-
164195
virtual ~worker_base() = default;
165196
virtual void run(launcher launch) = 0;
166197
virtual corosio::socket& socket() = 0;
167-
168-
protected:
169-
worker_base(capy::execution_context& ctx)
170-
: sock(ctx)
171-
{
172-
}
173198
};
174199

175200
class launcher
@@ -217,14 +242,15 @@ class BOOST_COROSIO_DECL
217242
} guard{srv_, w};
218243

219244
auto wrapper =
220-
[](Executor ex, tcp_server* self, capy::task<void> t, worker_base* wp)
221-
-> launch_wrapper
222-
{
223-
(void)ex; // Prevent executor destruction while coroutine runs
224-
co_await std::move(t);
225-
co_await self->push(*wp);
226-
}(ex, srv_, std::move(task), w);
245+
[](Executor ex, tcp_server* self, capy::task<void> t, worker_base* wp)
246+
-> launch_wrapper<Executor>
247+
{
248+
(void)ex; // Executor stored in promise via constructor
249+
co_await std::move(t);
250+
co_await self->push(*wp);
251+
}(ex, srv_, std::move(task), w);
227252

253+
// Executor is now stored in promise via constructor
228254
ex.post(std::exchange(wrapper.h, nullptr)); // Release before post
229255
guard.w = nullptr; // Success - dismiss guard
230256
}
@@ -274,8 +300,7 @@ class BOOST_COROSIO_DECL
274300
io_context& ctx,
275301
Ex const& ex)
276302
: ctx_(ctx)
277-
, dispatch_(ex)
278-
, post_(ex)
303+
, ex_(ex)
279304
{
280305
}
281306

src/corosio/src/tcp_server.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ await_ready() const noexcept
3333
std::coroutine_handle<>
3434
tcp_server::
3535
push_aw::
36-
await_suspend(
36+
await_suspend_impl(
3737
std::coroutine_handle<> h) noexcept
3838
{
3939
// Dispatch to server's executor before touching shared state
40-
return self_.dispatch_.dispatch(h);
40+
return self_.ex_.dispatch(h);
4141
}
4242

4343
void
@@ -50,7 +50,7 @@ await_resume() noexcept
5050
auto* wait = self_.waiters_;
5151
self_.waiters_ = wait->next;
5252
wait->w = &w_;
53-
self_.post_.post(wait->h);
53+
self_.ex_.post(wait->h);
5454
}
5555
else
5656
{
@@ -77,7 +77,7 @@ await_ready() const noexcept
7777
bool
7878
tcp_server::
7979
pop_aw::
80-
await_suspend(
80+
await_suspend_impl(
8181
std::coroutine_handle<> h) noexcept
8282
{
8383
wait_.h = h;
@@ -114,7 +114,7 @@ push_sync(worker_base& w) noexcept
114114
auto* wait = waiters_;
115115
waiters_ = wait->next;
116116
wait->w = &w;
117-
post_.post(wait->h);
117+
ex_.post(wait->h);
118118
}
119119
else
120120
{
@@ -138,7 +138,7 @@ tcp_server::do_accept(acceptor& acc)
138138
if(rv.has_error())
139139
continue;
140140
auto& w = rv.value();
141-
auto ec = co_await acc.accept(w.socket());
141+
auto [ec] = co_await acc.accept(w.socket());
142142
if(ec)
143143
{
144144
co_await push(w);
@@ -161,7 +161,7 @@ void
161161
tcp_server::start()
162162
{
163163
for(auto& t : ports_)
164-
capy::run_async(post_)(do_accept(t));
164+
capy::run_async(ex_)(do_accept(t));
165165
}
166166

167167
} // namespace corosio

src/corosio/src/test/mocket.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ get_test_port() noexcept
454454
{
455455
auto port = test_port_base + (next_test_port % test_port_range);
456456
++next_test_port;
457-
return port;
457+
return static_cast<std::uint16_t>(port);
458458
}
459459

460460
} // namespace

test/unit/io_result.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,10 @@ struct io_result_test
2929
// Default construction
3030
io_result<> r1;
3131
BOOST_TEST(!r1.ec);
32-
BOOST_TEST(r1);
3332

3433
// With error
3534
io_result<> r2{make_error_code(system::errc::invalid_argument)};
3635
BOOST_TEST(r2.ec);
37-
BOOST_TEST(!r2);
3836

3937
// Structured binding
4038
auto [ec] = r1;
@@ -54,20 +52,17 @@ struct io_result_test
5452
io_result<std::size_t> r1;
5553
BOOST_TEST(!r1.ec);
5654
BOOST_TEST_EQ(r1.n, 0u);
57-
BOOST_TEST(r1);
5855

5956
// With values
6057
io_result<std::size_t> r2{{}, 42};
6158
BOOST_TEST(!r2.ec);
6259
BOOST_TEST_EQ(r2.n, 42u);
63-
BOOST_TEST(r2);
6460

6561
// With error
6662
io_result<std::size_t> r3{
6763
make_error_code(system::errc::invalid_argument), 10};
6864
BOOST_TEST(r3.ec);
6965
BOOST_TEST_EQ(r3.n, 10u);
70-
BOOST_TEST(!r3);
7166

7267
// Structured binding
7368
auto [ec, n] = r2;
@@ -88,7 +83,6 @@ struct io_result_test
8883
io_result<std::string> r1{{}, "hello"};
8984
BOOST_TEST(!r1.ec);
9085
BOOST_TEST_EQ(r1.value_, "hello");
91-
BOOST_TEST(r1);
9286

9387
// Structured binding
9488
auto [ec, v] = r1;
@@ -101,7 +95,7 @@ struct io_result_test
10195
// With error
10296
io_result<std::string> r2{
10397
make_error_code(system::errc::invalid_argument), "error"};
104-
BOOST_TEST(!r2);
98+
BOOST_TEST(r2.ec);
10599
BOOST_TEST_THROWS(r2.value(), boost::system::system_error);
106100
}
107101

@@ -112,7 +106,6 @@ struct io_result_test
112106
io_result<int, double, std::string> r1{
113107
{}, std::make_tuple(42, 3.14, std::string("test"))};
114108
BOOST_TEST(!r1.ec);
115-
BOOST_TEST(r1);
116109

117110
// Structured binding
118111
auto [ec, a, b, c] = r1;
@@ -131,7 +124,7 @@ struct io_result_test
131124
io_result<int, double> r2{
132125
make_error_code(system::errc::invalid_argument),
133126
std::make_tuple(0, 0.0)};
134-
BOOST_TEST(!r2);
127+
BOOST_TEST(r2.ec);
135128
BOOST_TEST_THROWS(r2.value(), boost::system::system_error);
136129
}
137130

test/unit/signal_set.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ struct signal_set_test
524524
std::raise(SIGINT);
525525

526526
auto result = co_await s.async_wait();
527-
result_ok = static_cast<bool>(result);
527+
result_ok = !result.ec;
528528
}());
529529

530530
ioc.run();
@@ -545,7 +545,7 @@ struct signal_set_test
545545
[&]() -> capy::task<>
546546
{
547547
auto result = co_await s.async_wait();
548-
result_ok = static_cast<bool>(result);
548+
result_ok = !result.ec;
549549
result_ec = result.ec;
550550
}());
551551

0 commit comments

Comments
 (0)