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
jh::async Namespace Reference

Aggregated entry point for coroutine-based asynchronous facilities. More...

Classes

struct  resume_t
 Tag type used to trigger a co_await inside a fiber. More...
class  fiber
 Coroutine-based fiber providing manual suspension and resumption. More...
class  generator
 Coroutine-based generator supporting both yielding and receiving values. More...
class  generator_range
 A range-like wrapper that enables iteration over a generator factory. More...
class  listener
 A one-shot inbox that serves as the fan-in aggregation point. More...
class  slot
 Coroutine representing the user-defined asynchronous state machine. More...
class  slot_hub
 Synchronization domain managing timed mutex acquisition and binding exactly one slot. More...
class  event_signal
 Lightweight push-only event emitter. More...

Functions

template<concepts::sequence SeqType>
generator< concepts::sequence_value_t< SeqType > > 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 > > make_generator (R &&rng)
 Converts a standard range into a generator.
template<typename T>
std::vector< T > to_vector (generator< T > &gen)
 Collects all yielded values from a generator into a std::vector.
template<typename T, typename U>
std::vector< T > 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 > 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 > to_deque (generator< T > &gen)
 Collects all yielded values from a generator into a std::deque.
template<typename T, typename U>
std::deque< T > 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 > 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.

Variables

resume_t resume_tag {}
 Global constant instance of resume_t.

Detailed Description

Aggregated entry point for coroutine-based asynchronous facilities.

The <jh/async> forwarding header provides a unified, engineering-oriented interface over the coroutine-based asynchronous components implemented under jh/asynchronous/.
Rather than exposing raw coroutine primitives, this module presents constrained and semantically well-defined abstractions such as generators, fibers, and coroutine-backed signal slots.
This header is the recommended user-facing entry point as of v1.4.0. Individual component headers remain fully supported.

Function Documentation

◆ make_generator() [1/2]

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.

This overload provides the most permissive fallback version of make_generator(). It accepts any type that satisfies the minimal jh::sequence concept: having begin() and end() returning readable iterators and supporting != comparison.

Unlike std::ranges::range, a jh::sequence does not guarantee forwarding or lifetime semantics โ€” only that it can be read immutably. Therefore, this overload uses const reference and avoids forwarding or move-based iteration.

  • Acts as a duck-typed fallback for legacy or lightweight containers that behave like ranges but are not formally defined as such.
  • Preserves the minimal safety invariant: iteration must not mutate seq.
  • Ensures compatibility with immutable const iteration even in non-range-conforming types.
Template Parameters
SeqTypeThe input sequence type; must satisfy jh::sequence but not std::ranges::range.
Parameters
seqThe sequence-like object to convert (read-only).
Returns
A generator yielding elements from seq.

◆ make_generator() [2/2]

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.

This overload handles any type satisfying the C++20 std::ranges::range concept. It directly consumes the range by iteration, yielding each element via co_yield.

Because range guarantees valid lifetime and iterator semantics, this overload may safely take the range by universal reference and use std::forward to preserve value category.

  • Preserves const correctness and supports read-only iteration.
  • Allows moving temporary or view-based ranges directly into the coroutine โ€” the generator takes ownership of the iteration sequence.
  • Unlike the sequence overload, this version fully supports forwarded rvalue ranges and lazy views.
Template Parameters
RA valid std::ranges::range type.
Parameters
rngThe range object or view to convert.
Returns
A generator yielding elements from rng.

◆ to_deque() [1/3]

template<typename T>
std::deque< T > jh::async::to_deque ( generator< T > & gen)

Collects all yielded values from a generator into a std::deque.

This overload applies to generators that produce values but do not receive input (U == typed::monostate). It repeatedly advances the coroutine using next() until completion, appending each yielded element into a std::deque.

  • Designed for output-only generators.
  • Maintains stable iterator validity across insertions.
  • Uses the fastest STL segmented linear container, ideal for frequent push_back() operations.
Template Parameters
TThe generator's yielded value type.
Parameters
genThe generator instance to collect from.
Returns
A std::deque containing all yielded elements in order.

