Skip to content

Commit 92dc830

Browse files
Fix nvexec upon_stopped move-only callable forwarding (#2193)
* Fix nvexec upon_stopped callable forwarding * clang-format --------- Co-authored-by: Eric Niebler <eniebler@nvidia.com>
1 parent ca11a04 commit 92dc830

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

include/nvexec/stream/upon_stopped.cuh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ namespace nv::execution::_strm
160160
static_cast<Self&&>(self).sndr_,
161161
static_cast<Receiver&&>(rcvr),
162162
[&](_strm::opstate_base<Receiver>& stream_provider) -> _receiver_t<Receiver>
163-
{ return _receiver_t<Receiver>(self.fun_, stream_provider); });
163+
{ return _receiver_t<Receiver>(static_cast<Self&&>(self).fun_, stream_provider); });
164164
}
165165
STDEXEC_EXPLICIT_THIS_END(connect)
166166

test/nvexec/upon_stopped.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <test_common/senders.hpp>
44
#include <test_common/type_helpers.hpp>
55

6+
#include <type_traits>
7+
68
#include "common.cuh"
79
#include "nvexec/stream_context.cuh"
810

@@ -12,6 +14,23 @@ using nvexec::is_on_gpu;
1214

1315
namespace
1416
{
17+
struct move_only_stopped_handler
18+
{
19+
move_only_stopped_handler() = default;
20+
move_only_stopped_handler(move_only_stopped_handler const &) = delete;
21+
22+
STDEXEC_ATTRIBUTE(host, device)
23+
move_only_stopped_handler(move_only_stopped_handler &&) = default;
24+
25+
STDEXEC_ATTRIBUTE(host, device) auto operator()() const -> int
26+
{
27+
return 42;
28+
}
29+
};
30+
31+
static_assert(std::is_trivially_copyable_v<move_only_stopped_handler>);
32+
static_assert(!std::is_copy_constructible_v<move_only_stopped_handler>);
33+
1534
struct move_only_result
1635
{
1736
STDEXEC_ATTRIBUTE(host, device)
@@ -20,7 +39,7 @@ namespace
2039
{}
2140

2241
STDEXEC_ATTRIBUTE(host, device)
23-
move_only_result(move_only_result&& other) noexcept
42+
move_only_result(move_only_result &&other) noexcept
2443
: value_(other.value_)
2544
{
2645
other.value_ = 0;
@@ -83,6 +102,18 @@ namespace
83102
REQUIRE(flags_storage.all_set_once());
84103
}
85104

105+
TEST_CASE("nvexec upon_stopped supports move-only function objects",
106+
"[cuda][stream][adaptors][upon_stopped]")
107+
{
108+
nvexec::stream_context stream_ctx{};
109+
110+
auto snd = ex::just_stopped() | ex::continues_on(stream_ctx.get_scheduler())
111+
| ex::upon_stopped(move_only_stopped_handler{});
112+
auto const [result] = STDEXEC::sync_wait(std::move(snd)).value();
113+
114+
REQUIRE(result == 42);
115+
}
116+
86117
TEST_CASE("nvexec upon_stopped moves its result", "[cuda][stream][adaptors][upon_stopped]")
87118
{
88119
nvexec::stream_context stream_ctx{};

0 commit comments

Comments
 (0)