Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/coroutine/generator"

From cppreference.com
< cpp‎ | coroutine
(what's the point of these links?)
Line 48: Line 48:
 
If {{tt|Allocator}} is not {{c|void}}, then:
 
If {{tt|Allocator}} is not {{c|void}}, then:
 
* {{c|std::allocator_traits<Allocator>::pointer}} is a pointer type;
 
* {{c|std::allocator_traits<Allocator>::pointer}} is a pointer type;
* {{tt|Allocator}} meets the {{named req|LegacyAllocator}} requirements.
+
* {{tt|Allocator}} meets the {{named req|Allocator}} requirements.
  
 
===Member types===
 
===Member types===
Line 76: Line 76:
 
===Nested classes===
 
===Nested classes===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc mem class|cpp/coroutine/generator/promise|the promise type|notes={{mark c++23}}}}
+
{{dsc mem class|cpp/coroutine/generator/promise_type|the promise type|notes={{mark c++23}}}}
 
{{dsc expos mem class|cpp/coroutine/generator/iterator|the iterator type|notes={{mark c++23}}}}
 
{{dsc expos mem class|cpp/coroutine/generator/iterator|the iterator type|notes={{mark c++23}}}}
 
{{dsc end}}
 
{{dsc end}}

Revision as of 10:24, 15 February 2023

 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
 
Coroutine support
Coroutine traits
Coroutine handle
No-op coroutines
Trivial awaitables
Range generators
generator
(C++23)
 
Ranges library
Range adaptors
 
 
Defined in header <generator>
template<

    class Ref,
    class V = void,
    class Allocator = void
>

class generator : public ranges::view_interface<generator<Ref, V, Allocator>>
(1) (since C++23)
namespace pmr {

template< class Ref, class V = void >
using generator =
    std::generator<Ref, V, std::pmr::polymorphic_allocator<Ref>>;

}
(2) (since C++23)
1) The class template std::generator presents a view of the elements yielded by the evaluation of a coroutine.
2) Convenience alias template for the generator using the polymorphic allocator.

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.

std::generator models view and input_range.

The behavior of a program that adds a specialization for std::generator is undefined.

Internally, each active instance of std::generator is associated with a stack.

  • When begin is 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, rng is 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_suspend is called), it is removed from the stack.

Contents

Template parameters

Ref - a reference type
V - a value type or void
Allocator - an allocator type or void

If Allocator is not void, then:

Member types

Member type Definition
yielded (since C++23) std::conditional_t<std::is_reference_v<T>, T, const T&>
/*value*/ (private)(since C++23) std::conditional_t<std::is_void_v<V>, std::remove_cvref_t<Ref>, V>;.
/*value*/ is a cv-unqualified object type. The name is for exposition only.
/*reference*/ (private)(since C++23) std::conditional_t<std::is_void_v<V>, Ref&&, Ref>;.
/*reference*/ is either a reference type, or a cv-unqualified object type that models copy_constructible. The name is for exposition only.

Let RRef denote std::remove_reference_t</*reference*/>&& if /*reference*/ is a reference type, and /*reference*/ otherwise. The following concepts are modeled:

Member functions

constructs a generator object
(public member function) [edit]
effectively destroys the entire stack of yielded generators
(public member function) [edit]
assigns a generator object
(public member function) [edit]
resumes the initially suspended coroutine and returns an iterator to its handle
(public member function) [edit]
returns std::default_sentinel
(public member function) [edit]
Inherited from std::ranges::view_interface
returns whether the derived view is empty. Provided if it satisfies sized_range or forward_range.
(public member function of std::ranges::view_interface<D>) [edit]
(C++23)
returns a constant iterator to the beginning of the range.
(public member function of std::ranges::view_interface<D>) [edit]
(C++23)
returns a sentinel for the constant iterator of the range.
(public member function of std::ranges::view_interface<D>) [edit]
returns whether the derived view is not empty. Provided if ranges::empty is applicable to it.
(public member function of std::ranges::view_interface<D>) [edit]

Nested classes

the promise type
(public member class)
(C++23)
the iterator type
(exposition-only member class*)

Notes

Feature-test macro Value Std Feature
__cpp_lib_generator 202207L (C++23) std::generator – synchronous coroutine generator for ranges

Example

#include <generator>
#include <ranges>
#include <iostream>
 
std::generator<char> letters(char first)
{
    for (;; co_yield first++);
}
 
int main()
{
    for (const char ch : letters('a') | std::views::take(032))
        std::cout << ch << ' ';
    std::cout << '\n';
}

Output:

a b c d e f g h i j k l m n o p q r s t u v w x y z

See also

creates a coroutine handle that has no observable effects when resumed or destroyed
(function) [edit]