@@ -590,15 +590,27 @@ namespace exec {
590590 struct __future_state : __future_state_base<__future_completions_t <_Sender, _Env>, _Env> {
591591 using _Completions = __future_completions_t <_Sender, _Env>;
592592
593- __future_state (_Sender __sndr, _Env __env, const __impl* __scope)
593+ __future_state (connect_t , _Sender&& __sndr, _Env __env, const __impl* __scope)
594594 : __future_state_base<_Completions, _Env>(static_cast <_Env&&>(__env), __scope)
595- , __op_(
596- stdexec::connect (
597- static_cast <_Sender&&>(__sndr),
598- __future_receiver_t <_Sender, _Env>{this , __scope})) {
595+ , __op_(static_cast <_Sender&&>(__sndr), __future_receiver_t <_Sender, _Env>{this , __scope}) {
599596 }
600597
601- connect_result_t <_Sender, __future_receiver_t <_Sender, _Env>> __op_;
598+ __future_state (_Sender __sndr, _Env __env, const __impl* __scope)
599+ : __future_state(
600+ connect,
601+ static_cast <_Sender&&>(__sndr),
602+ static_cast <_Env&&>(__env),
603+ __scope) {
604+ // If the operation completes synchronously, then the following line will cause
605+ // the destruction of *this, which is not a problem because we used a delegating
606+ // constructor, so *this is considered fully constructed.
607+ __op_.submit (
608+ static_cast <_Sender&&>(__sndr), __future_receiver_t <_Sender, _Env>{this , __scope});
609+ }
610+
611+ STDEXEC_ATTRIBUTE ((no_unique_address)) [[]] //
612+ submit_result<_Sender, __future_receiver_t <_Sender, _Env>>
613+ __op_{};
602614 };
603615
604616 template <class _SenderId , class _EnvId >
@@ -729,21 +741,26 @@ namespace exec {
729741 using _Sender = stdexec::__t <_SenderId>;
730742
731743 struct __t : __spawn_op_base<_EnvId> {
732- template <__decays_to<_Sender> _Sndr>
733- __t (_Sndr&& __sndr, _Env __env, const __impl* __scope)
744+ __t (connect_t , _Sender&& __sndr, _Env __env, const __impl* __scope)
734745 : __spawn_op_base<_EnvId>{__env::__join (static_cast <_Env&&>(__env),
735746 __spawn_env_{__scope->__stop_source_ .get_token ()}),
736747 [](__spawn_op_base<_EnvId>* __op) {
737748 delete static_cast <__t *>(__op);
738749 }}
739- , __op_(stdexec::connect( static_cast <_Sndr &&>(__sndr), __spawn_receiver_t <_Env>{this }) ) {
750+ , __data_( static_cast <_Sender &&>(__sndr), __spawn_receiver_t <_Env>{this }) {
740751 }
741752
742- void start () & noexcept {
743- stdexec::start (__op_);
753+ __t (_Sender __sndr, _Env __env, const __impl* __scope)
754+ : __t (connect, static_cast <_Sender&&>(__sndr), static_cast <_Env&&>(__env), __scope) {
755+ // If the operation completes synchronously, then the following line will cause
756+ // the destruction of *this, which is not a problem because we used a delegating
757+ // constructor, so *this is considered fully constructed.
758+ __data_.submit (static_cast <_Sender&&>(__sndr), __spawn_receiver_t <_Env>{this });
744759 }
745760
746- connect_result_t <_Sender, __spawn_receiver_t <_Env>> __op_;
761+ STDEXEC_ATTRIBUTE ((no_unique_address)) [[]] //
762+ submit_result<_Sender, __spawn_receiver_t <_Env>>
763+ __data_;
747764 };
748765 };
749766
@@ -779,19 +796,18 @@ namespace exec {
779796 requires sender_to<nest_result_t <_Sender>, __spawn_receiver_t <_Env>>
780797 void spawn (_Sender&& __sndr, _Env __env = {}) {
781798 using __op_t = __spawn_operation_t <nest_result_t <_Sender>, _Env>;
782- // start is noexcept so we can assume that the operation will complete
783- // after this, which means we can rely on its self-ownership to ensure
784- // that it is eventually deleted
785- stdexec::start (*(
786- new __op_t {nest (static_cast <_Sender&&>(__sndr)), static_cast <_Env&&>(__env), &__impl_})) ;
799+ // this will connect and start the operation, after which the operation state is
800+ // responsible for deleting itself after it completes.
801+ [[maybe_unused]]
802+ auto * __op =
803+ new __op_t {nest (static_cast <_Sender&&>(__sndr)), static_cast <_Env&&>(__env), &__impl_};
787804 }
788805
789806 template <__movable_value _Env = env<>, sender_in<__env_t <_Env>> _Sender>
790807 auto spawn_future (_Sender&& __sndr, _Env __env = {}) -> __future_t<_Sender, _Env> {
791808 using __state_t = __future_state<nest_result_t <_Sender>, _Env>;
792809 auto __state = std::make_unique<__state_t >(
793810 nest (static_cast <_Sender&&>(__sndr)), static_cast <_Env&&>(__env), &__impl_);
794- stdexec::start (__state->__op_ );
795811 return __future_t <_Sender, _Env>{std::move (__state)};
796812 }
797813
0 commit comments