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