Boost logo

Boost :

Subject: Re: [boost] Coroutines and Output Iterators
From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2008-10-10 11:07:34


On Fri, Oct 10, 2008 at 3:50 PM, Mathias Gaunard
<mathias.gaunard_at_[hidden]> wrote:
>
> Another solution is coroutines, which allows to return data then reenter
> later in the same context and keep going.
> The results of a coroutine can then be iterated as they come, giving the
> advantages of smart iterator/ranges while keeping the syntax of output
> iterators. It is however at the cost of some stack allocation at the
> beginning (which can be improved using pools) and context switches at each
> iteration.
>

Stack switching can be amortized by buffering more than one data for
every context switch.
The consumer can no longer control the exact amount of data produced
by the producer but in many cases it doesn't matter.

> What I propose is thus to make an output iterator that will yield the data
> within a coroutine context.
> With that solution, one writes generators as functions writing to output
> iterators, but those iterators might as well be writing to containers than
> actually yielding the result, which means the person designing the generator
> does not have the overhead of coroutines forced upon him.
>
<SNIP>

In fact I have been planning for a long time to make the 'self' type
be a functor. The interface to yield a value would change from the
current:

template<Self>
my_result my_gen(Self& f) {
   for(....)
       self.yield(val);
   self.exit();
}

to:

template<F>
void my_gen(F f) {
    for(...)
        f(val);
}

(note the switch from pass by reference to pass by value)
Making an output iterator from 'f' is trivial via
boost::function_output_iterator.

> The coroutine GSoC library from 2006 does offer that kind of thing, but not
> as non-intrusive output iterators. (I don't even get why it needs to call
> self.__self_exit__() at the end).

For no reason: at that time I thought it would have been a good idea
to require the generating function have a result type equal to the
coroutine yield-type, so that I could statically check it.
Unfortunately this means you have to use 'return' instead of 'yield'
to yield the last value of the generation, or exit via an exception
(generated by self.exit()). It was just stupid and I will to remove
it.

Btw, the same thing can be done with the current interface with a
trivial wrapper around the generating function.

>
> By the way, what is the status of that library? I haven't heard of it for
> quite a while.
>

Real life (and a job) got in the way. Progress has since been slow.

-- 
gpd

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