Created
August 2, 2020 08:18
-
-
Save anatoly-spb/279e0f8e19d9a191933319aed314febf to your computer and use it in GitHub Desktop.
co_yield
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace coyield | |
{ | |
template<typename T> | |
struct generator_type | |
{ | |
struct promise_type; | |
using coroutine_handle_type = stdco::coroutine_handle<promise_type>; | |
coroutine_handle_type handle; | |
generator_type(coroutine_handle_type handle) : handle{ handle } | |
{ | |
scope_tracer _{ __FUNCSIG__, this }; | |
} | |
generator_type(generator_type const&) = delete; | |
generator_type(generator_type&& other) noexcept : handle{ std::move(other.handle) } | |
{ | |
scope_tracer _{ __FUNCSIG__, this }; | |
other.handle = nullptr; | |
} | |
generator_type& operator = (generator_type const&) = delete; | |
generator_type& operator = (generator_type&& other) noexcept { | |
handle = other.handle; | |
other.handle = nullptr; | |
return *this; | |
} | |
~generator_type() | |
{ | |
scope_tracer _{ __FUNCSIG__, this }; | |
if (handle) handle.destroy(); | |
} | |
bool move_next() | |
{ | |
scope_tracer _{ __FUNCSIG__, this }; | |
_.info("Moving to next"); | |
handle.resume(); | |
_.info("Are we done?"); | |
auto still_going = not handle.done(); | |
_.info(still_going ? "There is another" : "We're done"); | |
return still_going; | |
} | |
T current_value() | |
{ | |
scope_tracer _{ __FUNCSIG__, this }; | |
return handle.promise().value; | |
} | |
struct promise_type { | |
T value; | |
promise_type() : value{ -1 } { | |
scope_tracer _{ __FUNCSIG__, this }; | |
} | |
promise_type(tracer param) : value{ } { | |
scope_tracer _{ __FUNCSIG__, this }; | |
} | |
~promise_type() { | |
scope_tracer _{ __FUNCSIG__, this }; | |
} | |
auto get_return_object() { | |
scope_tracer _{ __FUNCSIG__, this }; | |
_.info("return generator object"); | |
return generator_type<T>{coroutine_handle_type::from_promise(*this)}; | |
} | |
auto initial_suspend() { | |
scope_tracer _{ __FUNCSIG__, this }; | |
_.info("return suspend_always to suspend coroutine before enter into the body"); | |
return stdco::suspend_always{}; | |
} | |
void yield_value(T v) { | |
scope_tracer _{ __FUNCSIG__, this }; | |
_.info("yeild value to ", value = v); | |
} | |
auto final_suspend() noexcept { | |
scope_tracer _{ __FUNCSIG__, this }; | |
_.info("return suspend_always to suspend coroutine in final suspension point"); | |
return stdco::suspend_always{}; | |
} | |
void unhandled_exception() { | |
scope_tracer _{ __FUNCSIG__, this }; | |
std::terminate(); | |
} | |
void return_void() { | |
scope_tracer _{ __FUNCSIG__, this }; | |
_.info("return_void"); | |
} | |
}; // promise_type | |
}; // generator_type | |
generator_type<int> coroutine() | |
{ | |
scope_tracer _{ __FUNCSIG__ }; | |
_.info("co_yeild 1"); | |
co_yield 1; | |
_.info("co_yeild 2"); | |
co_yield 2; | |
_.info("we are done"); | |
} | |
void test() | |
{ | |
scope_tracer _{ __FUNCSIG__ }; | |
_.info("generator_type<int> g = coroutine();"); | |
generator_type<int> g = coroutine(); | |
_.info("while(g.move_next()) {"); | |
while (g.move_next()) { | |
_.info("g.current_value()"); | |
_.info(g.current_value()); | |
} | |
_.info("}"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16600 [00000000]>> void __cdecl coyield::test(void) | |
249400 [00000000] generator_type<int> g = coroutine(); | |
284800 [009A2E98] >> __thiscall coyield::generator_type<int>::promise_type::promise_type(void) | |
317600 [009A2E98] << __thiscall coyield::generator_type<int>::promise_type::promise_type(void) | |
346500 [009A2E98] >> auto __thiscall coyield::generator_type<int>::promise_type::get_return_object(void) | |
378100 [009A2E98] return generator object | |
411100 [002BFB34] >> __thiscall coyield::generator_type<int>::generator_type(struct std::experimental::coroutine_handle<struct coyie | |
ld::generator_type<int>::promise_type>) | |
439600 [002BFB34] << __thiscall coyield::generator_type<int>::generator_type(struct std::experimental::coroutine_handle<struct coyie | |
ld::generator_type<int>::promise_type>) | |
471200 [009A2E98] << auto __thiscall coyield::generator_type<int>::promise_type::get_return_object(void) | |
496800 [009A2E98] >> auto __thiscall coyield::generator_type<int>::promise_type::initial_suspend(void) | |
526500 [009A2E98] return suspend_always to suspend coroutine before enter into the body | |
556600 [009A2E98] << auto __thiscall coyield::generator_type<int>::promise_type::initial_suspend(void) | |
584600 [00000000] while(g.move_next()) { | |
627300 [002BFB34] >> bool __thiscall coyield::generator_type<int>::move_next(void) | |
657800 [002BFB34] Moving to next | |
691100 [00000000] >> struct coyield::generator_type<int> __cdecl coyield::coroutine(void) | |
724300 [00000000] co_yeild 1 | |
751900 [009A2E98] >> void __thiscall coyield::generator_type<int>::promise_type::yield_value(int) | |
781400 [009A2E98] yeild value to 1 | |
821800 [009A2E98] << void __thiscall coyield::generator_type<int>::promise_type::yield_value(int) | |
848700 [002BFB34] Are we done? | |
873000 [002BFB34] There is another | |
900000 [002BFB34] << bool __thiscall coyield::generator_type<int>::move_next(void) | |
931200 [00000000] g.current_value() | |
956500 [002BFB34] >> int __thiscall coyield::generator_type<int>::current_value(void) | |
984900 [002BFB34] << int __thiscall coyield::generator_type<int>::current_value(void) | |
1011900 [00000000] 1 | |
1036900 [002BFB34] >> bool __thiscall coyield::generator_type<int>::move_next(void) | |
1062000 [002BFB34] Moving to next | |
1084800 [00000000] co_yeild 2 | |
1107600 [009A2E98] >> void __thiscall coyield::generator_type<int>::promise_type::yield_value(int) | |
1133000 [009A2E98] yeild value to 2 | |
1176700 [009A2E98] << void __thiscall coyield::generator_type<int>::promise_type::yield_value(int) | |
1203800 [002BFB34] Are we done? | |
1226400 [002BFB34] There is another | |
1248700 [002BFB34] << bool __thiscall coyield::generator_type<int>::move_next(void) | |
1273700 [00000000] g.current_value() | |
1296200 [002BFB34] >> int __thiscall coyield::generator_type<int>::current_value(void) | |
1321500 [002BFB34] << int __thiscall coyield::generator_type<int>::current_value(void) | |
1346500 [00000000] 2 | |
1369700 [002BFB34] >> bool __thiscall coyield::generator_type<int>::move_next(void) | |
1394700 [002BFB34] Moving to next | |
1417200 [00000000] we are done | |
1440900 [00000000] << struct coyield::generator_type<int> __cdecl coyield::coroutine(void) | |
1466200 [009A2E98] >> void __thiscall coyield::generator_type<int>::promise_type::return_void(void) | |
1491100 [009A2E98] return_void | |
1513200 [009A2E98] << void __thiscall coyield::generator_type<int>::promise_type::return_void(void) | |
1538200 [009A2E98] >> auto __thiscall coyield::generator_type<int>::promise_type::final_suspend(void) noexcept | |
1563800 [009A2E98] return suspend_always to suspend coroutine in final suspension point | |
1590100 [009A2E98] << auto __thiscall coyield::generator_type<int>::promise_type::final_suspend(void) noexcept | |
1619900 [002BFB34] Are we done? | |
1642400 [002BFB34] We're done | |
1664500 [002BFB34] << bool __thiscall coyield::generator_type<int>::move_next(void) | |
1692700 [00000000] } | |
1716800 [002BFB34] >> __thiscall coyield::generator_type<int>::~generator_type(void) | |
1746400 [009A2E98] >> __thiscall coyield::generator_type<int>::promise_type::~promise_type(void) | |
1777300 [009A2E98] << __thiscall coyield::generator_type<int>::promise_type::~promise_type(void) | |
1810900 [002BFB34] << __thiscall coyield::generator_type<int>::~generator_type(void) | |
1837600 [00000000]<< void __cdecl coyield::test(void) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment