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