Boost logo

Boost :

Subject: Re: [boost] [coroutine] new versions
From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2012-10-11 08:21:48


On Thu, Oct 11, 2012 at 12:39 PM, Oliver Kowalke <oliver.kowalke_at_[hidden]>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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk