Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to nest coroutines using Boost.Coroutine?

I would like to call a coroutine when already in a coroutine. Is it possible using Boost.Coroutine?

like image 361
Alexandre Hamez Avatar asked Sep 20 '13 12:09

Alexandre Hamez


People also ask

What is boost Coroutine?

Coroutine provides templates for generalized subroutines which allow suspending and resuming execution at certain locations. It preserves the local state of execution and allows re-entering subroutines more than once (useful if state must be kept across function calls).

What are the characteristics of co routine feature?

Characteristics of a coroutine are: values of local data persist between successive calls (context switches) execution is suspended as control leaves coroutine and is resumed at certain time later. symmetric or asymmetric control-transfer mechanism; see below.


1 Answers

Yes, it's easy as:

#include <iostream>
#include <boost/coroutine/coroutine.hpp>

typedef boost::coroutines::coroutine<int()> generator;

void bar(generator::caller_type& yield)
{
  for (std::size_t i = 100; i < 110; ++i)
    yield(i);
}

void foo(generator::caller_type& yield)
{
  for (std::size_t i = 0; i < 10; ++i)
  {
    generator nested_gen(bar);
    while (nested_gen)
    {
      std::cout << "foo: " << nested_gen.get() << std::endl;
      nested_gen();
    }
    yield(i);
  }
}

int main()
{
  generator gen(foo);
  while (gen)
  {
    std::cout << "main: " << gen.get() << std::endl;
    gen();
  }
  return 0;
};

Edit: With Boost >= 1.56

#include <iostream>
#include <boost/coroutine/asymmetric_coroutine.hpp>

using generator = typename boost::coroutines::asymmetric_coroutine<std::size_t>::pull_type;
using yield_type = typename boost::coroutines::asymmetric_coroutine<std::size_t>::push_type;

void bar(yield_type& yield)
{
  for (std::size_t i = 100; i < 110; ++i)
    yield(i);
}

void foo(yield_type& yield)
{
  for (std::size_t i = 0; i < 10; ++i)
  {
    generator nested_gen{bar};
    while (nested_gen)
    {
      std::cout << "foo: " << nested_gen.get() << '\n';
      nested_gen();
    }
    yield(i);
  }
}

int main()
{
  generator gen{foo};
  while (gen)
  {
    std::cout << "main: " << gen.get() << '\n';
    gen();
  }
  return 0;
};
like image 115
Alexandre Hamez Avatar answered Sep 28 '22 01:09

Alexandre Hamez