source: doc/papers/concurrency/examples/Format.cpp @ 075c6d5

Last change on this file since 075c6d5 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
RevLine 
[571bf75]1#include <iostream>
2#include <experimental/coroutine>
[be3416d]3
4struct fmt_cor {
5        struct promise_type {
[8f936bf]6                char _value;
[be3416d]7
8                fmt_cor get_return_object() {
9                        return fmt_cor(std::experimental::coroutine_handle<promise_type>::from_promise(*this));
10                }
11
[571bf75]12                auto initial_suspend() { return std::experimental::suspend_never(); }
13                auto final_suspend()   { return std::experimental::suspend_always(); }
[be3416d]14
15                void return_void() {}
[8f936bf]16                void unhandled_exception() {}
17        };
18
19        struct get {
20                promise_type * _promise = nullptr;
[be3416d]21
[8f936bf]22                bool await_ready() noexcept {
23                        return false;
[be3416d]24                }
25
[8f936bf]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                }
[be3416d]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() {
[13b1b1d]42                if(_coroutine) {
43                        _coroutine.destroy();
[571bf75]44
[13b1b1d]45                }
[be3416d]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) {
[8f936bf]65                _coroutine.promise()._value = a;
[be3416d]66                _coroutine.resume();
67        }
68};
69
70fmt_cor Fmt() {
[571bf75]71        struct locals {
72                int g, b;
73
74                ~locals() {
75                        if (g != 0 | b != 0) {
76                                std::cout << "\n";
77                        }
78                }
79        } l;
[be3416d]80        for(;;) {
[13b1b1d]81                for(l.g = 0; l.g < 5; l.g++) {
82                        for(l.b = 0; l.b < 4; l.b++) {
[8f936bf]83                                std::cout << co_await fmt_cor::get();
[be3416d]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.