Commit f7900b6b authored by Tom Niget's avatar Tom Niget

Generator core update

parent 5f506528
......@@ -13,11 +13,44 @@ namespace typon {
* https://github.com/feabhas/coroutines-blog
*/
template <typename T> class Generator {
class Promise {
public:
using value_type = T;
class promise_type;
explicit Generator(std::coroutine_handle<promise_type> coroutine) noexcept
: _coroutine(coroutine) {}
Generator(const Generator &) = delete;
Generator &operator=(const Generator &) = delete;
Generator(Generator &&other) noexcept
: _coroutine(std::exchange(other._coroutine, nullptr)) {}
Generator &operator=(Generator other) {
std::swap(_coroutine, other._coroutine);
return *this;
}
~Generator() {
if (_coroutine) {
_coroutine.destroy();
}
}
Task<Generator> async_self() {
co_return std::move(*this);
}
auto operator co_await() && noexcept {
return std::move(async_self().operator co_await());
}
class promise_type {
public:
using value_type = std::optional<T>;
Promise() = default;
promise_type() = default;
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept {
final = true;
......@@ -38,7 +71,10 @@ template <typename T> class Generator {
void return_void() { this->value = std::nullopt; }
inline Generator get_return_object();
inline Generator<T> get_return_object() noexcept {
return Generator{
std::coroutine_handle<promise_type>::from_promise(*this)};
}
value_type get_value() { return std::move(value); }
......@@ -52,24 +88,12 @@ template <typename T> class Generator {
bool final = false;
};
public:
using value_type = T;
using promise_type = Promise;
explicit Generator(std::coroutine_handle<Promise> handle) : handle(handle) {}
~Generator() {
if (handle) {
handle.destroy();
}
promise_type::value_type next() {
if (_coroutine) {
if (!_coroutine.promise().finished()) {
_coroutine.resume();
}
Promise::value_type next() {
if (handle) {
if (!handle.promise().finished()) {
handle.resume();
}
return handle.promise().get_value();
return _coroutine.promise().get_value();
} else {
return {};
}
......@@ -79,7 +103,7 @@ public:
class iterator {
public:
using value_type = Promise::value_type;
using value_type = promise_type::value_type;
using difference_type = std::ptrdiff_t;
using iterator_category = std::input_iterator_tag;
......@@ -88,34 +112,34 @@ public:
value_type operator*() const {
if (generator) {
return generator->handle.promise().get_value();
return generator->_coroutine.promise().get_value();
}
return {};
}
value_type operator->() const {
if (generator) {
return generator->handle.promise().get_value();
return generator->_coroutine.promise().get_value();
}
return {};
}
iterator &operator++() {
if (generator && generator->handle) {
generator->handle.resume();
if (generator && generator->_coroutine) {
generator->_coroutine.resume();
}
return *this;
}
iterator &operator++(int) {
if (generator && generator->handle) {
generator->handle.resume();
if (generator && generator->_coroutine) {
generator->_coroutine.resume();
}
return *this;
}
bool operator==(const end_iterator &) const {
return generator ? generator->handle.promise().finished() : true;
return !generator || generator->_coroutine.promise().finished();
}
private:
......@@ -133,14 +157,9 @@ public:
private:
end_iterator end_sentinel{};
std::coroutine_handle<Promise> handle;
std::coroutine_handle<promise_type> _coroutine;
};
template <typename T>
inline Generator<T> Generator<T>::Promise::get_return_object() {
return Generator{std::coroutine_handle<Promise>::from_promise(*this)};
}
} // namespace typon
#endif // TYPON_GENERATOR_HPP
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment