11#include < stdexec/execution.hpp>
22#include < test_common/catch2.hpp>
33
4+ #include < type_traits>
5+
46#include " common.cuh"
57#include " nvexec/stream_context.cuh"
68
@@ -11,6 +13,23 @@ using nvexec::is_on_gpu;
1113namespace
1214{
1315
16+ struct move_only_error_handler
17+ {
18+ move_only_error_handler () = default ;
19+ move_only_error_handler (move_only_error_handler const &) = delete ;
20+
21+ STDEXEC_ATTRIBUTE (host, device)
22+ move_only_error_handler (move_only_error_handler &&) = default ;
23+
24+ STDEXEC_ATTRIBUTE (host, device) auto operator ()(int error) const -> int
25+ {
26+ return error;
27+ }
28+ };
29+
30+ static_assert (std::is_trivially_copyable_v<move_only_error_handler>);
31+ static_assert (!std::is_copy_constructible_v<move_only_error_handler>);
32+
1433 TEST_CASE (" nvexec upon_error returns a sender" , " [cuda][stream][adaptors][upon_error]" )
1534 {
1635 nvexec::stream_context stream_ctx{};
@@ -21,6 +40,18 @@ namespace
2140 (void ) snd;
2241 }
2342
43+ TEST_CASE (" nvexec upon_error supports move-only function objects" ,
44+ " [cuda][stream][adaptors][upon_error]" )
45+ {
46+ nvexec::stream_context stream_ctx{};
47+
48+ auto snd = ex::just_error (42 ) | ex::continues_on (stream_ctx.get_scheduler ())
49+ | ex::upon_error (move_only_error_handler{});
50+ auto const [result] = STDEXEC::sync_wait (std::move (snd)).value ();
51+
52+ REQUIRE (result == 42 );
53+ }
54+
2455 TEST_CASE (" nvexec upon_error executes on GPU" , " [cuda][stream][adaptors][upon_error]" )
2556 {
2657 nvexec::stream_context stream_ctx{};
0 commit comments