30 #ifndef PT_GENERATOR_H
31 #define PT_GENERATOR_H
34 #include <Pt/Coroutine.h>
36 #if __cplusplus >= 202002L
50 { _result = std::move(v); }
53 {
return std::move(_result); }
56 GeneratorResult() =
default;
57 ~GeneratorResult() =
default;
59 GeneratorResult(
const GeneratorResult&) =
delete;
60 GeneratorResult& operator=(
const GeneratorResult&) =
delete;
70 class GeneratorResult<T&>
80 GeneratorResult() =
default;
81 ~GeneratorResult() =
default;
83 GeneratorResult(
const GeneratorResult&) =
delete;
84 GeneratorResult& operator=(
const GeneratorResult&) =
delete;
96 bool await_ready() const noexcept
100 std::coroutine_handle<> await_suspend(std::coroutine_handle<P> h) noexcept
102 PromiseBase* outer = h.promise()._outer;
104 if( outer && outer != &h.promise() )
105 outer->setFinished();
107 h.promise()._outer =
nullptr;
109 if( h.promise()._continuation )
110 return h.promise()._continuation;
112 return std::noop_coroutine();
115 void await_resume() noexcept
167 class Promise :
public GeneratorResult<T>
168 ,
public Pt::PromiseBase
171 std::exception_ptr _exception;
175 return Generator(std::coroutine_handle<Promise>::from_promise(*
this));
178 std::suspend_always initial_suspend() noexcept
181 FinalAwaiter final_suspend() noexcept
184 void unhandled_exception()
185 { _exception = std::current_exception(); }
187 void return_void() noexcept
191 AwaiterProxy<A> await_transform(A&& a)
194 return AwaiterProxy<A>{ std::forward<A>(a),
this };
197 YieldAwaiter yield_value(T
value) noexcept
199 this->set(std::forward<T>(
value));
204 using promise_type = Promise;
205 using handle_type = std::coroutine_handle<promise_type>;
222 : _generator(&generator)
223 , _handle(generator._handle)
231 if(_generator && _isPending)
232 _generator->detachAwaiter(*
this);
239 if( _handle && ! _handle.done() )
240 _handle.promise().cancel();
246 {
return ! _handle || _handle.done(); }
252 template<
typename FormP>
255 _generator->attachAwaiter(*
this);
258 if( _handle.promise()._outer )
259 throw std::logic_error(
"generator pending");
261 _handle.promise()._continuation = outer;
262 _handle.promise()._outer = &outer.promise();
272 if(_generator && _isPending)
274 _generator->detachAwaiter(*
this);
281 if (_handle.promise()._exception)
282 std::rethrow_exception(_handle.promise()._exception);
284 return ! _handle.done();
292 _generator =
nullptr;
312 : _handle(other._handle)
314 other._handle =
nullptr;
333 _awaiter->onDetach();
339 _handle.promise().cancel();
361 return _handle.promise().get();
365 void attachAwaiter(NextAwaiter& awaiter)
367 if(_awaiter && _awaiter != &awaiter)
368 throw std::logic_error(
"generator pending");
373 void detachAwaiter(NextAwaiter& awaiter)
375 if(_awaiter == &awaiter)
384 NextAwaiter* _awaiter =
nullptr;
389 #endif // __cplusplus >= 202002L
391 #endif // PT_GENERATOR_H