| 118 | |
| 119 | template <class _Child, class _Receiver> |
| 120 | struct __opstate final : __opstate_base<_Receiver> |
| 121 | { |
| 122 | using __receiver_t = __receiver<_Receiver>; |
| 123 | using __child_op_t = STDEXEC::connect_result_t<__bouncy_sndr_t<_Child>, __receiver_t>; |
| 124 | |
| 125 | constexpr explicit __opstate(std::size_t __count, _Child __child, _Receiver __rcvr) |
| 126 | noexcept(__nothrow_move_constructible<_Child> && __nothrow_connect<_Child, _Receiver>) |
| 127 | : __opstate_base<_Receiver>{static_cast<_Receiver &&>(__rcvr), __count} |
| 128 | , __child_(std::move(__child)) |
| 129 | { |
| 130 | if (this->__count_ != 0) |
| 131 | { |
| 132 | __connect(); |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | constexpr void start() noexcept |
| 137 | { |
| 138 | if (this->__count_ == 0) |
| 139 | { |
| 140 | STDEXEC::set_value(static_cast<_Receiver &&>(this->__rcvr_)); |
| 141 | } |
| 142 | else |
| 143 | { |
| 144 | STDEXEC::start(*__child_op_); |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | constexpr auto __connect() noexcept(__nothrow_connect<_Child, _Receiver>) -> __child_op_t & |
| 149 | { |
| 150 | return __child_op_.__emplace_from(STDEXEC::connect, |
| 151 | exec::sequence(STDEXEC::schedule(trampoline_scheduler{}), |
| 152 | __child_), |
| 153 | __receiver_t{this}); |
| 154 | } |
| 155 | |
| 156 | constexpr void __cleanup() noexcept final |
| 157 | { |
| 158 | __child_op_.reset(); |
| 159 | } |
| 160 | |
| 161 | constexpr void __repeat() noexcept final |
| 162 | { |
| 163 | STDEXEC_ASSERT(this->__count_ > 0); |
| 164 | STDEXEC_TRY |
| 165 | { |
| 166 | if (--this->__count_ == 0) |
| 167 | { |
| 168 | __cleanup(); |
| 169 | STDEXEC::set_value(std::move(this->__rcvr_)); |
| 170 | } |
| 171 | else |
| 172 | { |
| 173 | STDEXEC::start(__connect()); |
| 174 | } |
| 175 | } |
| 176 | STDEXEC_CATCH_ALL |
| 177 | { |