/
index.hxx
117 lines (91 loc) · 2.38 KB
/
index.hxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#ifndef HYPER_UTIL_ASYNC_H
#define HYPER_UTIL_ASYNC_H
#include <future>
#include <experimental/coroutine>
namespace Hyper {
namespace Util {
template<typename T> struct Async {
struct promise_type;
using handle_type = std::experimental::coroutine_handle<promise_type>;
handle_type coro;
Async(handle_type h) : coro(h) {}
Async(const Async &) = delete;
Async(Async &&s) : coro(s.coro) {
s.coro = nullptr;
}
~Async() {
if (coro) {
coro.destroy();
}
}
Async &operator = (const Async &) = delete;
Async &operator = (Async &&s) {
coro = s.coro;
s.coro = nullptr;
return *this;
}
T get() {
if (!this->coro.done()) {
this->coro.resume();
}
auto p = coro.promise();
return p.value;
}
auto operator co_await() {
struct awaitable_type {
handle_type coro;
bool await_ready() {
const auto ready = coro.done();
return coro.done();
}
void await_suspend(std::experimental::coroutine_handle<> awaiting) {
coro.resume();
awaiting.resume();
}
auto await_resume() {
const auto r = coro.promise().value;
return r;
}
};
return awaitable_type{coro};
}
struct promise_type {
T value;
promise_type() {}
~promise_type() {}
auto get_return_object() {
return Async<T>{handle_type::from_promise(*this)};
}
// lazy, not lazy
auto initial_suspend() {
// return std::experimental::suspend_never{};
return std::experimental::suspend_always{};
}
auto return_value(T v) {
value = v;
return std::experimental::suspend_never{};
}
auto final_suspend() {
return std::experimental::suspend_always{};
}
void unhandled_exception() {
std::exit(1);
}
};
};
template<typename T> struct Promise {
std::promise<T> p;
std::shared_future<T> f;
T await () {
return f.get();
}
void resolve (T val) {
p.set_value(val);
}
Promise () {
this->f = p.get_future();
}
};
} // namespace Util
} // namespace Hypercore
#endif