10 template <
std::movable T>
15 return Generator{Handle::from_promise(*
this)};
17 static std::suspend_always initial_suspend()
noexcept {
return {}; }
18 static std::suspend_always final_suspend()
noexcept {
return {}; }
19 std::suspend_always yield_value(T value)
noexcept {
20 current_value = std::move(value);
24 void await_transform() =
delete;
25 [[
noreturn]]
static void unhandled_exception() {
throw; }
27 std::optional<T> current_value;
32 explicit Generator(
const Handle coroutine) : m_coroutine{coroutine} {}
34 Generator() =
default;
36 if(m_coroutine) m_coroutine.destroy();
42 Generator(
Generator&& other)
noexcept : m_coroutine{other.m_coroutine} {
43 other.m_coroutine = {};
47 if(m_coroutine) m_coroutine.destroy();
48 m_coroutine = other.m_coroutine;
49 other.m_coroutine = {};
57 void operator++() { m_coroutine.resume(); }
58 const T& operator*()
const {
return *m_coroutine.promise().current_value; }
59 bool operator==(std::default_sentinel_t)
const {
60 return !m_coroutine || m_coroutine.done();
63 explicit Iter(
const Handle coroutine) : m_coroutine{coroutine} {}
70 if(m_coroutine) m_coroutine.resume();
71 return Iter{m_coroutine};
74 std::default_sentinel_t end() {
return {}; }
80 template <std::integral T>
81 Generator<T> range(T first,
const T last) {
82 while(first < last)
co_yield first++;