141 lines
3.7 KiB
C++
141 lines
3.7 KiB
C++
|
#include <iostream>
|
||
|
#include <coroutine>
|
||
|
|
||
|
//���ſ���
|
||
|
//1.Э����Ҫ�����첽�������̡�
|
||
|
//2.Э�̱���������ͨ�������û���û���𣬲�ͬ�ĵط���Э��״̬���ڶ��Ϸ��������ǵ���ջ������������ʱ��ͣ������ִ�еĹ��ܡ�
|
||
|
//3.�������ڳ�����co_await��co_return��co_yield����һ������������Ϊ�ú�����Э�̺�����
|
||
|
|
||
|
//��ʹ�á�
|
||
|
//1.Э�飺Э�̺����������з���ֵ��
|
||
|
//2.Э�飺�������ͱ�����Ƕ promise_type ���͡�
|
||
|
//3.Э�飺��Ƕ�� promise_type ����ʵ�����ټ����ض���
|
||
|
// A.initial_suspend
|
||
|
// B.final_suspend
|
||
|
// C.unhandled_exception
|
||
|
// D.get_return_object
|
||
|
//4.���ã�co_return ����Э�̺����ķ���
|
||
|
// �������� void ����Ƕ�� promise_type ������ʵ��
|
||
|
// E.return_void
|
||
|
// ��������ֵ���� ����Ƕ�� promise_type ������ʵ��
|
||
|
// F.return_value(T&& t) noexcept
|
||
|
//5.���ã�co_yield ��ʵ�� co_await �ı�����
|
||
|
// co_yield exp --> co_await promise.yield_value(exp)
|
||
|
// co_yield ����Э��ͬʱ����һ��ֵ����Ƕ�� promise_type ������ʵ��
|
||
|
// G.yield_value
|
||
|
//6.���ã�co_await exp �����ܵõ�һ�� awaitable ������
|
||
|
// �������������ض�ʵ�ֵľ��� awaitable ������
|
||
|
// A.bool await_ready
|
||
|
// B.T await_resume
|
||
|
// C.void await_suspend(std::coroutine_handle<> handle)
|
||
|
|
||
|
//��������
|
||
|
// 1.���ȵ��� await_ready��������ֵ��
|
||
|
// 2. false --> ���� await_suspend ����Э�̣��β� handle ��ʾЭ�̶�������������Э�̡�
|
||
|
// true --> ���� await_resume ����ֵ��
|
||
|
// 3.��2���У��� false ����֮���Ե��� await_resume
|
||
|
|
||
|
template<typename T>
|
||
|
struct SimpleGenerator
|
||
|
{
|
||
|
struct promise_type;
|
||
|
using coroutine_handle = std::coroutine_handle<promise_type>;
|
||
|
|
||
|
// ��������״̬
|
||
|
enum class State { Ready, Done };
|
||
|
|
||
|
// ��������promise����
|
||
|
struct promise_type {
|
||
|
T value{};
|
||
|
State state = State::Ready;
|
||
|
|
||
|
//��Э�̿�ʼ��ʱ������
|
||
|
auto initial_suspend() const noexcept {
|
||
|
return std::suspend_always{};
|
||
|
}
|
||
|
|
||
|
//��Э�̽�����ʱ������
|
||
|
auto final_suspend() const noexcept {
|
||
|
return std::suspend_always{};
|
||
|
}
|
||
|
|
||
|
SimpleGenerator get_return_object() {
|
||
|
return SimpleGenerator{ coroutine_handle::from_promise(*this) };
|
||
|
}
|
||
|
|
||
|
void return_void() {}
|
||
|
|
||
|
auto yield_value(T val) noexcept {
|
||
|
value = val;
|
||
|
state = State::Ready;
|
||
|
return std::suspend_always{};
|
||
|
}
|
||
|
|
||
|
void unhandled_exception() {
|
||
|
std::terminate();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// ���캯��
|
||
|
SimpleGenerator(coroutine_handle handle) : coro(handle) {}
|
||
|
|
||
|
// ��ֹ�������ƶ�
|
||
|
SimpleGenerator(const SimpleGenerator&) = delete;
|
||
|
SimpleGenerator& operator=(const SimpleGenerator&) = delete;
|
||
|
|
||
|
SimpleGenerator(SimpleGenerator&& other) noexcept : coro(other.coro) {
|
||
|
other.coro = nullptr;
|
||
|
}
|
||
|
|
||
|
SimpleGenerator& operator=(SimpleGenerator&& other) noexcept {
|
||
|
if (this != &other) {
|
||
|
coro = other.coro;
|
||
|
other.coro = nullptr;
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
// ��������
|
||
|
~SimpleGenerator() {
|
||
|
if (coro)
|
||
|
coro.destroy();
|
||
|
}
|
||
|
|
||
|
// �����������Ƿ�����
|
||
|
bool done() const {
|
||
|
return coro && coro.done();
|
||
|
}
|
||
|
|
||
|
// ����������*���Ի�ȡ��ǰ��������ֵ
|
||
|
T& operator*() {
|
||
|
return coro.promise().value;
|
||
|
}
|
||
|
|
||
|
// ����++���������Լ�����������ִ��
|
||
|
void operator++() {
|
||
|
if (!done())
|
||
|
coro.resume();
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
coroutine_handle coro;
|
||
|
};
|
||
|
|
||
|
// һ��������������
|
||
|
SimpleGenerator<int> Counter(int start, int end) {
|
||
|
for (int i = start; i <= end; ++i) {
|
||
|
co_yield i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int main() {
|
||
|
auto gen = Counter(1, 5);
|
||
|
|
||
|
while (!gen.done()) {
|
||
|
std::cout << *gen << std::endl;
|
||
|
++gen;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|