// ===== CodeLab: C++20 新特性:概念(concepts)、协程与 ranges 库 =====
// 来源: https://aoerliang.dpdns.org/articles/cpp20-features
// 以下代码片段按文章出现顺序拼接, 共 4 段

// ----- 片段 1 (cpp) -----
#include <concepts>
#include <iostream>
#include <string>

// 定义一个概念:Numeric = 整型或浮点型
template <typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;

// 用概念约束模板参数
template <Numeric T>
T add(T a, T b) {
    return a + b;
}

// 等价写法:requires 子句
template <typename T>
    requires Numeric<T>
T mul(T a, T b) {
    return a * b;
}

int main() {
    std::cout << add(1, 2) << std::endl;        // 3
    std::cout << mul(2.5, 4.0) << std::endl;    // 10
    // add(std::string("a"), std::string("b")); // 编译错误:不满足 Numeric
    return 0;
}

// ----- 片段 2 (cpp) -----
#include <coroutine>
#include <iostream>

// 极简生成器:惰性产出 T 类型序列
template <typename T>
struct Generator {
    struct promise_type {
        T current;
        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 {}; }
        void unhandled_exception() {}   // 真实代码应保存并重新抛出异常
        std::suspend_always yield_value(T v) {
            current = v;
            return {};
        }
        void return_void() {}
    };
    using handle = std::coroutine_handle<promise_type>;

    explicit Generator(handle h) : h_(h) {}
    ~Generator() { if (h_) h_.destroy(); }
    Generator(const Generator&) = delete;   // 不可拷贝

    bool next() {
        if (!h_ || h_.done()) return false;
        h_.resume();                 // 恢复执行到下一个挂起点
        return !h_.done();
    }
    T value() const { return h_.promise().current; }

private:
    handle h_;
};

// co_yield 让这个普通函数变成惰性序列
Generator<int> range(int n) {
    for (int i = 0; i < n; ++i) {
        co_yield i;   // 产出 i 并挂起
    }
}

int main() {
    auto gen = range(5);
    while (gen.next()) {
        std::cout << gen.value() << ' ';   // 输出 0 1 2 3 4
    }
    std::cout << std::endl;
    return 0;
}

// ----- 片段 3 (cpp) -----
#include <iostream>
#include <ranges>
#include <vector>

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};

    // 筛选偶数 -> 平方 -> 输出,全程无中间容器
    auto even_squares = v
        | std::views::filter([](int x) { return x % 2 == 0; })
        | std::views::transform([](int x) { return x * x; });

    for (int x : even_squares) {
        std::cout << x << ' ';   // 输出 4 16 36 64
    }
    std::cout << std::endl;

    int sum = 0;
    for (int x : even_squares) sum += x;
    std::cout << "sum = " << sum << std::endl;   // 120
    return 0;
}

// ----- 片段 4 (cpp) -----
# 编译并运行(GCC 建议 12+,协程支持较新)
g++ -std=c++20 main.cpp -o main
./main

# Clang 建议 16+,协程需配合 libc++
clang++ -std=c++20 -stdlib=libc++ main.cpp -o main
