Могу ли я построить двунаправленную сопрограмму с Boost 1.55?

Текущая версия Boost 1.55 предлагает два вида однонаправленных сопрограмм. Одним из них является pull-type, который является сопрограммой, которая не принимает параметров и возвращает значение в основной контекст; другой - push-type, который является сопрограммой, которая принимает параметр из основного контекста, но не возвращает никакого значения.

Как я могу объединить эти два, чтобы создать двунаправленную сопрограмму, которая принимает параметр и возвращает значение? На первый взгляд кажется, что это должно быть возможно, но я не могу понять, как это сделать со строительными блоками, которые у меня есть в boost::coroutine. Раньше существовала двунаправленная сопрограмма в старших Boosts, но теперь она устарела и недокументирована, поэтому я не должен полагаться на нее.

т.е. мне хотелось бы что-то подобное:

void accumulate( pull_func &in, push_func &out )
{
  int x = 0;
  while ( in ) 
  {
    x += in.get() ; // transfers control from main context 
    out(x); // yields control to main context
  }
}

void caller( int n ) 
{
   bidirectional_coro( accumulate );
   for ( int i = 0 ; i < n ; ++i )
   {
      int y = accumulate(i); 
      printf( "%d ", y ); // "0 1 3 6 10" etc
   }
}

Ответы

Ответ 1

На самом деле, boost coroutine был двунаправленным, когда он был впервые включен в boost (1.53, я думаю).

http://www.boost.org/doc/libs/1_53_0_beta1/libs/coroutine/doc/html/coroutine/coroutine.htm

Этот код должен быть совместим с самой последней версией boost, с незначительной модификацией.

Кроме того, вы можете напрямую использовать boost:: context, чтобы создать свой собственный класс coroutine.

http://www.boost.org/doc/libs/1_55_0/libs/context/doc/html/index.html

Параметр "intptr_t vp" fcontext_swap может использоваться для передачи значений/указателей взад и вперед, или вы можете хранить значения в самой сопрограмме, так как переменные-члены вашего класса coroutine должны быть действительными из обоих контекстов.

изменить

Короткий ответ на ваш первоначальный вопрос - нет. То, что вы просите, не может быть сделано. Каждая сопрограмма имеет собственный стек и контекст, которые недоступны из других экземпляров coroutine. Кроме того, когда вы переходите в контекст coroutine, состояние вызывающего контекста хранится в экземпляре , который coroutine, а переход обратно в исходный контекст может быть выполнен только путем вызова в аргумент > , который сопроводил вашу функцию.

Но переменные, объявленные вне локальной области сопрограммы, будут действительны изнутри и вне функции сопрограмм. Таким образом, вы можете использовать coroutine:: push_type и нажимать указатель вместо значения. Вы можете использовать это значение и затем изменить его, прежде чем переходить к исходному контексту.

Кроме того, вы можете безопасно передавать указатели на локальные переменные в сопрограмму coroutine, так как они не будут уничтожены до тех пор, пока вы не вернетесь из сопрограммы и не завершите выполнение области вызова.