1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef SUPPORT_COROUTINE_TYPES_H 12 #define SUPPORT_COROUTINE_TYPES_H 13 14 #include <experimental/coroutine> 15 16 template <typename Ty> struct generator { 17 struct promise_type { 18 Ty current_value; 19 std::experimental::suspend_always yield_value(Ty value) { 20 this->current_value = value; 21 return {}; 22 } 23 std::experimental::suspend_always initial_suspend() { return {}; } 24 std::experimental::suspend_always final_suspend() { return {}; } 25 generator get_return_object() { return generator{this}; }; 26 void return_void() {} 27 void unhandled_exception() {} 28 }; 29 30 struct iterator { 31 std::experimental::coroutine_handle<promise_type> _Coro; 32 bool _Done; 33 34 iterator(std::experimental::coroutine_handle<promise_type> Coro, bool Done) 35 : _Coro(Coro), _Done(Done) {} 36 37 iterator &operator++() { 38 _Coro.resume(); 39 _Done = _Coro.done(); 40 return *this; 41 } 42 43 bool operator==(iterator const &_Right) const { 44 return _Done == _Right._Done; 45 } 46 47 bool operator!=(iterator const &_Right) const { return !(*this == _Right); } 48 49 Ty const &operator*() const { return _Coro.promise().current_value; } 50 51 Ty const *operator->() const { return &(operator*()); } 52 }; 53 54 iterator begin() { 55 p.resume(); 56 return {p, p.done()}; 57 } 58 59 iterator end() { return {p, true}; } 60 61 generator(generator &&rhs) : p(rhs.p) { rhs.p = nullptr; } 62 63 ~generator() { 64 if (p) 65 p.destroy(); 66 } 67 68 private: 69 explicit generator(promise_type *p) 70 : p(std::experimental::coroutine_handle<promise_type>::from_promise(*p)) {} 71 72 std::experimental::coroutine_handle<promise_type> p; 73 }; 74 75 #endif // SUPPORT_COROUTINE_TYPES_H 76