Boost logo

Boost :

Subject: Re: [boost] [Review.Coroutine] Vicente's review
From: Eugene Yakubovich (eyakubovich_at_[hidden])
Date: 2012-09-13 12:39:08


> This design required pre-fetching and storing the return value via a context
> jump into the generator routine.
> Only with this mechanism I was able to know if the next call to
> generator<>::operator() will return a value.
> (requires that the first pre-fetch is done in the ctor of generator<>
>
> The difference to the actual design
>
>
> if ( optional< int > val = gen() ) {
> ....
> }
>
> is that I don't need to pre-fetch and not to store the optional<> as
> parameter (optional is only created inside generator<>::operator()).
>

If the generator-function returns non-void (original design) and has
no yield_break, then it's possible for generator::operator() to return
R (not optional<R>) and do no prefetching. But personally, I would
rather take the optional<R> with a void generator-function and provide
the iterator (iterator::operator* will return R, not optional<R>) as
the preferred interface.

>>>> * The access to the actual coroutine parameters is asymmetric, letting
>>>> access to old actual parameters that can point to objects that have
>>>> already
>>>> been destroyed.
>>>>
>>>> Maybe the self_t object could take care of this (or this_coroutine). We
>>>> can use a get<> function to give access to the actual parameters.
>>>>
>>>> int f20(coro_t::self_t & self)
>>>> {
>>>> self.yield(2*self.get<0>());
>>>> }
>>>>
>>>>
>>>> int f20()
>>>> {
>>>> typedef this_coroutine&lt;int(int)&gt; this_coro;
>>>> this_coro::yield(2*this_coro::get<0>());
>>>> }
>>>
>>> interesting idea, I find it better than the version using bind because
>>> you
>>> don't can't forget to 'bind'. you are always required to use
>>> self_t::get<>().

One could still do this:

int f20(coro_t::self_t & self) {
    X& x1 = self.get<0>();
    self.yield();
    X& x2 = self.get<0>();
    // use x1 and x2 here. x1 might be bogus now
}

Maybe the example is a bit contrived but not anymore than the original
one where the use of formal parameters posed the same danger. Even
with bind(), one could create a ref/ptr to the bound variable that
would be bogus after the next yield().

Regards,
Eugene


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