All Recipes
Home/Coroutines/Generator Coroutines
intermediate

Generator Coroutines

Create lazy sequences using coroutines

Example Code

cpp
#include <coroutine>
#include <iostream>
#include <optional>
// Simple generator type
template<typename T>
struct Generator {
struct promise_type {
T current_value;
Generator get_return_object() {
return Generator{
std::coroutine_handle<promise_type>::from_promise(*this)
};
}
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
std::suspend_always yield_value(T value) {
current_value = value;
return {};
}
void return_void() {}
void unhandled_exception() { std::terminate(); }
};
std::coroutine_handle<promise_type> handle;
Generator(std::coroutine_handle<promise_type> h) : handle(h) {}
~Generator() { if (handle) handle.destroy(); }
// Iterator interface
struct iterator {
std::coroutine_handle<promise_type> handle;
void operator++() { handle.resume(); }
T operator*() { return handle.promise().current_value; }
bool operator!=(std::default_sentinel_t) {
return !handle.done();
}
};
iterator begin() { handle.resume(); return {handle}; }
std::default_sentinel_t end() { return {}; }
};
// Coroutine that generates Fibonacci numbers
Generator<int> fibonacci(int count) {
int a = 0, b = 1;
for (int i = 0; i < count; ++i) {
co_yield a;
auto next = a + b;
a = b;
b = next;
}
}
int main() {
std::cout << "Fibonacci: ";
for (int n : fibonacci(10)) {
std::cout << n << " ";
}
std::cout << std::endl;
return 0;
}

Explanation

Coroutines enable lazy evaluation through generators. The co_yield keyword suspends execution and returns a value. The coroutine resumes when the next value is requested.

Key Points

  • 1co_yield suspends and returns a value
  • 2Promise type controls coroutine behavior
  • 3Generators are lazy - values computed on demand
  • 4Useful for sequences and streams