Today I saw discussion about boost.coroutine on gmane:
Generators and coroutines are conceptually the same feature and I have implementation of $generator thing that can be used to implement coroutines.
My implementation is of 15 lines of code and does not require any threads/fibers and so context switches – pure C++ with macro magic, pretty straightforward though.
Anyway, here is an example how coroutine can be implemented using that $generator thing.
First, let’s define coroutine (or generator) that will establish connection with some server and will supply (yield) data chunks read from socket:
$generator(net_reader)
{
socket_t sock;
byte buffer[2048];
net_reader(const char* addr) { sock.connect(addr); }
// from $emit to $stop is a body of our coroutine:
$emit(slice<byte>) // Coroutine will emit slice<byte> values. Start of coroutine body.
while( sock.valid() )
{
slice<byte> r(buffer,0);
r.length = sock.read(buffer,sizeof(buffer));
if(r.length)
$yield( r );
else
break;
}
$stop; // stop. End of coroutine body.
};
Having this we can write code that will read data chunk by chunk and store it in some array.
array<byte> data;
net_reader get("data.example.com:4002");
for(slice<byte> chunk; get(chunk);)
data.push(chunk);
That’s easy, no?
Yes, $generator thing is not free from problems (e.g. you cannot use switch() inside its body) but other than that and in 99% of coroutine cases you will get what is needed from generators/coroutines. And without those tons of code.