编译运行:clang++ -std=c++26 -Wall -Wextra -pthread 测试_第29章_协程.cpp -o t && ./t(需先 cd 测试/)
// 第29章测试:协程与异步(生成器实现 + 验证)
// 编译需要 -fcoroutines-ts 或 C++20 原生协程支持
#include <print>
#include <coroutine>
#include <cstdint>
#include <exception>
#include <vector>
#include <cmath>
int failures = 0;
#define CHECK(expr) \
do { \
if (!(expr)) { \
++failures; \
std::println("FAIL 第{}行: {}", __LINE__, #expr); \
} \
} while (0)
// 29.3 最小生成器框架(教材级)
template <typename T>
class Generator {
public:
struct promise_type;
using handle = std::coroutine_handle<promise_type>;
struct promise_type {
T current;
struct FinalAwaiter {
bool await_ready() const noexcept { return false; }
void await_suspend(handle) const noexcept {}
void await_resume() const noexcept {}
};
Generator get_return_object() { return Generator{handle::from_promise(*this)}; }
std::suspend_always initial_suspend() const noexcept { return {}; }
FinalAwaiter final_suspend() const noexcept { return {}; }
void return_void() const noexcept {}
void unhandled_exception() { std::terminate(); } // 异常处理(教材简化)
std::suspend_always yield_value(T value) {
current = std::move(value);
return {};
}
};
struct Iterator {
handle h;
bool operator!=(const Iterator&) const noexcept { return !h.done(); }
void operator++() { h.resume(); }
T& operator*() { return h.promise().current; }
};
Iterator begin() { h.resume(); return {h}; }
Iterator end() { return {handle{}}; }
Generator(Generator&& o) noexcept : h(o.h) { o.h = nullptr; }
~Generator() { if (h) h.destroy(); }
private:
explicit Generator(handle h) : h(h) {}
handle h;
};
// 29.2 生成器:区间
Generator<int> range(int from, int to) {
for (int i = from; i < to; ++i)
co_yield i;
}
// 29.4 无限斐波那契生成器
Generator<unsigned long long> fibonacci() {
unsigned long long a = 0, b = 1;
while (true) {
co_yield a;
unsigned long long t = a + b;
a = b; b = t;
}
}
// 练习3:质数生成器(朴素判定)
Generator<int> primes() {
co_yield 2;
for (int n = 3; ; n += 2) {
bool ok = true;
for (int d = 3; d * d <= n; d += 2)
if (n % d == 0) { ok = false; break; }
if (ok) co_yield n;
}
}
// 练习4:平方生成器
Generator<long long> squares(int n) {
for (int i = 1; i <= n; ++i)
co_yield (long long)i * i;
}
int main() {
// 29.2 基础生成器
std::vector<int> got;
for (int x : range(0, 5)) got.push_back(x);
CHECK((got == std::vector<int>{0, 1, 2, 3, 4}));
// 29.4 无限斐波那契(惰性:只取前 10 个)
std::vector<unsigned long long> fibs;
for (auto v : fibonacci()) {
if (fibs.size() >= 10) break;
fibs.push_back(v);
}
CHECK(fibs.size() == 10);
CHECK(fibs[0] == 0 && fibs[1] == 1 && fibs[2] == 1);
CHECK(fibs[9] == 34);
// 惰性验证:无限序列只算需要的部分(上面已证明)
// 生成器内存 O(1):连续取 1 亿个也不占内存(概念验证,
// 这里取 10 万说明遍历可行)
std::size_t count = 0;
for (auto v : fibonacci()) {
(void)v;
if (++count >= 100'000) break;
}
CHECK(count == 100'000);
// 练习3:前 10 个质数
std::vector<int> ps;
for (int p : primes()) {
ps.push_back(p);
if (ps.size() >= 10) break;
}
CHECK((ps == std::vector<int>{2, 3, 5, 7, 11, 13, 17, 19, 23, 29}));
// 练习4:平方生成器
std::vector<long long> sq;
for (auto v : squares(5)) sq.push_back(v);
CHECK((sq == std::vector<long long>{1, 4, 9, 16, 25}));
// 生成器与算法配合:求和
long long total = 0;
for (auto v : range(1, 101)) total += v;
CHECK(total == 5050);
if (failures == 0) std::println("全部通过");
return failures;
}