|
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 |
|
17 | | -#include "exec/libdispatch_queue.hpp" |
18 | | -#include "stdexec/execution.hpp" |
19 | 17 | #include "test_common/catch2.hpp" |
| 18 | + |
| 19 | +#include "stdexec/execution.hpp" |
| 20 | + |
| 21 | +#include "exec/libdispatch_queue.hpp" |
20 | 22 | #include "test_common/type_helpers.hpp" |
21 | 23 |
|
22 | 24 | #include <atomic> |
@@ -196,7 +198,62 @@ namespace |
196 | 198 | CHECK(indices == std::vector<int>{0, 1, 2, 3}); |
197 | 199 | } |
198 | 200 |
|
| 201 | + TEST_CASE("libdispatch bulk accepts lvalue-only callbacks") |
| 202 | + { |
| 203 | + struct callback |
| 204 | + { |
| 205 | + std::atomic<int> *calls; |
| 206 | + |
| 207 | + void operator()(int begin, int end) & noexcept |
| 208 | + { |
| 209 | + calls->fetch_add(end - begin); |
| 210 | + } |
| 211 | + |
| 212 | + void operator()(int, int) && = delete; |
| 213 | + }; |
| 214 | + |
| 215 | + exec::libdispatch_queue queue; |
| 216 | + auto check = [&](auto policy) |
| 217 | + { |
| 218 | + for (int shape: {0, 8}) |
| 219 | + { |
| 220 | + std::atomic<int> calls{0}; |
| 221 | + auto sender = STDEXEC::schedule(queue.get_scheduler()) |
| 222 | + | STDEXEC::bulk_chunked(policy, shape, callback{&calls}); |
| 223 | + REQUIRE(STDEXEC::sync_wait(std::move(sender)).has_value()); |
| 224 | + CHECK(calls.load() == shape); |
| 225 | + } |
| 226 | + }; |
| 227 | + |
| 228 | + check(STDEXEC::par); |
| 229 | + check(STDEXEC::seq); |
| 230 | + } |
| 231 | + |
199 | 232 | #if !STDEXEC_NO_STDCPP_EXCEPTIONS() |
| 233 | + TEST_CASE("libdispatch bulk catches exceptions from lvalue-qualified callbacks") |
| 234 | + { |
| 235 | + struct callback |
| 236 | + { |
| 237 | + void operator()(int, int) & |
| 238 | + { |
| 239 | + throw 42; |
| 240 | + } |
| 241 | + |
| 242 | + void operator()(int, int) && noexcept {} |
| 243 | + }; |
| 244 | + |
| 245 | + exec::libdispatch_queue queue; |
| 246 | + auto check = [&](auto policy) |
| 247 | + { |
| 248 | + auto sender = STDEXEC::schedule(queue.get_scheduler()) |
| 249 | + | STDEXEC::bulk_chunked(policy, 8, callback{}); |
| 250 | + CHECK_THROWS_AS(STDEXEC::sync_wait(std::move(sender)), int); |
| 251 | + }; |
| 252 | + |
| 253 | + check(STDEXEC::par); |
| 254 | + check(STDEXEC::seq); |
| 255 | + } |
| 256 | + |
200 | 257 | TEST_CASE("libdispatch bulk should handle exceptions gracefully") |
201 | 258 | { |
202 | 259 | exec::libdispatch_queue queue; |
|
0 commit comments