Commit 5f506528 authored by Tom Niget's avatar Tom Niget

Add preliminary support for generators with new coroutine system

parent dfbd8f84
...@@ -12,17 +12,17 @@ namespace typon { ...@@ -12,17 +12,17 @@ namespace typon {
/** /**
* https://github.com/feabhas/coroutines-blog * https://github.com/feabhas/coroutines-blog
*/ */
template <typename T> template <typename T> class Generator {
class Generator class Promise {
{
class Promise
{
public: public:
using value_type = std::optional<T>; using value_type = std::optional<T>;
Promise() = default; Promise() = default;
std::suspend_always initial_suspend() { return {}; } std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { final = true; return {}; } std::suspend_always final_suspend() noexcept {
final = true;
return {};
}
void unhandled_exception() { void unhandled_exception() {
std::rethrow_exception(std::move(std::current_exception())); std::rethrow_exception(std::move(std::current_exception()));
} }
...@@ -36,18 +36,14 @@ class Generator ...@@ -36,18 +36,14 @@ class Generator
// this->value = std::move(value); // this->value = std::move(value);
// } // }
void return_void() { void return_void() { this->value = std::nullopt; }
this->value = std::nullopt;
}
inline Generator get_return_object(); inline Generator get_return_object();
value_type get_value() { value_type get_value() { return std::move(value); }
return std::move(value);
}
bool finished() { bool finished() {
//return !value.has_value(); // return !value.has_value();
return final; return final;
} }
...@@ -60,12 +56,12 @@ public: ...@@ -60,12 +56,12 @@ public:
using value_type = T; using value_type = T;
using promise_type = Promise; using promise_type = Promise;
explicit Generator(std::coroutine_handle<Promise> handle) explicit Generator(std::coroutine_handle<Promise> handle) : handle(handle) {}
: handle (handle)
{}
~Generator() { ~Generator() {
if (handle) { handle.destroy(); } if (handle) {
handle.destroy();
}
} }
Promise::value_type next() { Promise::value_type next() {
...@@ -74,24 +70,21 @@ public: ...@@ -74,24 +70,21 @@ public:
handle.resume(); handle.resume();
} }
return handle.promise().get_value(); return handle.promise().get_value();
} } else {
else {
return {}; return {};
} }
} }
struct end_iterator {}; struct end_iterator {};
class iterator class iterator {
{
public: public:
using value_type = Promise::value_type; using value_type = Promise::value_type;
using difference_type = std::ptrdiff_t; using difference_type = std::ptrdiff_t;
using iterator_category = std::input_iterator_tag; using iterator_category = std::input_iterator_tag;
iterator() = default; iterator() = default;
iterator(Generator& generator) : generator{&generator} iterator(Generator &generator) : generator{&generator} {}
{}
value_type operator*() const { value_type operator*() const {
if (generator) { if (generator) {
...@@ -107,26 +100,26 @@ public: ...@@ -107,26 +100,26 @@ public:
return {}; return {};
} }
iterator& operator++() { iterator &operator++() {
if (generator && generator->handle) { if (generator && generator->handle) {
generator->handle.resume(); generator->handle.resume();
} }
return *this; return *this;
} }
iterator& operator++(int) { iterator &operator++(int) {
if (generator && generator->handle) { if (generator && generator->handle) {
generator->handle.resume(); generator->handle.resume();
} }
return *this; return *this;
} }
bool operator== (const end_iterator&) const { bool operator==(const end_iterator &) const {
return generator ? generator->handle.promise().finished() : true; return generator ? generator->handle.promise().finished() : true;
} }
private: private:
Generator* generator{}; Generator *generator{};
}; };
iterator begin() { iterator begin() {
...@@ -134,24 +127,18 @@ public: ...@@ -134,24 +127,18 @@ public:
return ++it; return ++it;
} }
end_iterator end() { end_iterator end() { return end_sentinel; }
return end_sentinel;
}
std::optional<value_type> py_next() { std::optional<value_type> py_next() { return next(); }
return next();
}
private: private:
end_iterator end_sentinel{}; end_iterator end_sentinel{};
std::coroutine_handle<Promise> handle; std::coroutine_handle<Promise> handle;
}; };
template <typename T> template <typename T>
inline Generator<T> Generator<T>::Promise::get_return_object() inline Generator<T> Generator<T>::Promise::get_return_object() {
{ return Generator{std::coroutine_handle<Promise>::from_promise(*this)};
return Generator{ std::coroutine_handle<Promise>::from_promise(*this) };
} }
} // namespace typon } // namespace typon
......
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