| 319 | Shape task_id_; |
| 320 | |
| 321 | explicit bulk_task(bulk_shared_state *sh_state_arg, Shape task_id_arg) |
| 322 | : sh_state_(sh_state_arg) |
| 323 | , task_id_(task_id_arg) |
| 324 | { |
| 325 | this->execute = [](task_base *t) noexcept |
| 326 | { |
| 327 | auto &sh_state = *static_cast<bulk_task *>(t)->sh_state_; |
| 328 | auto task_id = static_cast<bulk_task *>(t)->task_id_; |
| 329 | auto total_tasks = static_cast<std::uint32_t>(sh_state.num_tasks()); |
| 330 | |
| 331 | auto computation = [&sh_state, task_id](auto &...args) |
| 332 | { |
| 333 | sh_state.fun_(task_id, args...); |
| 334 | }; |
| 335 | |
| 336 | auto completion = [&](auto &...args) |
| 337 | { |
| 338 | STDEXEC::set_value(std::move(sh_state.rcvr_), std::move(args)...); |
| 339 | }; |
| 340 | |
| 341 | if constexpr (MayThrow) |
| 342 | { |
| 343 | STDEXEC_TRY |
| 344 | { |
| 345 | sh_state.apply(computation); |
| 346 | } |
| 347 | STDEXEC_CATCH_ALL |
| 348 | { |
| 349 | std::uint32_t expected = total_tasks; |
| 350 | |
| 351 | if (sh_state.task_with_exception_.compare_exchange_strong( |
| 352 | expected, |
| 353 | static_cast<std::uint32_t>(task_id), |
| 354 | STDEXEC::__std::memory_order_relaxed, |
| 355 | STDEXEC::__std::memory_order_relaxed)) |
| 356 | { |
| 357 | sh_state.exception_ = std::current_exception(); |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | bool const is_last_task = sh_state.finished_tasks_.fetch_add(1) == (total_tasks - 1); |
| 362 | |
| 363 | if (is_last_task) |
| 364 | { |
| 365 | if (sh_state.exception_) |
| 366 | { |
| 367 | STDEXEC::set_error(std::move(sh_state.rcvr_), std::move(sh_state.exception_)); |
| 368 | } |
| 369 | else |
| 370 | { |
| 371 | sh_state.apply(completion); |
| 372 | } |
| 373 | } |
| 374 | } |
| 375 | else |
| 376 | { |
| 377 | sh_state.apply(computation); |
nothing calls this directly
no test coverage detected