hmontero1205 / cpp20-coro-generator

Example of a C++20 coroutine implementing a Fibonacci Sequence generator (using clang++ v9.0.0)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Exploring C++20 coroutines (using Clang++ 9.0.0)

Introduction

A simple program implementing one specific capability of C++20 coroutines - a generator.

This generator example generates the Fibonacci Sequence up to some specified ceiling.

Description

Here is the function - its the use of co_yield that make it a C++20 coroutine (as opposed to an ordinary function):

    generator<double> fibonacci(const double ceiling) {
      double j = 0;
      double i = 1;
      co_yield j;
      if (ceiling > j) {
        do {
          co_yield i;
          double tmp = i;
          i += j;
          j = tmp;
        } while (i <= ceiling);
      }
    }

The generator function's return value generator<double> is an iterator for the type of its template argument. In this programming example it is using the template class coro_exp::generator<> which the implementation of is provided. However, the C++20 standard is specifying std::generator<>1, but it is not available in the Clang++ (9.0.0) experimental implementation yet.

NOTE: The template class coro_exp::generator<> has been customized off of Rainer Grimm's implementation.2

Here is code that consumes generated values from fibonacci():

    const double demo_ceiling = 10E44;

    auto iter = fibonacci(demo_ceiling);

    while(iter.next()) {
      const auto value = iter.getValue();
      std::cout << value << '\n';
    }

This will print out 217 values of the Fibonacci Sequence.

The consuming code and the generator code are executing on the same thread context and yet the fibonacci() function enjoys a preserved local scope state as it executes and then resumes from co_yield. The generator function just falls out of the loop when the specified ceiling is exceeded to terminate itself - the consuming code will detect this in the while(iter.next()) {...} loop condition and fall out of the loop.

Building the program

The program can be built with cmake as a CMakeLists.txt file is provided. Because it depends on using a Clang C++ compiler that has the experimental implementation of coroutines, will need to insure that the cmake variable CMAKE_CXX_COMPILER is suitably defined to clang++.

I installed Clang/LLVM from the version 9.0.0 pre-built binary distribution3. On my Ubuntu Linux 18.04 I had to also install libtinfo54, which clang required:

    sudo apt-get install libtinfo5

Adjust accordingly to suit your environment.

1: cppreference.com - Coroutines (C++20)

2: Rainer Grimm, Concurrency with Modern C++ (Leanpub, 2017 - 2019), 207-209.

3: Clang-LLVM downloads

4: libtinfo5 package

About

Example of a C++20 coroutine implementing a Fibonacci Sequence generator (using clang++ v9.0.0)

License:MIT License


Languages

Language:C++ 82.6%Language:CMake 17.4%