1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 
11 // <coroutine>
12 
13 // template <class Promise>
14 // struct coroutine_handle<Promise>;
15 
16 // Promise& promise() const
17 
18 #include <coroutine>
19 #include <type_traits>
20 #include <memory>
21 #include <utility>
22 #include <cstdint>
23 #include <cassert>
24 
25 #include "test_macros.h"
26 
27 struct MyCoro {
28   struct promise_type {
unhandled_exceptionMyCoro::promise_type29     void unhandled_exception() {}
return_voidMyCoro::promise_type30     void return_void() {}
initial_suspendMyCoro::promise_type31     std::suspend_never initial_suspend() { return {}; }
final_suspendMyCoro::promise_type32     std::suspend_never final_suspend() noexcept { return {}; }
get_return_objectMyCoro::promise_type33     MyCoro get_return_object() {
34       do_runtime_test();
35       return {};
36     }
do_runtime_testMyCoro::promise_type37     void do_runtime_test() {
38       // Test that a coroutine_handle<const T> can be created from a const
39       // promise_type and that it represents the same coroutine as
40       // coroutine_handle<T>
41       using CH = std::coroutine_handle<promise_type>;
42       using CCH = std::coroutine_handle<const promise_type>;
43       const auto &cthis = *this;
44       CH h = CH::from_promise(*this);
45       CCH h2 = CCH::from_promise(*this);
46       CCH h3 = CCH::from_promise(cthis);
47       assert(&h.promise() == this);
48       assert(&h2.promise() == this);
49       assert(&h3.promise() == this);
50       assert(h.address() == h2.address());
51       assert(h2.address() == h3.address());
52     }
53   };
54 };
55 
do_runtime_test()56 MyCoro do_runtime_test() {
57   co_await std::suspend_never{};
58 }
59 
60 template <class Promise>
do_test(std::coroutine_handle<Promise> && H)61 void do_test(std::coroutine_handle<Promise>&& H) {
62 
63   // FIXME Add a runtime test
64   {
65     ASSERT_SAME_TYPE(decltype(H.promise()), Promise&);
66     LIBCPP_ASSERT_NOT_NOEXCEPT(H.promise());
67   }
68   {
69     auto const& CH = H;
70     ASSERT_SAME_TYPE(decltype(CH.promise()), Promise&);
71     LIBCPP_ASSERT_NOT_NOEXCEPT(CH.promise());
72   }
73 }
74 
main(int,char **)75 int main(int, char**)
76 {
77   do_test(std::coroutine_handle<int>{});
78   do_test(std::coroutine_handle<const int>{});
79   do_runtime_test();
80 
81   return 0;
82 }
83