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

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since a86b1b85 was 571bf75, checked in by tdelisle <tdelisle@…>, 6 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.