JH-Toolkit v1.4.1
An engineering-oriented C++20 toolkit with duck-typed concepts, static design, async coroutines, and semantic containers — header-only, RTTI-free, and concurrency-friendly.
Loading...
Searching...
No Matches
generator.h File Reference

Coroutine-based generator system for modern C++20. More...

#include <coroutine>
#include <functional>
#include <deque>
#include <optional>
#include <stdexcept>
#include <utility>
#include <vector>
#include <memory>
#include "jh/conceptual/sequence.h"
#include "jh/conceptual/iterator.h"
#include "jh/typing/monostate.h"

Go to the source code of this file.

Classes

class  jh::async::generator< T, U >
 Coroutine-based generator supporting both yielding and receiving values. More...
struct  jh::async::generator< T, U >::iterator
struct  jh::async::generator< T, U >::promise_type
struct  jh::async::generator< T, U >::promise_type::awaiter
 Lightweight awaiter used to deliver values sent into the generator via co_await. More...
class  jh::async::generator_range< T >
 A range-like wrapper that enables iteration over a generator factory. More...
class  jh::async::generator_range< T >::iterator

Namespaces

namespace  jh::async
 Aggregated entry point for coroutine-based asynchronous facilities.

Functions

template<concepts::sequence SeqType>
generator< concepts::sequence_value_t< SeqType > > jh::async::make_generator (const SeqType &seq)
 Converts a duck-typed sequence-like object into a generator.
template<std::ranges::range R>
generator< std::ranges::range_value_t< R > > jh::async::make_generator (R &&rng)
 Converts a standard range into a generator.
template<typename T>
std::vector< T > jh::async::to_vector (generator< T > &gen)
 Collects all yielded values from a generator into a std::vector.
template<typename T, typename U>
std::vector< T > jh::async::to_vector (generator< T, U > &gen, U input_value)
 Collects all yielded values into a std::vector using a fixed input value.
template<typename T, std::ranges::range R>
std::vector< T > jh::async::to_vector (generator< T, std::ranges::range_value_t< R > > &gen, const R &inputs)
 Collects all yielded values into a std::vector using a sequence of input values.
template<typename T>
std::deque< T > jh::async::to_deque (generator< T > &gen)
 Collects all yielded values from a generator into a std::deque.
template<typename T, typename U>
std::deque< T > jh::async::to_deque (generator< T, U > &gen, U input_value)
 Collects all yielded values into a std::deque using a fixed input value.
template<typename T, std::ranges::range R>
std::deque< T > jh::async::to_deque (generator< T, std::ranges::range_value_t< R > > &gen, const R &inputs)
 Collects all yielded values into a std::deque using a sequence of input values.
template<typename F>
auto jh::to_range (F &&f)
 Converts a generator factory (lambda or function) into a repeatable range.

Detailed Description

Coroutine-based generator system for modern C++20.

Author
JeongHan-Bae <mastropseudo@gmail.com>

Overview

This header defines jh::async::generator<T, U>, a coroutine-based generator inspired by Python's Generator[T, U, R] type.
It provides both value-yielding (co_yield) and interactive (send()) semantics while keeping the implementation fully type-safe, constexpr-friendly, and header-only.

Namespace Design

This version lives under the jh::async namespace, to emphasize that the generator is coroutine-based and semantically asynchronous.
However, because generator is also a foundational utility, you may include <jh/generator> to import it into jh directly.

Include Behavior

Design Motivation

In Python, Generator[T, U, R] expresses three roles:

  • T — values yielded by the generator.
  • U — values sent into the generator.
  • R — the value returned when the generator finishes.

However, Python's R is not a true return value — it is part of the coroutine exit mechanism (an exception-based control path). In C++, such behavior can be cleanly modeled using standard exception handling (try/catch). Therefore, JH's generator<T, U> intentionally omits R to simplify design and align with idiomatic C++ coroutine semantics.

Core Concepts

  • Yield type (T) — values produced by co_yield, accessible via generator.value() as std::optional<T>. The optional may be empty if the coroutine has completed.

  • Await type (U) — values received by co_await, corresponding to inputs provided through send() or send_ite().

  • Return type (R) — intentionally omitted. In Python's Generator[T, U, R] model, R represents a special termination channel, but in C++ it can be naturally handled via try/catch and normal function return semantics. Thus, jh::async::generator<T, U> omits R entirely.

Key Features

  • Coroutine-based generator with full C++20 support.
  • Supports both iterative (next()) and interactive (send()) control.
  • Range-compatible iteration for non-input generators (U == monostate).
  • Conversion utilities for std::vector, std::deque, and range wrapping.
  • Designed for POD-safe, header-only use in low-overhead data pipelines.

Usage Notes

  • Generators are single-pass — iteration consumes them.
  • Copying is disallowed (coroutine handles are unique and non-shareable).
  • Prefer POD or trivially copyable types for best performance.
  • U defaults to typed::monostate (no input behavior).
Version
1.3.x
Date
2025