diff --git a/include/stdexec/__detail/__task.hpp b/include/stdexec/__detail/__task.hpp index 3e699e716..f489e0df3 100644 --- a/include/stdexec/__detail/__task.hpp +++ b/include/stdexec/__detail/__task.hpp @@ -132,9 +132,10 @@ namespace STDEXEC _Alloc(STDEXEC::get_allocator(STDEXEC::get_env(__has_env))); }; - template - concept __has_scheduler_compatible_with = requires(_EnvProvider const & __has_env) { - _Scheduler(STDEXEC::get_scheduler(STDEXEC::get_env(__has_env))); + template + concept __has_scheduler_compatible_with = requires(_EnvProvider const & __has_env, + _Alloc const &... __alloc) { + _Scheduler(STDEXEC::get_scheduler(STDEXEC::get_env(__has_env)), __alloc...); }; template @@ -299,9 +300,17 @@ namespace STDEXEC template [[nodiscard]] - static auto __mk_sched(_EnvProvider const & __has_env) noexcept -> scheduler_type + static auto __mk_sched(_EnvProvider const & __has_env, allocator_type const & __alloc) noexcept + -> scheduler_type { - if constexpr (__task::__has_scheduler_compatible_with<_EnvProvider, scheduler_type>) + // NOT TO SPEC: try constructing the scheduler with the allocator if possible. + if constexpr (__task::__has_scheduler_compatible_with<_EnvProvider, + scheduler_type, + allocator_type>) + { + return scheduler_type(get_scheduler(STDEXEC::get_env(__has_env)), __alloc); + } + else if constexpr (__task::__has_scheduler_compatible_with<_EnvProvider, scheduler_type>) { return scheduler_type(get_scheduler(STDEXEC::get_env(__has_env))); } @@ -350,7 +359,7 @@ namespace STDEXEC template constexpr explicit __opstate_base(task&& __task, _EnvProvider const & __has_env) noexcept : allocator_type(__mk_alloc(__has_env)) - , __sch_(__mk_sched(__has_env)) + , __sch_(__mk_sched(__has_env, __get_allocator())) , __task_(static_cast(__task)) { auto& __promise = __task_.__coro_.promise(); @@ -376,7 +385,7 @@ namespace STDEXEC virtual auto __canceled() noexcept -> __std::coroutine_handle<> = 0; [[nodiscard]] - constexpr auto __get_allocator() const noexcept -> allocator_type + constexpr auto __get_allocator() const noexcept -> allocator_type const & { return static_cast(*this); } diff --git a/include/stdexec/__detail/__task_scheduler.hpp b/include/stdexec/__detail/__task_scheduler.hpp index a8203aac3..cc9c2f7ce 100644 --- a/include/stdexec/__detail/__task_scheduler.hpp +++ b/include/stdexec/__detail/__task_scheduler.hpp @@ -598,13 +598,12 @@ namespace STDEXEC class __opstate : _Alloc { public: - using allocator_type = _Alloc; - using receiver_proxy = system_context_replaceability::receiver_proxy; - using __receiver_t = __detail::__proxy_receiver; + using __rcvr_proxy_t = system_context_replaceability::receiver_proxy; + using __receiver_t = __detail::__proxy_receiver<__rcvr_proxy_t, _Env>; constexpr explicit __opstate(_Alloc __alloc, _Sndr __sndr, - receiver_proxy& __rcvr, + __rcvr_proxy_t& __rcvr, bool __in_situ) : _Alloc(std::move(__alloc)) , __opstate_(STDEXEC::connect(std::move(__sndr),