|
11 | 11 |
|
12 | 12 | #include <experimental/coroutine> |
13 | 13 | #include <cassert> |
| 14 | +#include <memory> |
14 | 15 |
|
15 | 16 | #include "test_macros.h" |
16 | 17 | using namespace std::experimental; |
17 | 18 |
|
18 | | -struct error {}; |
| 19 | +struct error_tag { }; |
19 | 20 |
|
20 | 21 | template <typename T, typename Error = int> |
21 | 22 | struct expected { |
22 | 23 |
|
23 | 24 | struct Data { |
| 25 | + Data() : val(), error() { } |
| 26 | + Data(T v, Error e) : val(v), error(e) { } |
24 | 27 | T val; |
25 | 28 | Error error; |
26 | 29 | }; |
27 | | - Data data; |
| 30 | + std::shared_ptr<Data> data; |
28 | 31 |
|
29 | | - struct DataPtr { |
30 | | - Data *p; |
31 | | - ~DataPtr() { delete p; } |
32 | | - }; |
33 | | - |
34 | | - expected() {} |
35 | | - expected(T val) : data{std::move(val),{}} {} |
36 | | - expected(struct error, Error error) : data{{}, std::move(error)} {} |
37 | | - expected(DataPtr & p) : data{std::move(p.p->val), std::move(p.p->error)} {} |
| 32 | + expected(T val) : data(std::make_shared<Data>(val, Error())) {} |
| 33 | + expected(error_tag, Error error) : data(std::make_shared<Data>(T(), error)) {} |
| 34 | + expected(std::shared_ptr<Data> p) : data(p) {} |
38 | 35 |
|
39 | 36 | struct promise_type { |
40 | | - Data* data; |
41 | | - DataPtr get_return_object() { data = new Data{}; return {data}; } |
| 37 | + std::shared_ptr<Data> data; |
| 38 | + std::shared_ptr<Data> get_return_object() { data = std::make_shared<Data>(); return data; } |
42 | 39 | suspend_never initial_suspend() { return {}; } |
43 | 40 | suspend_never final_suspend() noexcept { return {}; } |
44 | | - void return_value(T v) { data->val = std::move(v); data->error = {};} |
| 41 | + void return_value(T v) { data->val = v; data->error = {}; } |
45 | 42 | void unhandled_exception() {} |
46 | 43 | }; |
47 | 44 |
|
48 | | - bool await_ready() { return !data.error; } |
49 | | - T await_resume() { return std::move(data.val); } |
| 45 | + bool await_ready() { return !data->error; } |
| 46 | + T await_resume() { return data->val; } |
50 | 47 | void await_suspend(coroutine_handle<promise_type> h) { |
51 | | - h.promise().data->error =std::move(data.error); |
| 48 | + h.promise().data->error = data->error; |
52 | 49 | h.destroy(); |
53 | 50 | } |
54 | 51 |
|
55 | | - T const& value() { return data.val; } |
56 | | - Error const& error() { return data.error; } |
| 52 | + T const& value() { return data->val; } |
| 53 | + Error const& error() { return data->error; } |
57 | 54 | }; |
58 | 55 |
|
59 | 56 | expected<int> g() { return {0}; } |
60 | | -expected<int> h() { return {error{}, 42}; } |
| 57 | +expected<int> h() { return {error_tag{}, 42}; } |
61 | 58 |
|
62 | 59 | extern "C" void print(int); |
63 | 60 |
|
|
0 commit comments