suspend-iter.cpp

#include <coroutine>
#include <iostream>
#include <iterator>

class Coro {
public:
    struct promise_type
    {
        Coro get_return_object() { return Coro(this); }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_always yield_value(std::string v) // <--- called by co_yield  
        { 
            last_value = v;                            // <--- save yielded value
            return {};
        }
        std::suspend_always final_suspend() noexcept(true) { return {}; }
        void return_void() {}        
        void unhandled_exception() {}
        std::string last_value;                        // <--- last value co_yield'ed
    };

    struct sentinel {};
    struct iterator
    {
        std::coroutine_handle<promise_type> coro;
        bool operator==(sentinel) const { return coro.done(); }
        iterator& operator++()
        {
            coro.resume();
            return *this;
        }
        std::string operator*() const
        {
            return coro.promise().last_value;
        }
    };

public:
    Coro(promise_type* p) : _promise(p) {}
    iterator begin() const { return {std::coroutine_handle<promise_type>::from_promise(*_promise)}; }
    sentinel end() const { return {}; }

private:
    promise_type* _promise;
};

Coro hello()
{
    std::cout << "Saying Hello" << std::endl;
    co_yield "Hello";
    std::cout << "Not Saying Bye" << std::endl;
    co_return;
}

int main()
{
    auto hello_instance = hello();

    for (auto elem: hello_instance)
        std::cout << elem << std::endl;

    return 0;
}