@@ -98,7 +98,8 @@ namespace exec {
9898 // / The execution domain of the parallel_scheduler, used for the purposes of customizing
9999 // / sender algorithms such as `bulk_chunked` and `bulk_unchunked`.
100100 struct __parallel_scheduler_domain : stdexec::default_domain {
101- // / Schedules new bulk chunked work.
101+ template <__bulk_chunked_or_unchunked _Sender>
102+ auto transform_sender (_Sender&& __sndr) const noexcept ;
102103 template <__bulk_chunked_or_unchunked _Sender, class _Env >
103104 auto transform_sender (_Sender&& __sndr, const _Env& __env) const noexcept ;
104105 };
@@ -374,9 +375,16 @@ namespace exec {
374375 auto __state = reinterpret_cast <_BulkState*>(this );
375376 if constexpr (_BulkState::__is_unchunked) {
376377 (void ) __end; // not used
377- std::apply (
378- [&](auto &&... __args) { __state->__fun_ (__begin, __args...); },
379- *reinterpret_cast <std::tuple<_As...>*>(__base_t ::__arguments_data_));
378+ // If we are not parallelizing, we need to run all the iterations sequentially.
379+ uint32_t __increments = 1 ;
380+ if constexpr (!_BulkState::__parallelize) {
381+ __increments = __state->__size_ ;
382+ }
383+ for (uint32_t __i = __begin; __i < __begin + __increments; __i++) {
384+ std::apply (
385+ [&](auto &&... __args) { __state->__fun_ (__i, __args...); },
386+ *reinterpret_cast <std::tuple<_As...>*>(__base_t ::__arguments_data_));
387+ }
380388 } else {
381389 // If we are not parallelizing, we need to pass the entire range to the functor.
382390 if constexpr (!_BulkState::__parallelize) {
@@ -464,7 +472,8 @@ namespace exec {
464472 // Schedule the bulk work on the system scheduler.
465473 // This will invoke `execute` on our receiver multiple times, and then a completion signal (e.g., `set_value`).
466474 if constexpr (_BulkState::__is_unchunked) {
467- __scheduler->schedule_bulk_unchunked (__size, __storage, *__r);
475+ __scheduler
476+ ->schedule_bulk_unchunked (_BulkState::__parallelize ? __size : 1 , __storage, *__r);
468477 } else {
469478 __scheduler
470479 ->schedule_bulk_chunked (_BulkState::__parallelize ? __size : 1 , __storage, *__r);
@@ -677,9 +686,17 @@ namespace exec {
677686 template <class _Data , class _Previous >
678687 auto
679688 operator ()(stdexec::bulk_unchunked_t , _Data&& __data, _Previous&& __previous) const noexcept {
680- auto [__unused_pol, __shape, __fn] = static_cast <_Data&&>(__data);
681- return __parallel_bulk_sender<true , _Previous, decltype (__shape), decltype (__fn), true >{
682- __sched_, static_cast <_Previous&&>(__previous), __shape, std::move (__fn)};
689+ auto [__pol, __shape, __fn] = static_cast <_Data&&>(__data);
690+ using __policy_t = std::remove_cvref_t <decltype (__pol.__get ())>;
691+ constexpr bool __parallelize = std::same_as<__policy_t , stdexec::parallel_policy>
692+ || std::same_as<__policy_t , stdexec::parallel_unsequenced_policy>;
693+ return __parallel_bulk_sender<
694+ true ,
695+ _Previous,
696+ decltype (__shape),
697+ decltype (__fn),
698+ __parallelize
699+ >{__sched_, static_cast <_Previous&&>(__previous), __shape, std::move (__fn)};
683700 }
684701
685702 parallel_scheduler __sched_;
@@ -690,6 +707,22 @@ namespace exec {
690707 using sender_concept = stdexec::sender_t ;
691708 };
692709
710+ template <__bulk_chunked_or_unchunked _Sender>
711+ auto __parallel_scheduler_domain::transform_sender (_Sender&& __sndr)
712+ const noexcept {
713+ if constexpr (stdexec::__completes_on<_Sender, parallel_scheduler>) {
714+ auto __sched = stdexec::get_completion_scheduler<stdexec::set_value_t >(
715+ stdexec::get_env (__sndr));
716+ return stdexec::__sexpr_apply (
717+ static_cast <_Sender&&>(__sndr), __transform_parallel_bulk_sender{__sched});
718+ } else {
719+ static_assert (
720+ stdexec::__completes_on<_Sender, parallel_scheduler>,
721+ " No parallel_scheduler instance can be found in the sender's "
722+ " environment on which to schedule bulk work." );
723+ return __not_a_sender<stdexec::__name_of<_Sender>>();
724+ }
725+ }
693726 template <__bulk_chunked_or_unchunked _Sender, class _Env >
694727 auto __parallel_scheduler_domain::transform_sender (_Sender&& __sndr, const _Env& __env)
695728 const noexcept {
0 commit comments