| 291 | }; |
| 292 | |
| 293 | struct __chunked_impl : __impl_base<bulk_chunked_t> |
| 294 | { |
| 295 | //! This implements the core default behavior for `bulk_chunked`: |
| 296 | //! When setting value, it calls the function with the entire range. |
| 297 | //! Note: This is not done in parallel. That is customized by the scheduler. |
| 298 | //! See, e.g., static_thread_pool::bulk_receiver::__t. |
| 299 | static constexpr auto __complete = |
| 300 | []<class _Tag, class _State, class... _Args>(__ignore, |
| 301 | _State& __state, |
| 302 | _Tag, |
| 303 | _Args&&... __args) noexcept -> void |
| 304 | { |
| 305 | if constexpr (__std::same_as<_Tag, set_value_t>) |
| 306 | { |
| 307 | // Intercept set_value and dispatch to the bulk operation. |
| 308 | using __shape_t = decltype(__state.__data_.__shape_); |
| 309 | using __fun_t = decltype(__state.__data_.__fun_); |
| 310 | constexpr bool __is_nothrow = __nothrow_callable<__fun_t, __shape_t, __shape_t, _Args...>; |
| 311 | STDEXEC_TRY |
| 312 | { |
| 313 | __state.__data_.__fun_(static_cast<__shape_t>(0), __state.__data_.__shape_, __args...); |
| 314 | _Tag()(static_cast<_State&&>(__state).__rcvr_, static_cast<_Args&&>(__args)...); |
| 315 | } |
| 316 | STDEXEC_CATCH_ALL |
| 317 | { |
| 318 | if constexpr (!__is_nothrow) |
| 319 | { |
| 320 | STDEXEC::set_error(static_cast<_State&&>(__state).__rcvr_, std::current_exception()); |
| 321 | } |
| 322 | } |
| 323 | } |
| 324 | else |
| 325 | { |
| 326 | _Tag()(static_cast<_State&&>(__state).__rcvr_, static_cast<_Args&&>(__args)...); |
| 327 | } |
| 328 | }; |
| 329 | }; |
| 330 | |
| 331 | struct __unchunked_impl : __impl_base<bulk_unchunked_t> |
| 332 | { |