#include #include #include #include #include void track(std::source_location l = std::source_location::current()) noexcept { fprintf(stderr, "%s:%u %s\n", l.file_name(), l.line(), l.function_name()); } struct awaitable // std::suspend_always carbon copy { awaitable() { track(); } ~awaitable() { track(); } constexpr bool await_ready() const noexcept { track(); return false; } constexpr void await_suspend(std::coroutine_handle<>) const noexcept { track();} constexpr void await_resume() const noexcept { track(); } }; struct fiber { struct promise_type // coroutine controller { promise_type() { track(); } ~promise_type() { track(); } fiber get_return_object() { track(); return handle_type::from_promise(*this);} awaitable initial_suspend() noexcept { track(); return {};} awaitable final_suspend() noexcept { track(); return {};} void return_void() { track(); } void unhandled_exception() { track(); std::terminate();} }; using handle_type = std::coroutine_handle; handle_type handle = nullptr; fiber(handle_type h): handle(h) { track(); } ~fiber() { track(); if (handle) handle.destroy();} }; fiber make_fiber() { for (auto i: {0, 1, 2, 3, 4}) { printf("%i ", i); co_await awaitable{}; } } int main() { auto t = make_fiber(); while (!t.handle.done()) t.handle.resume(); puts(""); }