Эмуляция оператора
await из языка C# 5.
Данный proof-of-concept показывает, что идентичный синтаксис оператора await может быть достигнут с помощью Stackful Coroutines, демонстрируя что они предоставляют превосходящие возможности.
Цель данного proof-of-concept — привлечь внимание к Stackful Coroutines, а не эмуляция await'а сама по себе — так как с помощью сопроцедур можно достичь более высоких уровней
инкапсуляцииАвтор: Evgeny.Panasyuk
Дата: 21.06.13
.
Пример использования:
int bar(int i)
{
// await is not limited by "one level" as in C#
auto result = await async([i]{ return reschedule(), i*100; });
return result + i*10;
}
int foo(int i)
{
cout << i << ":\tbegin" << endl;
cout << await async([i]{ return reschedule(), i*10; }) << ":\tbody" << endl;
cout << bar(i) << ":\tend" << endl;
return i*1000;
}
void async_user_handler()
{
vector<future<int>> fs;
// instead of `async` at function signature, `asynchronous` should be
// used at the call place:
for(auto i=0; i!=5; ++i)
fs.push_back( asynchronous([i]{ return foo(i+1); }) );
for(auto &&f : fs)
cout << await f << ":\tafter end" << endl;
}
"Оператор" await принимает std::future-like объект с поддержкой продолжений (например
.then) и возвращает результат future (await future<int>(...), вернёт int).
В данном примере используется boost::async. Но такой подход может использоваться и с другими видами future, например
PPL task::then и т.д.
Вывод:
1: begin
2: begin
3: begin
4: begin
5: begin
20: body
10: body
30: body
110: end
1000: after end
50: body
220: end
2000: after end
550: end
40: body
330: end
3000: after end
440: end
4000: after end
5000: after end