summaryrefslogtreecommitdiff
path: root/test/std/experimental/language.support/support.coroutines/end.to.end/expected.pass.cpp
diff options
context:
space:
mode:
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.cpp89
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);
+}