
On Thu, Oct 11, 2012 at 12:39 PM, Oliver Kowalke <oliver.kowalke@gmx.de>wrote:
What I do is having operator bool () return true if the coroutine has not terminated and has data.
How does this indicate that the next call to coroutine<>::operator() would not return a value?
It indicates that the *last* call did return a value,
Also, the coroutine-fn is called immediately when the coroutine is called, and not deferred to the first operator() call.
I don't get it - when will be the body of coroutine-fn entered?
coro_t c( fn);//? or c(); //?
The first option.
In the current implementation the first call of coroutine<>::operator() enters the body of the coroutine-fn.
example with some additional arguments:
typedef coroutine< std::string(int) > coro1_t; typedef coroutine< int(std::string) > coro2_t;
void fn( coro2_t & c){ int x = c.get(); c( textual_cast( x) ); x = c.get(); c( textual_cast( x) ); }
coro1_t c( fn); c( 1); // fn() is entered here std::string str = c.get();
int i = 0; for(; c ; c( ++i)) { std::string s = c.get(); }
I think your forr-loop would not work .
After the second call to 'c( i++)' in the loop 'c.get()' returns a value
('two'). 'coroutine::operator bool()' will evaluate to true (because result is available). If the next time c( ++i) is called the code returns from the last 'c( textual_cast( x) );' in coroutine-fn and terminates fn() - no data is returned. Because the for-loop does not test 'coroutine::operator bool()' before 'c.get()' you get a fault.
you do need to invoke the coroutine-fn immediately. I think that the interface works better this way. See for eaxmple https://github.com/gpderetta/Experiments/blob/bind/switch_test.cc, specifically: { std::vector<int> v = { 0,1,2,3,4,5,6,7,8,9,10 }; auto f = [=](continuation<void(int)> c) { return std::for_each(v.begin(), v.end(), std::move(c)); }; for(auto i = callcc(f) ; i ; i()) { int x = i.get(); assert(v[x] == x); } } Of couse it doesn't come for free; as I said, you now have the symmetric issue that in the coroutine-fn, the coroutine object doesn't have data till the first call to operator(). But again, I think that pull by default works better. -- gpd