In this post, I analyze the new keyword co_yield. Thanks to co_yield, you can create an infinite data stream in C++20.
This is what happened so far in my pragmatical journey through the new coroutine keywords
- Implementing Simple Futures With Coroutines
- Lazy Futures with Coroutines
- Executing a Future in a separate Thread with Coroutines
As a starting point for further variations, I want to start with a generator which I only ask for three values. This simplification and visualization should help understand the generator’s control flow.
Let’s analyze the control flow.
getNext() (line 1) triggers the creation of the
promise_type (line 2) is created, and the following
get_return_object call (line 3) creates the generator (line 4) and stores it in a local variable. The result of this call is returned to the caller when the coroutine is suspended the first time. The initial suspension happens immediately (line 5). Because the member function call
initial_suspend returns an Awaitable
std::suspend_always (line 6), the control flow continues with the coroutine
getNext until the instruction
co_yield value (line 7). This call is mapped to the call
yield_value(int value) (line 8), and the current value is prepared
current_value = value (line 9). The member function
yield_value(int value) returns the Awaitable
std::suspend_always (line 10). Consequently, the execution of the coroutine pauses, the control flow goes back to the main function, and the for loop starts (line 11). The call
gen.getNextValue() (line 12) starts the execution of the coroutine by resuming the coroutine using
coro.resume() (line 13). Further, the function
getNextValue() returns the current value prepared using the previously invoked member function
yield_value(int value) (line 8). Finally, the generated number is displayed in line 14 and the for loop continues. In the end, the generator and the promise are destroyed.
After this detailed analysis, I want first to modify the control flow.
infiniteDataStreamComments.cpp. I only show the modifications.
The Coroutine is Not Resumed
gen.getNextValue()in line 12) and the display of its value (line 14), the coroutine immediately pauses.
initial_suspend Never Suspends
In the program, the member function
initial_suspend returns the Awaitable
std::suspend_always (line 5). As its name suggests, the Awaitable
std::suspends_always causes the coroutine to pause immediately. Let me return
std::suspend_never instead of
yield_value(line 8) is invoked. A subsequent call
gen.getNextValue()(line 12) resumes the coroutine and triggers the execution of the member function
yield_valueonce more. The start value 10 is ignored, and the coroutine returns 20, 30, and 40.
yield_value Never Suspends
co_yield valueand prepares the current_value (line 9). The function returns the Awaitable
std::suspend_always(line 10) and pauses the coroutine. Consequently, a subsequent call
gen.getNextValue(line 12) has to resume the coroutine. When I change the return value of the member function
std::suspend_never, let me see what happens.
So far, I have never used the fact that the coroutine is a class template. In my next post, I restructure the generator to produce a finite number of arbitrary values.
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, and Marco Parri Empoli.
Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.
|My special thanks to Embarcadero|
|My special thanks to PVS-Studio|
|My special thanks to Tipi.build|
|My special thanks to Take Up Code|
I’m happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
- Embedded Programmierung mit modernem C++ 12.12.2023 – 14.12.2023 (Präsenzschulung, Termingarantie)
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
- C++ – The Core Language
- C++ – The Standard Library
- C++ – Compact
- C++11 and C++14
- Concurrency with Modern C++
- Design Pattern and Architectural Pattern with C++
- Embedded Programming with Modern C++
- Generic Programming (Templates) with C++
- Clean Code with Modern C++
- Phone: +49 7472 917441
- Mobil:: +49 176 5506 5086
- Mail: schulung@ModernesCpp.de
- German Seminar Page: www.ModernesCpp.de
- Mentoring Page: www.ModernesCpp.org
Modernes C++ Mentoring,