// -*- C++ -*- //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11 // REQUIRES: fcoroutines-ts // RUN: %build -fcoroutines-ts // RUN: %run #include #include using namespace std::experimental; struct error {}; template struct expected { struct Data { T val; Error error; }; Data data; struct DataPtr { Data *p; ~DataPtr() { delete p; } }; expected() {} expected(T val) : data{std::move(val),{}} {} expected(struct error, Error error) : data{{}, std::move(error)} {} expected(DataPtr & p) : data{std::move(p.p->val), std::move(p.p->error)} {} struct promise_type { Data* data; DataPtr get_return_object() { data = new Data{}; return {data}; } suspend_never initial_suspend() { return {}; } suspend_never final_suspend() { return {}; } void return_value(T v) { data->val = std::move(v); data->error = {};} void unhandled_exception() {} }; bool await_ready() { return !data.error; } T await_resume() { return std::move(data.val); } void await_suspend(coroutine_handle h) { h.promise().data->error =std::move(data.error); h.destroy(); } T const& value() { return data.val; } Error const& error() { return data.error; } }; expected g() { return {0}; } expected h() { return {error{}, 42}; } extern "C" void print(int); bool f1_started, f1_resumed = false; expected f1() { f1_started = true; (void)(co_await g()); f1_resumed = true; co_return 100; } bool f2_started, f2_resumed = false; expected f2() { f2_started = true; (void)(co_await h()); f2_resumed = true; co_return 200; } int main() { auto c1 = f1(); assert(f1_started && f1_resumed); assert(c1.value() == 100); assert(c1.error() == 0); auto c2 = f2(); assert(f2_started && !f2_resumed); assert(c2.value() == 0); assert(c2.error() == 42); }