Viewing file: pr95615.inc (2.75 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#if __has_include(<coroutine>) #include <coroutine> #else #include <experimental/coroutine> namespace std { using namespace std::experimental; } #endif #include <cassert> #include <cstdio> #include <cstdlib>
bool frame_live = false; bool promise_live = false; bool gro_live = false;
struct X {};
int Y_live = 0;
struct Y { Y () { std::puts("Y ()"); Y_live++; } Y (const Y&) { std::puts("Y (const Y&)"); Y_live++; } ~Y () { std::puts("~Y ()"); Y_live--; } };
struct task { struct promise_type { void* operator new(size_t sz) { std::puts("operator new()"); frame_live = true; return ::operator new(sz); }
void operator delete(void* p, size_t sz) { std::puts("operator delete"); frame_live = false; return ::operator delete(p, sz); }
promise_type() { std::puts("promise_type()"); #if PROMISE_CTOR_THROWS throw X{}; #endif promise_live = true; }
~promise_type() { std::puts("~promise_type()"); promise_live = false; }
struct awaiter { bool await_ready() { #if INITIAL_AWAIT_READY_THROWS throw X{}; #endif return false; } void await_suspend(std::coroutine_handle<>) { #if INITIAL_AWAIT_SUSPEND_THROWS throw X{}; #endif } void await_resume() { #if INITIAL_AWAIT_RESUME_THROWS // this would be caught by unhandled_exception () which is tested // elsewhere. throw X{}; #endif } };
awaiter initial_suspend() { #if INITIAL_SUSPEND_THROWS throw X{}; #endif return {}; }
task get_return_object() { std::puts("get_return_object()"); #if GET_RETURN_OBJECT_THROWS throw X{}; #endif bool gro_live = true; return task{}; }
std::suspend_never final_suspend() noexcept { return {}; } void return_void() noexcept {} void unhandled_exception() noexcept { std::puts("unhandled_exception()"); } };
task() { std::puts("task()"); } ~task() { std::puts("~task()"); } task(task&&) { std::puts("task(task&&)"); } };
task f(Y Val) { co_return; }
int main() { bool failed = false; Y Val; try { f(Val); } catch (X) { std::puts("caught X"); if (gro_live) std::puts("gro live"), failed = true; if (promise_live) std::puts("promise live"), failed = true; if (frame_live) std::puts("frame live"), failed = true; }
if (Y_live != 1) std::printf("Y live %d\n", Y_live), failed = true;
if (failed) abort() ; }
|