Boost logo

Boost :

Subject: Re: [boost] {Review] Coroutine reviewstarts today, September 3rd
From: Eugene Yakubovich (eyakubovich_at_[hidden])
Date: 2012-09-04 14:56:38

On Tue, Sep 4, 2012 at 1:38 AM, Oliver Kowalke <oliver.kowalke_at_[hidden]> wrote:
>> typedef boost::coro::generator< int > gen_t;
>> gen_t evens(int cnt) {
>> return [=](gen_t::self_t& self) {
>> for( int i = 0; i < cnt; i++ )
>> self.yield(i*2);
>> };
>> }
> the generator<> template was derived from coroutine<> and therefore it generator follows the practice of coroutien return_type(). Of course I think it would be possible to require a generator-function of void() with
> self_t::operator( T t) (T = int, ... == return type from generator) - I should think about it (if and how it is implementable - what think the community members?).
> some compilers complain some compilers to no if you end a function without a return statement.

Do you mean in the cases where the function has been declared to
return something other than void? Because I'm proposing to have
generator-function's return type be void -- there should be no
problems in that case.

> yield_return() does complete the generator and unwind the stack (AFAIK python coroutines are stackles). Unforutnately each compiler has its own unwind facility so it is easier to throw an exception in order to unwind the corutine/generator.

You mean yield_break, right? I would keep yield_break as is for the
cases where one wants to terminate the generator from a call to
another function. e.g.

void foo(gen_t::self_t& self) {

void gen_func(gen_t::self_t& self) {

But I would think that many generator-functions would exit naturally
from top-level and saving yield_break in that case would improve style
and performance.

>> for( int x: evens(10) )
>> std::cout << x << ' ';
> Of course iterators should benefit from coroutines/generators in some places. Your code looks like C# - I assume evens(10) is the range enumerator based on a generator?

It might look like C# :)

evens() is the function defined question (1) and I got it to work with
based-range-for by defining this hackish iterator:

template <typename G>
struct gen_iter {
    G* g;
    typedef decltype(std::declval<G>()()) result_type;

    result_type operator*() const { return (*g)(); }
    gen_iter& operator++() { return *this; }
    bool operator!=(const gen_iter&) const { return *g; }

namespace boost { namespace coro {
    template <typename G> gen_iter<G> begin(G& g) { return gen_iter<G>{&g}; }
    template <typename G> gen_iter<G> end(G& g) { return gen_iter<G>{nullptr}; }
} }

Boost list run by bdawes at, gregod at, cpdaniel at, john at