blob: e5d40b1fc530cc0bc9bd4583fa3eb0d31c4a4349 [file] [log] [blame]
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef SUPPORT_COROUTINE_TYPES_H
#define SUPPORT_COROUTINE_TYPES_H
#include <experimental/coroutine>
template <typename Ty> struct generator {
struct promise_type {
Ty current_value;
std::experimental::suspend_always yield_value(Ty value) {
this->current_value = value;
return {};
}
std::experimental::suspend_always initial_suspend() { return {}; }
std::experimental::suspend_always final_suspend() { return {}; }
generator get_return_object() { return generator{this}; };
void return_void() {}
void unhandled_exception() {}
};
struct iterator {
std::experimental::coroutine_handle<promise_type> _Coro;
bool _Done;
iterator(std::experimental::coroutine_handle<promise_type> Coro, bool Done)
: _Coro(Coro), _Done(Done) {}
iterator &operator++() {
_Coro.resume();
_Done = _Coro.done();
return *this;
}
bool operator==(iterator const &_Right) const {
return _Done == _Right._Done;
}
bool operator!=(iterator const &_Right) const { return !(*this == _Right); }
Ty const &operator*() const { return _Coro.promise().current_value; }
Ty const *operator->() const { return &(operator*()); }
};
iterator begin() {
p.resume();
return {p, p.done()};
}
iterator end() { return {p, true}; }
generator(generator &&rhs) : p(rhs.p) { rhs.p = nullptr; }
~generator() {
if (p)
p.destroy();
}
private:
explicit generator(promise_type *p)
: p(std::experimental::coroutine_handle<promise_type>::from_promise(*p)) {}
std::experimental::coroutine_handle<promise_type> p;
};
#endif // SUPPORT_COROUTINE_TYPES_H