@@ -394,10 +394,13 @@ namespace STDEXEC
394394
395395 struct __opstate_base : private allocator_type
396396 {
397- template <class _Env >
398- constexpr explicit __opstate_base (task&& __task, _Env const & __env) noexcept
397+ template <class _Env , class _OwnEnv >
398+ constexpr explicit __opstate_base (task&& __task,
399+ _Env const & __env,
400+ _OwnEnv const & __own_env) noexcept
399401 : allocator_type(__mk_alloc(__env))
400402 , __sch_(__mk_sched(__env, __get_allocator()))
403+ , __env_(__mk_env(__env, __own_env))
401404 , __task_(static_cast <task&&>(__task))
402405 {
403406 auto & __promise = __task_.__coro_ .promise ();
@@ -434,19 +437,26 @@ namespace STDEXEC
434437 }
435438
436439 start_scheduler_type __sch_;
440+ _TaskEnv __env_;
437441 task __task_;
438442 __error_variant_t __errors_{__no_init};
439443 };
440444
445+ template <class _Env >
446+ struct __own_env_box
447+ {
448+ __own_env_t <_Env> __own_env_;
449+ };
450+
441451 template <class _ParentPromise >
442452 struct STDEXEC_ATTRIBUTE (empty_bases) __awaiter final
443- : __opstate_base
453+ : __own_env_box<env_of_t <_ParentPromise>>
454+ , __opstate_base
444455 , __stop_callback_box_t <env_of_t <_ParentPromise>>
445456 {
446457 constexpr explicit __awaiter (task&& __task, _ParentPromise& __parent) noexcept
447- : __opstate_base (static_cast <task&&>(__task), STDEXEC::get_env (__parent))
448- , __own_env_ (__mk_own_env (STDEXEC::get_env (__parent)))
449- , __env_ (__mk_env (STDEXEC::get_env (__parent), __own_env_))
458+ : __awaiter::__own_env_box{__mk_own_env (STDEXEC::get_env (__parent))}
459+ , __opstate_base (static_cast <task&&>(__task), STDEXEC::get_env (__parent), this ->__own_env_ )
450460 , __parent_ (__parent)
451461 {}
452462
@@ -501,10 +511,8 @@ namespace STDEXEC
501511 return __parent_.unhandled_stopped ();
502512 }
503513
504- __own_env_t <_ParentPromise> __own_env_;
505- _TaskEnv __env_;
506- __std::coroutine_handle<> __continuation_;
507- _ParentPromise& __parent_;
514+ __std::coroutine_handle<> __continuation_;
515+ _ParentPromise& __parent_;
508516 };
509517
510518 struct __attrs
@@ -542,21 +550,23 @@ namespace STDEXEC
542550
543551 // //////////////////////////////////////////////////////////////////////////////////////
544552 // task<T,E>::__opstate
545- template <class _Ty , class _Env >
553+ template <class _Ty , class _TaskEnv >
546554 template <class _Rcvr >
547- struct STDEXEC_ATTRIBUTE (empty_bases) task<_Ty, _Env >::__opstate final
555+ struct STDEXEC_ATTRIBUTE (empty_bases) task<_Ty, _TaskEnv >::__opstate final
548556 : __rcvr_box<_Rcvr> // holds the receiver so that we can pass __opstate_base a reference to it
549- , __opstate_base
557+ , __own_env_box< env_of_t <_Rcvr>>
550558 , __stop_callback_box_t <env_of_t <_Rcvr>>
559+ , __opstate_base
551560 {
552561 public:
553562 using operation_state_concept = operation_state_tag;
554563
555564 explicit __opstate (task&& __task, _Rcvr&& __rcvr) noexcept
556565 : __rcvr_box<_Rcvr>{static_cast <_Rcvr&&>(__rcvr)}
557- , __opstate_base (static_cast <task&&>(__task), STDEXEC::get_env (this ->__rcvr_ ))
558- , __own_env_ (__mk_own_env (STDEXEC::get_env (this ->__rcvr_ )))
559- , __env_ (__mk_env (STDEXEC::get_env (this ->__rcvr_ ), __own_env_))
566+ , __opstate::__own_env_box{__mk_own_env (STDEXEC::get_env (this ->__rcvr_ ))}
567+ , __opstate_base (static_cast <task&&>(__task),
568+ STDEXEC::get_env (this ->__rcvr_ ),
569+ this ->__own_env_ )
560570 {}
561571
562572 void start () & noexcept
@@ -634,15 +644,12 @@ namespace STDEXEC
634644 STDEXEC::set_stopped (static_cast <_Rcvr&&>(this ->__rcvr_ ));
635645 return std::noop_coroutine ();
636646 }
637-
638- __own_env_t <_Rcvr> __own_env_;
639- _Env __env_;
640647 };
641648
642649 // //////////////////////////////////////////////////////////////////////////////////////
643650 // task<T,E>::promise_type
644- template <class _Ty , class _Env >
645- struct task <_Ty, _Env >::__promise : __task::__promise_base<_Ty>
651+ template <class _Ty , class _TaskEnv >
652+ struct task <_Ty, _TaskEnv >::__promise : __task::__promise_base<_Ty>
646653 {
647654 __promise () noexcept = default ;
648655
@@ -814,6 +821,16 @@ namespace STDEXEC
814821 }
815822 }
816823
824+ template <__forwarding_query _Query, class ... _Args>
825+ requires __queryable_with<_TaskEnv, _Query, _Args...>
826+ [[nodiscard]]
827+ constexpr auto query (_Query __tag, _Args&&... __args) const
828+ noexcept (__nothrow_queryable_with<_TaskEnv, _Query, _Args...>)
829+ -> __query_result_t<_TaskEnv, _Query, _Args...>
830+ {
831+ return __query<_Query>()(__promise_->__state_ ->__env_ , static_cast <_Args&&>(__args)...);
832+ }
833+
817834 __promise const * __promise_;
818835 };
819836
0 commit comments