[coroutine] new versions
I've uploaded two re-factored versions - I think most of the suggestions from the review are implemented (namespace is not corrected and documentation not updated yet). 1.) http://ok73.ok.funpic.de/boost-coroutine-self.zip 2.) http://ok73.ok.funpic.de/boost-coroutine-coro.zip Version 1) requires that coroutine-fn has only one argument == coroutine<>::self_t. Other arguments are accessed via coroutine<>::self_t::get< int >() and results via coroutine<>::get(). interface provides input/output iterators. typedef coroutine< int( int, int> > coro_t; int fn( coro_t::self_t & c) { int x = c.get< 0 >(); int y = c.get< 1 >(); c.yield( x +y); ... } coro_t coro( fn); int res = c( 3, 7).get(); Version 2) requires that coroutine-fn has only one argument too == coroutine<> with inverted signature. Other arguments are access via coroutine<>::get(). interface provides input/output iterators. typedef coroutine< int( int, int> > coro_t; int fn( coroutine< tuple< int, int >( int) & c) { int x = c.get().get< 0 >(); int y = c.get().get< 1 >(); c( x +y); ... } coro_t coro( fn); int res = c( 3, 7).get(); Both implementations are not optimized - I think we should get a small and clean interface first. Comments? regards, Oliver
On Fri, Oct 5, 2012 at 11:22 AM, Oliver Kowalke
Version 1) requires that coroutine-fn has only one argument == coroutine<>::self_t. Other arguments are accessed via coroutine<>::self_t::get< int >() and results via coroutine<>::get(). interface provides input/output iterators.
I'm not sure this is an improvement over having yield() return a tuple. I guess that discussion must've taken place on the developers list.
Version 2) requires that coroutine-fn has only one argument too == coroutine<> with inverted signature.
The signature inversion thing makes me uneasy. Although I don't yet have a definite case in mind, I worry that would make it difficult to synthesize a coroutine as a helper object in generic code that needs to deal with arbitrary signatures.
Am 05.10.2012 20:10, schrieb Nat Linden:
On Fri, Oct 5, 2012 at 11:22 AM, Oliver Kowalke
wrote: Version 1) requires that coroutine-fn has only one argument == coroutine<>::self_t. Other arguments are accessed via coroutine<>::self_t::get< int >() and results via coroutine<>::get(). interface provides input/output iterators. I'm not sure this is an improvement over having yield() return a tuple. yield() returns a reference to coroutine<>::self_t. I decided to remove the parameters from the coroutine-fn signature and let the user access them via self_t::get< N >(). Then it should be clearer when and where the values are updated/available after a yield/resume cycle.
Version 2) requires that coroutine-fn has only one argument too == coroutine<> with inverted signature. The signature inversion thing makes me uneasy. Although I don't yet have a definite case in mind, I worry that would make it difficult to synthesize a coroutine as a helper object in generic code that needs to deal with arbitrary signatures.
coroutine<>::caller_t is a typedef of the coroutine type expected/passed to coroutine-fn. typedef coroutine< int( int, int> > coro_t; int fn( coro_t::caller_t & c) { int x = c.get().get< 0 >(); int y = c.get().get< 1 >(); c( x +y); ... } coro_t coro( fn); int res = c( 3, 7).get(); regards, Oliver
On Fri, Oct 5, 2012 at 2:32 PM, Oliver Kowalke
Am 05.10.2012 20:10, schrieb Nat Linden:
On Fri, Oct 5, 2012 at 11:22 AM, Oliver Kowalke
wrote: Version 1) requires that coroutine-fn has only one argument == coroutine<>::self_t. Other arguments are accessed via coroutine<>::self_t::get< int >() and results via coroutine<>::get(). interface provides input/output iterators.
I'm not sure this is an improvement over having yield() return a tuple.
I decided to remove the parameters from the coroutine-fn signature and let the user access them via self_t::get< N >(). Then it should be clearer when and where the values are updated/available after a yield/resume cycle.
I can see that that eliminates the need for the coroutine-fn code to know whether it's accessing the parameters for the first time (obtain from formal function parameters) or a subsequent time (returned from yield()). Okay.
On Fri, Oct 5, 2012 at 8:22 AM, Oliver Kowalke
I've uploaded two re-factored versions - I think most of the suggestions from the review are implemented (namespace is not corrected and documentation not updated yet).
1.) http://ok73.ok.funpic.de/**boost-coroutine-self.ziphttp://ok73.ok.funpic.de/boost-coroutine-self.zip 2.) http://ok73.ok.funpic.de/**boost-coroutine-coro.ziphttp://ok73.ok.funpic.de/boost-coroutine-coro.zip
Version 1) requires that coroutine-fn has only one argument == coroutine<>::self_t. Other arguments are accessed via coroutine<>::self_t::get< int >() and results via coroutine<>::get(). interface provides input/output iterators.
typedef coroutine< int( int, int> > coro_t; int fn( coro_t::self_t & c) { int x = c.get< 0 >(); int y = c.get< 1 >(); c.yield( x +y); ... } coro_t coro( fn); int res = c( 3, 7).get();
Version 2) requires that coroutine-fn has only one argument too == coroutine<> with inverted signature. Other arguments are access via coroutine<>::get(). interface provides input/output iterators.
typedef coroutine< int( int, int> > coro_t; int fn( coroutine< tuple< int, int >( int) & c) { int x = c.get().get< 0 >(); int y = c.get().get< 1 >(); c( x +y); ... } coro_t coro( fn); int res = c( 3, 7).get();
Both implementations are not optimized - I think we should get a small and clean interface first. Comments?
FWIW, I (presently) prefer the syntax and symmetry in 2). Maybe for ease-of-use you can also submit a macro to Boost.Fusion that "unpacks and initializes" the arguments into local variables, something that allows you to do BOOST_FUSION_UNPACK( ( int x ) ( int y ), c.get() ) // Or maybe it could work with just "c"? Or maybe "c.result()" would be better? I have such a macro implemented, so could help with such a feature. It's basically an extension of tie'ing. It looks like there's still a question on when the coroutine function body is entered: upon construction of the coroutine object or upon the first call? Seems like the natural thing would be upon the first call, separate from the coroutine construction, but...yeah I admit I don't fully grasp the pros and cons of each convention. And this seems sufficiently important to get right. Sorry, that's probably not very helpful :) - Jeff
participants (3)
-
Jeffrey Lee Hellrung, Jr.
-
Nat Linden
-
Oliver Kowalke