source: doc/papers/concurrency/examples/Fib2.cpp @ c2d728c

Last change on this file since c2d728c was 17c6c1c3, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

add more paper examples

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