source: doc/papers/concurrency/examples/Fib.cpp @ aa22c60

arm-ehcleanup-dtorsjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-expr
Last change on this file since aa22c60 was aa22c60, checked in by tdelisle <tdelisle@…>, 3 years ago

Moved c++Cor example to examples folder

  • Property mode set to 100644
File size: 2.3 KB
Line 
1#include "base.hpp"
2
3#include <algorithm>
4#include <iterator>
5#include <vector>
6
7template<typename T>
8struct cor_range {
9        struct promise_type {
10                T _value;
11
12                cor_range get_return_object() {
13                        return cor_range(std::experimental::coroutine_handle<promise_type>::from_promise(*this));
14                }
15
16                auto initial_suspend() { return suspend_always(); }
17                auto final_suspend()   { return suspend_always(); }
18
19                void return_value(T value) {
20                        _value = value;
21                }
22
23                auto yield_value(T value) {
24                        _value = value;
25                        return suspend_always();
26                }
27
28                void unhandled_exception() {}
29        };
30
31        std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
32
33        explicit cor_range(std::experimental::coroutine_handle<promise_type> coroutine)
34                : _coroutine(coroutine)
35        {}
36
37        ~cor_range() {
38                if(_coroutine) { _coroutine.destroy(); }
39        }
40
41        cor_range() = default;
42        cor_range(cor_range const &) = delete;
43        cor_range& operator=(cor_range const &) = delete;
44
45        cor_range(cor_range&& other) {
46                std::swap(_coroutine, other._coroutine);
47        }
48
49        cor_range& operator=(cor_range&& other) {
50                if(&other != this) {
51                        _coroutine = other._coroutine;
52                        other._coroutine = nullptr;
53                }
54                return *this;
55        }
56
57        T next() {
58                _coroutine.resume();
59                return _coroutine.promise()._value;
60        }
61
62        struct iterator : std::iterator<std::input_iterator_tag, T> {
63                std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
64
65                iterator() = default;
66                explicit iterator(std::experimental::coroutine_handle<promise_type> coroutine)
67                        : _coroutine(coroutine)
68                {}
69
70                iterator& operator++() {
71                        _coroutine.resume();
72                        return *this;
73                }
74
75                T const & operator*() const {
76                        return _coroutine.promise()._value;
77                }
78        };
79
80        iterator begin() {
81                if(_coroutine) {
82                        _coroutine.resume();
83                        if(_coroutine.done()) { return end(); }
84                }
85
86                return iterator{ _coroutine };
87        }
88
89        iterator end() { return iterator{}; }
90};
91
92cor_range<int> fib() {
93        int fn;
94        fn = 0; int fn1 = fn; co_yield fn;
95        fn = 1; int fn2 = fn1; fn1 = fn; co_yield fn;
96        for(;;) {
97                fn = fn1 + fn2; fn2 = fn1; fn1 = fn; co_yield fn;
98        }
99}
100
101int main() {
102        {
103                auto f1 = fib();
104                auto f2 = fib();
105                for(int i = 0; i < 10; i++) {
106                        std::cout << f1.next() << " " << f2.next() << std::endl;
107                }
108        }
109
110        {
111                auto f1 = fib();
112                std::vector<int> fibs;
113                std::copy_n(f1.begin(), 10, std::back_inserter(fibs));
114
115                for(auto i : fibs) {
116                        std::cout << i << std::endl;
117                }
118        }
119}
Note: See TracBrowser for help on using the repository browser.