//#(compile) c++; compiler:g132; options:"-std=c++20"; libs:-
// https://godbolt.org/z/4ed3oWK7q
#include <coroutine>
#include <iostream>
struct Routine { // Koroutinen-Rückgabetyp
struct promise_type; // weiter unten definiert
Routine(auto h) : hdl_(h) {} // Konstruktor
~Routine() { if(hdl_) hdl_.destroy(); } // Destruktor
Routine(const Routine&) = delete; // keine Kopien
Routine(Routine&&) = delete; // keine Verschiebungen
// Schnittstelle für den Aufrufer:
bool more() { // Koroutine fortsetzen
if(!hdl_ || hdl_.done()) return false; // - nichts mehr zu tun
hdl_.resume(); // - blockierender Aufruf
return !hdl_.done(); // - signalisiert fertig oder nicht
}
private:
using handle_type_ = std::coroutine_handle<promise_type>;
handle_type_ hdl_; // zum Steuern der Koroutine
};
struct Routine::promise_type { // notwendiger promise_type
auto get_return_object() { // initialisiert das Handle
return Routine{ handle_type_::from_promise(*this) };
}
auto initial_suspend() { return std::suspend_never{}; } // sofort starten
auto final_suspend() noexcept { return std::suspend_always{}; } // Normalfall
void unhandled_exception() {} // keine Exception-Behandlung
void return_void() {} // Koroutine hat keine Rückgabe
};
Routine counter() { // Rückgabetyp ist unsere Wrapperklasse mit dem promise_type
for (unsigned i = 0;; ++i) {
co_await std::suspend_always{}; // Koroutine pausieren
std::cout << "counter: " << i << std::endl;
}
}
int main() {
Routine routine = counter(); // Koroutine erzeugen und starten
for (int i = 0; i < 3; ++i) {
std::cout << "Hallo main!\n";
routine.more(); // Koroutine fortsetzen
}
}