]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/experimental/language.support/support.coroutines/end.to.end/bool_await_suspend.pass.cpp
Vendor import of libc++ trunk r351319 (just before the release_80
[FreeBSD/FreeBSD.git] / test / std / experimental / language.support / support.coroutines / end.to.end / bool_await_suspend.pass.cpp
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 // UNSUPPORTED: c++98, c++03, c++11
12
13 // See https://bugs.llvm.org/show_bug.cgi?id=33271
14 // UNSUPPORTED: ubsan
15
16 #include <experimental/coroutine>
17 #include <cassert>
18
19 using namespace std::experimental;
20
21 struct coro_t {
22   struct promise_type {
23     coro_t get_return_object() {
24       return coroutine_handle<promise_type>::from_promise(*this);
25     }
26     suspend_never initial_suspend() { return {}; }
27     suspend_never final_suspend() { return {}; }
28     void return_void() {}
29     void unhandled_exception() {}
30   };
31   coro_t(coroutine_handle<promise_type> hh) : h(hh) {}
32   coroutine_handle<promise_type> h;
33 };
34
35 struct NoSuspend {
36   bool await_ready() { return false; }
37   void await_resume() {}
38   template <typename F> bool await_suspend(F) { return false; }
39 };
40
41 struct DoSuspend {
42   bool await_ready() { return false; }
43   void await_resume() {}
44   template <typename F> bool await_suspend(F) { return true; }
45 };
46
47 bool f_started, f_resumed = false;
48 coro_t f() {
49   f_started = true;
50   co_await DoSuspend{};
51   f_resumed = true;
52 }
53
54 bool g_started, g_resumed = false;
55 coro_t g() {
56   g_started = true;
57   co_await NoSuspend{};
58   g_resumed = true;
59 }
60
61 int main() {
62   assert(!f_started && !f_resumed && !g_started && !g_resumed);
63   auto fret = f();
64   assert(f_started && !f_resumed);
65   fret.h.destroy();
66   assert(f_started && !f_resumed);
67   g();
68   assert(g_started && g_resumed);
69 }