| 329 | }; |
| 330 | |
| 331 | struct __unchunked_impl : __impl_base<bulk_unchunked_t> |
| 332 | { |
| 333 | //! This implements the core default behavior for `bulk_unchunked`: |
| 334 | //! When setting value, it loops over the shape and invokes the function. |
| 335 | //! Note: This is not done in concurrently. That is customized by the scheduler. |
| 336 | static constexpr auto __complete = |
| 337 | []<class _Tag, class _State, class... _Args>(__ignore, |
| 338 | _State& __state, |
| 339 | _Tag, |
| 340 | _Args&&... __args) noexcept -> void |
| 341 | { |
| 342 | if constexpr (__std::same_as<_Tag, set_value_t>) |
| 343 | { |
| 344 | using __shape_t = decltype(__state.__data_.__shape_); |
| 345 | using __fun_t = decltype(__state.__data_.__fun_); |
| 346 | constexpr bool __is_nothrow = __nothrow_callable<__fun_t, __shape_t, _Args...>; |
| 347 | auto const __shape = __state.__data_.__shape_; |
| 348 | STDEXEC_TRY |
| 349 | { |
| 350 | for (__shape_t __i{}; __i != __shape; ++__i) |
| 351 | { |
| 352 | __state.__data_.__fun_(__i, __args...); |
| 353 | } |
| 354 | _Tag()(static_cast<_State&&>(__state).__rcvr_, static_cast<_Args&&>(__args)...); |
| 355 | } |
| 356 | STDEXEC_CATCH_ALL |
| 357 | { |
| 358 | if constexpr (!__is_nothrow) |
| 359 | { |
| 360 | STDEXEC::set_error(static_cast<_State&&>(__state).__rcvr_, std::current_exception()); |
| 361 | } |
| 362 | } |
| 363 | } |
| 364 | else |
| 365 | { |
| 366 | _Tag()(static_cast<_State&&>(__state).__rcvr_, static_cast<_Args&&>(__args)...); |
| 367 | } |
| 368 | }; |
| 369 | }; |
| 370 | |
| 371 | struct __impl : __impl_base<bulk_t> |
| 372 | { |