25template <
typename T>
class SimpleGenerator {
28 using handle_type = std::coroutine_handle<promise_type>;
34 explicit SimpleGenerator(handle_type h) : mCoro(h) {}
36 SimpleGenerator(SimpleGenerator &&other_sg) noexcept : mCoro(other_sg.mCoro) {
37 other_sg.mCoro =
nullptr;
39 SimpleGenerator &operator=(SimpleGenerator &&other)
noexcept {
42 other.mCoro =
nullptr;
46 SimpleGenerator(
const SimpleGenerator &) =
delete;
47 SimpleGenerator &operator=(
const SimpleGenerator &) =
delete;
56 void start() { try_next(); }
57 bool running() {
return not mCoro.done(); }
60 if (mCoro.promise().m_latest_exception) {
61 std::rethrow_exception(mCoro.promise().m_latest_exception);
64 T take() {
return std::move(mCoro.promise().m_current_value); }
70 std::exception_ptr m_latest_exception;
71 friend SimpleGenerator;
74 auto get_return_object() {
75 return SimpleGenerator{handle_type::from_promise(*
this)};
77 auto yield_value(T some_value) {
78 m_current_value = some_value;
79 return std::suspend_always{};
81 auto unhandled_exception() {
82 m_latest_exception = std::current_exception();
84 auto initial_suspend() {
return std::suspend_always{}; }
85 auto final_suspend()
noexcept {
return std::suspend_always{}; }
86 auto return_void() {
return std::suspend_never{}; }
92 SimpleGenerator<T> &owner;
96 done = not owner.running();
100 bool operator!=(
const iterator &r)
const {
return done != r.done; }
101 auto operator*()
const {
return owner.take(); }
102 iterator &operator++() {
106 iterator(SimpleGenerator<T> &o,
bool d) : owner(o), done(d) {
115 iterator begin() {
return iterator{*
this,
false}; }
116 iterator end() {
return iterator{*
this,
true}; }
120 std::unordered_set<T> to_unordered_set() {
121 std::unordered_set<T> result;
122 for (
auto &value : *
this) {
123 result.insert(value);
129 std::vector<T> to_vector() {
130 std::vector<T> result;
131 for (
auto &value : *
this) {
132 result.push_back(value);