
On Thu, Oct 11, 2012 at 10:22 AM, Oliver Kowalke <oliver.kowalke@gmx.de>wrote:
Von: "Oliver Kowalke" <oliver.kowalke@gmx.de>
An: boost@lists.boost.org, boost@lists.boost.org> > I would
like to see the coroutine-function with a void return type. Or have an option for that.
I've had such a version but I dropped it because for detecting the completeness of the coroutine would require an extra jump (return from last jump-function and calling return in the coroutine-fn). And this makes the implementation for iterators very painful:
void fn( coroutine<void(int)> & c) { c( 1); c( 2); }
The iterator would be required to be incremented three times. And std::distance would return 3 instead of 2.
If coroutine-fn is required to return void - we could detect the last 'caller_t::operator()' from coroutine-fn if we require to test the coroutine after each call:
typedef coroutine< int() > coro1_t; typedef coroutine< void(int) > coro2_t;
void fn( coro2_t & c) { c( 1); c( 2); }
coro1_t c( fn); while ( c) { c(); if ( ! c) break; int res = c.get(); }
What I do is having operator bool () return true if the coroutine has not terminated and has data. Also, the coroutine-fn is called immediately when the coroutine is called, and not deferred to the first operator() call. This way you can stop iteration as soon as data is no longer generated, whith the following pattern: void fn( coro2_t & c) { c(1); c(2); } coro1_t c(fn); for(; c ; c()) { int ret = c.get(); } Of course such a loop won't work in the coroutine-fn itself as the coro2_t c won't have data yet. An initial call to c() must be done. But I guess that coroutines will be used more often for pulling data than for pushing, so the interface works better like this. -- gpd