There's also co_yield, which calls .yield_value(value) on the promise and co_await's the result. You can build generators with this, I guess,
and in fact C++ 23 comes with an std::generator<> type you can just use (or could, if your codebase was C++ 23+ only). On the inside, it's a type that you can return from a coroutine (and it has all of the promise_type things wired up); on the outside, it implements .begin(), .end(), and the C++ 20 range view stuff, so you can just iterate over it.