From 43f0b4a15a4a968ae00cc4b50e68a62d4c54cd95 Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Sat, 15 Aug 2026 23:53:31 +0200 Subject: [PATCH 1/4] Fix schedule_all move-only range support --- include/exec/static_thread_pool.hpp | 2 +- test/exec/test_static_thread_pool.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/exec/static_thread_pool.hpp b/include/exec/static_thread_pool.hpp index 918fca6f4..615a194a7 100644 --- a/include/exec/static_thread_pool.hpp +++ b/include/exec/static_thread_pool.hpp @@ -1652,7 +1652,7 @@ namespace experimental::execution struct opstate_base_with_receiver : opstate_base { explicit opstate_base_with_receiver(Range range, _static_thread_pool& pool, Receiver rcvr) - : opstate_base{range, pool} + : opstate_base{std::move(range), pool} , rcvr_(static_cast(rcvr)) {} diff --git a/test/exec/test_static_thread_pool.cpp b/test/exec/test_static_thread_pool.cpp index 485745063..44cb6ad21 100644 --- a/test/exec/test_static_thread_pool.cpp +++ b/test/exec/test_static_thread_pool.cpp @@ -168,6 +168,19 @@ TEST_CASE("schedule_all on static_thread_pool handles empty ranges", "[types][st CHECK(ex::sync_wait(std::move(sender))); } +TEST_CASE("schedule_all on static_thread_pool accepts move-only ranges", + "[types][static_thread_pool]") +{ + exec::static_thread_pool pool{1}; + int sum = 0; + auto sender = exec::schedule_all(pool, std::views::all(std::vector{1, 2, 3})) + | exec::transform_each(ex::then([&sum](int value) noexcept { sum += value; })) + | exec::ignore_all_values(); + + CHECK(ex::sync_wait(std::move(sender))); + CHECK(sum == 6); +} + #if !STDEXEC_NO_STDCPP_EXCEPTIONS() TEST_CASE("schedule_all on static_thread_pool sends errors from set_next", "[types][static_thread_pool]") From 88c840ce6e11e0dc7a53890379bd566ae3de15fe Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Thu, 20 Aug 2026 23:22:51 +0200 Subject: [PATCH 2/4] Fix schedule_all test owning range --- test/exec/test_static_thread_pool.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/exec/test_static_thread_pool.cpp b/test/exec/test_static_thread_pool.cpp index 44cb6ad21..30bba15b0 100644 --- a/test/exec/test_static_thread_pool.cpp +++ b/test/exec/test_static_thread_pool.cpp @@ -173,7 +173,9 @@ TEST_CASE("schedule_all on static_thread_pool accepts move-only ranges", { exec::static_thread_pool pool{1}; int sum = 0; - auto sender = exec::schedule_all(pool, std::views::all(std::vector{1, 2, 3})) + auto sender = exec::schedule_all( + pool, + std::ranges::owning_view>{std::vector{1, 2, 3}}) | exec::transform_each(ex::then([&sum](int value) noexcept { sum += value; })) | exec::ignore_all_values(); From 5570a2bd93ce56156974400a231c401b8fae8034 Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Thu, 20 Aug 2026 23:25:25 +0200 Subject: [PATCH 3/4] Format schedule_all test --- test/exec/test_static_thread_pool.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/exec/test_static_thread_pool.cpp b/test/exec/test_static_thread_pool.cpp index 30bba15b0..e3763eba2 100644 --- a/test/exec/test_static_thread_pool.cpp +++ b/test/exec/test_static_thread_pool.cpp @@ -172,10 +172,11 @@ TEST_CASE("schedule_all on static_thread_pool accepts move-only ranges", "[types][static_thread_pool]") { exec::static_thread_pool pool{1}; - int sum = 0; - auto sender = exec::schedule_all( - pool, - std::ranges::owning_view>{std::vector{1, 2, 3}}) + int sum = 0; + auto sender = exec::schedule_all(pool, + std::ranges::owning_view>{ + std::vector{1, 2, 3} + }) | exec::transform_each(ex::then([&sum](int value) noexcept { sum += value; })) | exec::ignore_all_values(); From 4800f5fba64b0ebeb4b9846cc27e8b086fbf3ddd Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Sun, 30 Aug 2026 19:43:04 +0200 Subject: [PATCH 4/4] Use portable move-only range in schedule_all test --- test/exec/test_static_thread_pool.cpp | 28 ++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/test/exec/test_static_thread_pool.cpp b/test/exec/test_static_thread_pool.cpp index e3763eba2..fe1d19317 100644 --- a/test/exec/test_static_thread_pool.cpp +++ b/test/exec/test_static_thread_pool.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include namespace ex = STDEXEC; @@ -38,6 +39,31 @@ namespace { thread_local int current_numa_node = -1; + struct move_only_range + { + explicit move_only_range(std::vector values) + : values_(std::move(values)) + {} + + move_only_range(move_only_range&&) noexcept = default; + move_only_range(move_only_range const &) = delete; + auto operator=(move_only_range&&) noexcept -> move_only_range& = default; + auto operator=(move_only_range const &) -> move_only_range& = delete; + + auto begin() noexcept + { + return values_.begin(); + } + + auto end() noexcept + { + return values_.end(); + } + + private: + std::vector values_; + }; + struct two_node_numa_policy { [[nodiscard]] @@ -174,7 +200,7 @@ TEST_CASE("schedule_all on static_thread_pool accepts move-only ranges", exec::static_thread_pool pool{1}; int sum = 0; auto sender = exec::schedule_all(pool, - std::ranges::owning_view>{ + move_only_range{ std::vector{1, 2, 3} }) | exec::transform_each(ex::then([&sum](int value) noexcept { sum += value; }))