source: doc/papers/concurrency/c++-cor/fib.cpp @ 9cb4fc8

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 9cb4fc8 was 9cb4fc8, checked in by tdelisle <tdelisle@…>, 5 years ago

Addded C++ example for fibonacci and counter with C++20 coroutines

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