Skip to content

Commit b273eee

Browse files
authored
Merge pull request #1685 from RobertLeahy/sfinae_20251127
asioexec::completion_token & ::use_sender: Constrain Initiate
2 parents 05edd1a + 5953eb3 commit b273eee

File tree

4 files changed

+39
-0
lines changed

4 files changed

+39
-0
lines changed

include/asioexec/completion_token.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ namespace ASIOEXEC_ASIO_NAMESPACE {
527527
template <typename... Signatures>
528528
struct async_result<::asioexec::completion_token_t, Signatures...> {
529529
template <typename Initiation, typename... Args>
530+
requires (std::is_constructible_v<std::decay_t<Args>, Args> && ...)
530531
static constexpr auto
531532
initiate(Initiation&& i, const ::asioexec::completion_token_t&, Args&&... args) {
532533
return ::asioexec::detail::completion_token::sender<

include/asioexec/use_sender.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ namespace ASIOEXEC_ASIO_NAMESPACE {
212212
template <typename... Signatures>
213213
struct async_result<::asioexec::use_sender_t, Signatures...> {
214214
template <typename Initiation, typename... Args>
215+
requires(std::is_constructible_v<std::decay_t<Args>, Args> && ...)
215216
static constexpr auto
216217
initiate(Initiation&& i, const ::asioexec::use_sender_t&, Args&&... args) {
217218
return ::asioexec::detail::use_sender::sender(

test/asioexec/test_completion_token.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,4 +997,25 @@ namespace {
997997
CHECK(ctx.stopped());
998998
}
999999

1000+
TEST_CASE(
1001+
"Substitution into async_result<completion_token, ...>::initiate is SFINAE-friendly",
1002+
"[asioexec][completion_token]") {
1003+
asio_impl::io_context ctx;
1004+
asio_impl::ip::tcp::socket socket(ctx);
1005+
asio_impl::streambuf buf;
1006+
// With a SFINAE-unfriendly async_result<...>::initiate the below line doesn't compile because there's a hard compilation error trying to consider the async_read overload for dynamic buffers
1007+
//
1008+
// See: https://github.com/NVIDIA/stdexec/issues/1684
1009+
auto sender = asio_impl::async_read(socket, buf, completion_token);
1010+
auto op = ::stdexec::connect(
1011+
std::move(sender) | ::stdexec::then([](const auto ec, const auto bytes_transferred) {
1012+
CHECK(ec);
1013+
CHECK(!bytes_transferred);
1014+
}),
1015+
expect_void_receiver{});
1016+
::stdexec::start(op);
1017+
CHECK(ctx.run() != 0);
1018+
CHECK(ctx.stopped());
1019+
}
1020+
10001021
} // namespace

test/asioexec/test_use_sender.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,20 @@ namespace {
250250
CHECK(ctx.stopped());
251251
}
252252

253+
TEST_CASE(
254+
"Substitution into async_result<use_sender, ...>::initiate is SFINAE-friendly",
255+
"[asioexec][completion_token]") {
256+
asio_impl::io_context ctx;
257+
asio_impl::ip::tcp::socket socket(ctx);
258+
asio_impl::streambuf buf;
259+
// With a SFINAE-unfriendly async_result<...>::initiate the below line doesn't compile because there's a hard compilation error trying to consider the async_read overload for dynamic buffers
260+
//
261+
// See: https://github.com/NVIDIA/stdexec/issues/1684
262+
auto sender = asio_impl::async_read(socket, buf, use_sender);
263+
auto op = ::stdexec::connect(std::move(sender), expect_error_receiver{});
264+
::stdexec::start(op);
265+
CHECK(ctx.run() != 0);
266+
CHECK(ctx.stopped());
267+
}
268+
253269
} // namespace

0 commit comments

Comments
 (0)