diff --git a/include/nvexec/stream/upon_stopped.cuh b/include/nvexec/stream/upon_stopped.cuh index 83b88fd63..85121582d 100644 --- a/include/nvexec/stream/upon_stopped.cuh +++ b/include/nvexec/stream/upon_stopped.cuh @@ -160,7 +160,7 @@ namespace nv::execution::_strm static_cast(self).sndr_, static_cast(rcvr), [&](_strm::opstate_base& stream_provider) -> _receiver_t - { return _receiver_t(self.fun_, stream_provider); }); + { return _receiver_t(static_cast(self).fun_, stream_provider); }); } STDEXEC_EXPLICIT_THIS_END(connect) diff --git a/test/nvexec/upon_stopped.cpp b/test/nvexec/upon_stopped.cpp index 1b7438f8b..1cac5a096 100644 --- a/test/nvexec/upon_stopped.cpp +++ b/test/nvexec/upon_stopped.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include "common.cuh" #include "nvexec/stream_context.cuh" @@ -12,6 +14,23 @@ using nvexec::is_on_gpu; namespace { + struct move_only_stopped_handler + { + move_only_stopped_handler() = default; + move_only_stopped_handler(move_only_stopped_handler const &) = delete; + + STDEXEC_ATTRIBUTE(host, device) + move_only_stopped_handler(move_only_stopped_handler &&) = default; + + STDEXEC_ATTRIBUTE(host, device) auto operator()() const -> int + { + return 42; + } + }; + + static_assert(std::is_trivially_copyable_v); + static_assert(!std::is_copy_constructible_v); + struct move_only_result { STDEXEC_ATTRIBUTE(host, device) @@ -20,7 +39,7 @@ namespace {} STDEXEC_ATTRIBUTE(host, device) - move_only_result(move_only_result&& other) noexcept + move_only_result(move_only_result &&other) noexcept : value_(other.value_) { other.value_ = 0; @@ -83,6 +102,18 @@ namespace REQUIRE(flags_storage.all_set_once()); } + TEST_CASE("nvexec upon_stopped supports move-only function objects", + "[cuda][stream][adaptors][upon_stopped]") + { + nvexec::stream_context stream_ctx{}; + + auto snd = ex::just_stopped() | ex::continues_on(stream_ctx.get_scheduler()) + | ex::upon_stopped(move_only_stopped_handler{}); + auto const [result] = STDEXEC::sync_wait(std::move(snd)).value(); + + REQUIRE(result == 42); + } + TEST_CASE("nvexec upon_stopped moves its result", "[cuda][stream][adaptors][upon_stopped]") { nvexec::stream_context stream_ctx{};