0 day streak
cpp / expert
Snippet

Stateful Iteration with C++20 Coroutine Generators

C++20 coroutines allow functions to suspend and resume execution. Using 'co_yield', a function can produce values lazily. This is highly efficient for large datasets as it avoids allocating full containers in memory.

snippet.cpp
cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <coroutine>
template<typename T>
struct Generator {
struct promise_type {
T current_value;
auto get_return_object() { return Generator{handle_type::from_promise(*this)}; }
auto initial_suspend() { return std::suspend_always{}; }
auto final_suspend() noexcept { return std::suspend_always{}; }
auto yield_value(T value) { current_value = value; return std::suspend_always{}; }
void return_void() {}
void unhandled_exception() { std::terminate(); }
};
using handle_type = std::coroutine_handle<promise_type>;
handle_type h;
bool next() { h.resume(); return !h.done(); }
T value() { return h.promise().current_value; }
~Generator() { h.destroy(); }
};
Generator<int> count(int start, int end) {
for (int i = start; i <= end; ++i) co_yield i;
}
int main() {
auto g = count(1, 3);
while (g.next()) std::cout << g.value() << " ";
return 0;
}
Breakdown
1
co_yield i;
Suspends the function and returns the current value to the caller.
2
struct promise_type
The internal protocol that defines how the coroutine behaves and stores state.