◆ to_deque() [2/3]

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.

This overload supports generators that consume varying inputs. It sequentially sends each element from inputs to the generator via send() and appends the produced values into a deque.

  • Synchronizes one send() per yielded element.
  • Terminates when either the input range or generator is exhausted.
  • Deque is optimal for dynamic growth and stable iteration under expansion.

The inputs parameter must satisfy std::ranges::range. Nevertheless, any duck-typed sequence that conforms to jh::sequence can be wrapped via jh::to_range():

auto dq = jh::async::to_deque(gen, jh::to_range(my_sequence));
std::deque< T > to_deque(generator< T > &gen)
Collects all yielded values from a generator into a std::deque.
Definition generator.h:921
auto to_range(F &&f)
Converts a generator factory (lambda or function) into a repeatable range.
Definition generator.h:1195

This allows compatibility with user-defined containers that are not formally std::ranges::range but still support begin()/end().

Template Parameters
TThe generator's output type (co_yield value type).
RA std::ranges::range of input values sent to the generator.
Parameters
genThe generator to consume.
inputsThe input range providing values for each step.
Returns
A std::deque containing all yielded results in sequence.

◆ to_deque() [3/3]

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.

This overload supports interactive generators that expect an input type (U != typed::monostate). It sends the same input value at every coroutine step via send(), pushing each yielded element into a std::deque.

  • Each iteration performs next() then send(input_value).
  • Efficient for streaming pipelines where append cost must remain amortized O(1).
  • Deque preserves all references and pointers to existing elements upon reallocation.
Template Parameters
TThe yielded value type.
UThe input type accepted by the generator.
Parameters
genThe generator to consume.
input_valueThe fixed input sent at each step.
Returns
A std::deque containing all yielded values.

◆ to_vector() [1/3]

template<typename T>
std::vector< T > jh::async::to_vector ( generator< T > & gen)

Collects all yielded values from a generator into a std::vector.

This overload applies to generators that produce values but do not receive input (U == typed::monostate). It repeatedly advances the coroutine using next() until completion, copying each yielded value into a contiguous std::vector.

  • Intended for output-only generators.
  • Preserves iteration order and copies each yielded element.
  • Acts as the most lightweight way to "materialize" a generator sequence.
Template Parameters
TThe generator's yielded value type.
Parameters
genThe generator instance to collect from.
Returns
A std::vector containing all yielded elements in order.

◆ to_vector() [2/3]

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.

This overload supports generators that consume varying inputs. It sequentially sends each element from inputs to the generator via send() and accumulates the produced values into a vector.

  • Synchronizes one send() call per yielded element.
  • Terminates when either the input range or generator is exhausted.
  • Ensures order-preserving correspondence between inputs and outputs.

This function formally requires inputs to satisfy std::ranges::range. However, any duck-typed sequence that conforms to the jh::sequence concept can be made compatible by wrapping it with jh::to_range():

auto vec = jh::async::to_vector(gen, jh::to_range(my_sequence));
std::vector< T > to_vector(generator< T > &gen)
Collects all yielded values from a generator into a std::vector.
Definition generator.h:804

This design ensures that legacy containers and lightweight sequence-like types remain usable in generator pipelines without requiring full std::ranges compliance.

Template Parameters
TThe generator's output type (co_yield value type).
RA std::ranges::range of input values sent to the generator.
Parameters
genThe generator to consume.
inputsThe input range providing values for each step.
Returns
A std::vector containing all yielded results in sequence.

◆ to_vector() [3/3]

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.

This overload supports interactive generators that expect an input type (U != typed::monostate). It sends the same input value at every coroutine step via send(), producing a deterministic output sequence.

  • Each iteration performs next() then send(input_value).
  • Useful for constant-parameter simulations or iterative transforms.
  • If the generator terminates early, iteration stops gracefully.
Template Parameters
TThe yielded value type.
UThe input type accepted by the generator.
Parameters
genThe generator to consume.
input_valueThe fixed input sent at each step.
Returns
A std::vector containing all yielded values.