diff options
Diffstat (limited to 'test/std/experimental/language.support/support.coroutines/end.to.end/expected.pass.cpp')
-rw-r--r-- | test/std/experimental/language.support/support.coroutines/end.to.end/expected.pass.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/test/std/experimental/language.support/support.coroutines/end.to.end/expected.pass.cpp b/test/std/experimental/language.support/support.coroutines/end.to.end/expected.pass.cpp new file mode 100644 index 000000000000..77070cc5a3b0 --- /dev/null +++ b/test/std/experimental/language.support/support.coroutines/end.to.end/expected.pass.cpp @@ -0,0 +1,89 @@ +// -*- 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 + +#include <experimental/coroutine> +#include <cassert> +using namespace std::experimental; + +struct error {}; + +template <typename T, typename Error = int> +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<promise_type> h) { + h.promise().data->error =std::move(data.error); + h.destroy(); + } + + T const& value() { return data.val; } + Error const& error() { return data.error; } +}; + +expected<int> g() { return {0}; } +expected<int> h() { return {error{}, 42}; } + +extern "C" void print(int); + +bool f1_started, f1_resumed = false; +expected<int> f1() { + f1_started = true; + (void)(co_await g()); + f1_resumed = true; + co_return 100; +} + +bool f2_started, f2_resumed = false; +expected<int> 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); +} |