
Hi Oliver,
I managed to implement your suggestion - generator-functions are required to return void and generator<>::self_t::yield() accepts the return type specified as template arg of generator<>. generator<>::self_t::yield_break() was removed.
The code is available under git://gitorious.org/boost-dev/boost-dev.git (branch coroutine).
Thank you for implementing the changes. I know I initially argued to eliminate yield_break but later agreed that it was probably beneficial to have it for the cases when one wants to complete the generator from non top-level function. With the exception machinery there anyway, I think it won't hurt to keep it. Another issue that I see is with reference/pointer types. The fact that the following code will blow up is troubling: struct X {...}; typedef boost::coro::generator<X*> gen_t; void foo(gen_t::self_t& self) { X x1, x2; self.yield(&x1); self.yield(&x2); } gen_t g(foo); while( g ) { X* val = g(); // use *val. Ok on first iteration, dangling pointer on the second!!! } Especially if generator does not support movable-only types, I am afraid that this will be a common tripping point. Giovanni's design had the same issue which he advised to avoid by using the iterator like interface (using operator* and operator++). Maybe we can change behavior so that generator's constructor does not invoke the generator-function, only operator() does. And change operator() to return optional<R> instead of R. The usage can then be: gen_t g(foo); while( optional<X> val = g() ) { // use val.get() } I'm not really sure about what to do about is_complete() or operator unspecified-bool-type(), though. Maybe they are not needed at all? I admit that this interface might be a bit quirky but if the library also provides input iterator, that can become the primary interface. Generators are used to produce sequences and iterators are the central mechanism of dealing with sequences in C++. So the iterator usage could be: for( gen_t::iterator it = g.begin(); it != g.end(); ++it ) { X* val = *it; // no dangling pointers } (or BOOST_FOREACH, C++11 range-based for, or for_each). g.begin() or gen_t::iterator ctor would invoke the generator-function for the first time and ++it for all subsequent times. An alternative approach could be to try to make generator itself into an input iterator (like Giovanni's design) but that is hard because generator is non-copyable. Thoughts? Regards, -Eugene