std::generator(3)
hiii bestie π this is std::generator(3) from the C++ Standard Libary β manual name folded in near the top, and we're about to make this coroutine generator page make sense β¨
π NAME π
std::generator - std::generator β that's the name, bestie, no cap π
π¦ Synopsis π¦
okay so first: Defined in header <generator>, periodt. Then we got the main character template (1) (since C++23):
template<
class Ref,
class V = void,
class Allocator = void >
class generator
: public ranges::view_interface<generator<Ref, V, Allocator>>
and the pmr convenience alias (2) (since C++23) is giving:
namespace pmr {
template< class Ref, class V = void >
using generator =
std::generator<Ref, V, std::pmr::polymorphic_allocator<>>;
}
- The class template
std::generatorpresents a view of the elements yielded by the evaluation of a coroutine. iconic behavior fr fr π - Convenience alias template for the generator using the polymorphic allocator. cute and useful, we love to see it π«Ά
A std::generator generates a sequence of elements by repeatedly resuming the coroutine from which it was returned. Each time a co_yield statement is evaluated, the coroutine produces one element of the sequence. When the co_yield statement is of the form co_yield ranges::elements_of(rng), each element of the range rng is successively produced as an element of the sequence. that's the whole vibe β¨
std::generator models view and input_range β periodt π
π¨ warning, bestie: The behavior of a program that adds a specialization for std::generator is undefined. no cap, don't do it π
πΈ Template parameters πΈ
Refβ the reference type (ranges::range_reference_t) of the generator. IfVisvoid, both the reference type and the value type are inferred fromRef.Vβ the value type (range_value_t) of the generator, orvoid.Allocatorβ an allocator type orvoid.
β οΈ IfAllocatoris notvoid, then the behavior is undefined ifAllocatordoes not meet theAllocatorrequirements. read that twice, bestie π
β¨ Member types β¨
value(private) βstd::conditional_t<std::is_void_v<V>, std::remove_cvref_t<Ref>, V>;(exposition-only member type*)reference(private) βstd::conditional_t<std::is_void_v<V>, Ref&&, Ref>;(exposition-only member type*)yieldedβstd::conditional_t<std::is_reference_v<reference>, reference, const reference&>
π Type requirements π
std::allocator_traits<Allocator>::pointeris a pointer type.valueis a cv-unqualified object type.referenceis either a reference type, or a cv-unqualified object type that modelscopy_constructible.- Let
/*RRef*/denote:std::remove_reference_t</*reference*/>&&, if/*reference*/is a reference type, and/*reference*/otherwise.std::common_reference_with</*reference*/&&, /*value*/&>is modeled.std::common_reference_with</*reference*/&&, /*RRef*/&&>is modeled.std::common_reference_with</*RRef*/&&, const /*value*/&>is modeled.
π The program is ill-formed if any of these type requirements is not satisfied. not me being dramatic, that's literally what it says.
π§ Member objects π§
active_(private) β Internally, each active instance ofstd::generatoris associated with a stack (handled as if by object of typestd::unique_ptr<std::stack<std::coroutine_handle<>>>).- When
beginis called, a new stack is created and the generator is added to the stack. - When
co_yield ranges::elements_of(rng)is evaluated in a generator body,rngis converted to a generator and added to the stack that contains the enclosing generator. - When a generator iterator is incremented, the coroutine at the top of the associated stack is resumed.
- When a generator finishes (i.e. when
final_suspendis called), it is removed from the stack. (exposition-only member object*)
- When
coroutine_(private) β a handle of typestd::coroutine_handle<promise_type>(exposition-only member object*)
π₯ Member functions π₯
constructorβ constructs a generator object (public member function)destructorβ effectively destroys the entire stack of yielded generators (public member function)operator=β assigns a generator object (public member function)beginβ resumes the initially suspended coroutine and returns an iterator to its handle (public member function)endβ returnsstd::default_sentinel(public member function)
π«Ά Inherited from std::ranges::view_interface π«Ά
empty(C++20) β returns whether the derived view is empty. Provided if it satisfiessized_rangeorforward_range. (public member function ofstd::ranges::view_interface<D>)cbegin(C++23) β returns a constant iterator to the beginning of the range. (public member function ofstd::ranges::view_interface<D>)cend(C++23) β returns a sentinel for the constant iterator of the range. (public member function ofstd::ranges::view_interface<D>)operator bool(C++20) β returns whether the derived view is not empty. Provided ifranges::emptyis applicable to it. (public member function ofstd::ranges::view_interface<D>)
π Nested classes π
promise_typeβ the promise type (public member class)iteratorβ the iterator type (exposition-only member class*)
β Notes β
- Feature-test macro:
__cpp_lib_generatorβ value202207L, std(C++23), featurestd::generator β synchronous coroutine generator for ranges
π Example π
Can be tried in Compiler Explorer π
// Run this code
#include <generator>
#include <iostream>
template<typename T>
struct Tree
{
T value;
Tree *left{}, *right{};
std::generator<const T&> traverse_inorder() const
{
if (left)
for (const T& x : left->traverse_inorder())
co_yield x;
co_yield value;
if (right)
for (const T& x : right->traverse_inorder())
co_yield x;
}
};
int main()
{
Tree<char> tree[]
{
{'D', tree + 1, tree + 2},
// β
// βββββββββββββββββ΄βββββββββββββββββ
// β β
{'B', tree + 3, tree + 4}, {'F', tree + 5,
tree + 6},
// β β
// βββββββββββ΄ββββββββββββββ βββββββββββββ΄ββββββββββββββ
// β β β β
{'A'}, {'C'}, {'E'},
{'G'}
};
for (char x : tree->traverse_inorder())
std::cout << x << ' ';
std::cout << '\n';
}
Output:
A B C D E F G
π¦ References π¦
- C++23 standard (
ISO/IEC 14882:2023):26.8 Range generators [coro.generator]
π See also π
noop_coroutine(C++20) β creates a coroutine handle that has no observable effects when resumed or destroyed (function)
source: http://cppreference.com Β· version/date: 2024.06.10 Β· page: std::generator(3) πβ¨
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms