Standard Library Views

Using Views with C++20 Coroutines

How do views interact with C++20's coroutines?

Abstract art representing computer programming

C++20's coroutines and views can work together to create powerful, lazy-evaluated pipelines for data processing. Coroutines allow you to define sequences of values that can be produced on-demand, and views can consume these sequences efficiently.

Example: Using a Coroutine with a View

Here’s a simple example of a coroutine that generates an infinite sequence of numbers, which can be consumed by a view:

#include <coroutine>
#include <iostream>
#include <ranges>

class Generator {
 public:
  struct promise_type {
    int value_;
    std::suspend_always yield_value(int value) {
      value_ = value;
      return {};
    }

    std::suspend_always initial_suspend() {
      return {};
    }

    std::suspend_always final_suspend() noexcept {
      return {};
    }

    void unhandled_exception() {
      std::terminate();
    }

    Generator get_return_object() {
      return Generator{std::coroutine_handle<
        promise_type>::from_promise(*this)};
    }

    void return_void() {}
  };

  using handle_type =
    std::coroutine_handle<promise_type>;

  handle_type coro_;

  Generator(handle_type h) : coro_(h) {}
  ~Generator() {
    if (coro_) coro_.destroy();
  }

  bool next() {
    coro_.resume();
    return !coro_.done();
  }
  int value() const {
    return coro_.promise().value_; }
};

Generator GenerateNumbers() {
  for (int i = 1;; ++i) co_yield i;
}

int main() {
  auto gen = GenerateNumbers();

  auto view = std::views::iota(0)
    | std::views::transform([&gen](int) {
      if (gen.next()) return gen.value();
        return -1;  // Placeholder value
      });

  for (int x : view | std::views::take(10)) {
    std::cout << x << ", ";
  }
}
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,

Explanation

  • Generator Class: Implements the coroutine generator. It uses std::coroutine_handle to manage the coroutine state.
  • GenerateNumbers: A coroutine function that yields an infinite sequence of numbers.
  • View Usage: Combines the coroutine with a view using std::views::iota and std::views::transform to produce the sequence.

Benefits

  • Lazy Evaluation: Coroutines produce values on-demand, which aligns well with the lazy nature of views.
  • Efficiency: Only the needed values are generated and processed, reducing overhead.

Combining coroutines and views can help create highly efficient and readable code for complex data processing tasks.

Answers to questions are automatically generated and may not have been reviewed.

Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved