
On Sat, Oct 11, 2008 at 12:35 AM, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
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.
This isn't such a good idea, IMHO. I'm using the GSoC version for quite some time now and this Self instance is a good place to store/access fiber specific data (similar to thread specific storage, but not has no thread affinity, i.e. is available regardless of which thread actually executes the fiber/coroutine).
Well, treating the self instance as a function object doesn't prevent other more ad hoc uses. Generic code that doesn't care just treats it as a function object, more specialized code that is coroutine aware can have access to other functionality. The change I have in mind is basically just changing self_type::yield to self_type::operator() (and supporting copy semantics). -- gpd