I wrote up the iterator-driven for back in 2011, because it was one of those things that had been long-since forgotten about; along with what it would look like were it to be incorporated into the (then) C++ standard.
I am fortunate enough to own a copy of the High C/C++ Language Reference in English. (-:
Do you know how the break/return would get compiled down to? Would the yield function need to be transformed to return a status code and checked at the callsite?
It's a non-local goto, also a MetaWare language extension, out of the anonymous nested function that the for statement body becomes to (effectively) an anonymous label right after the for statement.
Another part of the High C/C++ Language Reference describes non-local labels and jumps to them. It doesn't go into great detail, but it does talk about stack unwinding, so expect something similar to how High C/C++ implemented throwing exceptions.
Not sure, but imo you could do it with basically reversing the call/return mechanism - that is, whenever the iterator function returns, it saves its state to the stack, just like if it would during a function call, and conversely, when the outside context hands back the control to the iterator, it would restore its state, analogous to how a return from an outside context would work.
That's not at all how MetaWare implemented iterator-driven for, though.
As Joe Groff said in the headlined post, MetaWare implemented it by turning the nested body of the for statement into an anonymous nested function, which is called back (through a "full function pointer") from the iterator function whenever there's a "yield()" in that latter.
So there's no "whenever the iterator function returns". It only returns when it has finished. The body of the for statement is called by and returns to the iterator function, which is in its turn called by and returns to the function that the for statement is in.
All of the "saving state to the stack" that happens is just the quite normal mechanics of function calling, with merely some special mechanics to pass around a pointer to the lexically outer function's activation record (which is why a "full function pointer" is not a plain "function pointer") as a hidden parameter so that the (anonymous) lexically inner function knows where the outer one's automatic storage duration variables are.
MetaWare also had non-local goto from within nested functions back out into lexically enclosing scopes, and since the for statement body is a nested function, it's just a question of employing that already available implementation mechanism (which in turn does the same sorts of things as throwing exceptions does, unwinding the stack through the iterator function) for break/continue/return (and of course goto) inside the for body.
I am fortunate enough to own a copy of the High C/C++ Language Reference in English. (-:
* http://jdebp.uk./FGA/metaware-iterator-driven-for.html
* http://jdebp.uk./Proposals/metaware-iterator-driven-for.html