source: doc/papers/concurrency/examples/Format.cpp@ 13b1b1d

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum stuck-waitfor-destruct
Last change on this file since 13b1b1d was 13b1b1d, checked in by tdelisle <tdelisle@…>, 7 years ago

C++ Format coroutine now "properly" destroys itself

  • Property mode set to 100644
File size: 1.9 KB
Line 
1
2#include "base.hpp"
3
4struct fmt_cor {
5 struct promise_type {
6 char _value;
7 struct locals {
8 int g, b;
9 } * _l;
10
11 fmt_cor get_return_object() {
12 return fmt_cor(std::experimental::coroutine_handle<promise_type>::from_promise(*this));
13 }
14
15 auto initial_suspend() { return suspend_never(); }
16 auto final_suspend() { return suspend_always(); }
17
18 void return_void() {}
19 void unhandled_exception() {}
20
21 auto yield_value(locals & l) {
22 _l = &l;
23 return suspend_never();
24 }
25 };
26
27 struct get {
28 promise_type * _promise = nullptr;
29
30 bool await_ready() noexcept {
31 return false;
32 }
33
34 void await_suspend(std::experimental::coroutine_handle<promise_type> _coroutine) noexcept {
35 _promise = &_coroutine.promise();
36 }
37 char await_resume() noexcept {
38 assert(_promise);
39 return _promise->_value;
40 }
41 };
42
43 std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
44
45 explicit fmt_cor(std::experimental::coroutine_handle<promise_type> coroutine)
46 : _coroutine(coroutine)
47 {}
48
49 ~fmt_cor() {
50 if(_coroutine) {
51 _coroutine.destroy();
52 if (_coroutine.promise()._l->g != 0 | _coroutine.promise()._l->b != 0) {
53 std::cout << "\n";
54 }
55 }
56 }
57
58 fmt_cor() = default;
59 fmt_cor(fmt_cor const &) = delete;
60 fmt_cor& operator=(fmt_cor const &) = delete;
61
62 fmt_cor(fmt_cor&& other) {
63 std::swap(_coroutine, other._coroutine);
64 }
65
66 fmt_cor& operator=(fmt_cor&& other) {
67 if(&other != this) {
68 _coroutine = other._coroutine;
69 other._coroutine = nullptr;
70 }
71 return *this;
72 }
73
74 void send(char a) {
75 _coroutine.promise()._value = a;
76 _coroutine.resume();
77 }
78};
79
80fmt_cor Fmt() {
81 fmt_cor::promise_type::locals l;
82 co_yield l;
83 for(;;) {
84 for(l.g = 0; l.g < 5; l.g++) {
85 for(l.b = 0; l.b < 4; l.b++) {
86 std::cout << co_await fmt_cor::get();
87 }
88 std::cout << " ";
89 }
90 std::cout << std::endl;
91 }
92}
93
94int main() {
95 auto fmt = Fmt();
96 for(int i = 0; i < 41; i++) {
97 fmt.send('a');
98 }
99}
Note: See TracBrowser for help on using the repository browser.