await in c++ - yield the next
The fibonacci example from Gor’s presentation (PDF, YouTube) is the subject of this post. generator<T>
implements the Range Concept so it works with existing algorithms from STL and Rangev3 and the range-for
feature. It can be found in the header experimental/generator
. A function that returns generator<T>
is allowed to use the yield_value
keyword (which evaluates to await generator<T>::promise_type::yield_value(T)
).
// yield.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <experimental/resumable>
#include <experimental/generator>
namespace ex = std::experimental;
ex::generator<int> fibonacci(int n) {
int a = 0;
int b = 1;
while (n-- > 0) {
__yield_value a;
auto next = a + b; a = b;
b = next;
}
}
int wmain() {
for (auto v : fibonacci(35)) {
if (v > 10)
break;
std::cout << v << ' ';
}
}
diagram
The fibonacci()
function uses yield_value
to interleave the fibonacci()
loop and the caller
loop on the current thread. The begin()
and operator++()
functions resume the fibonacci()
loop while yield_value
resumes the caller
loop. generator<T>
uses this interleaving to pass the value to the caller
as a const reference to the value inside the fibonacci()
loop. This avoids a copy while preventing the caller
from modifiying the state of the fibonacci()
loop.
try it out
After installing Visual Studio 2015 Preview clone await and open the await solution. This code is in the yield project in the solution.