source: doc/papers/concurrency/examples/Format.cpp@ d06707e

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since d06707e was 571bf75, checked in by tdelisle <tdelisle@…>, 7 years ago

Clean existing coroutines using std::experimental::suspend_never and fixed Format coroutines to use RAII

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