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

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since cb25fc9 was 17c6c1c3, checked in by Peter A. Buhr <pabuhr@…>, 7 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.