[coro.generator]

# 25 Ranges library [[ranges]](./#ranges)

## 25.8 Range generators [coro.generator]

### [25.8.1](#coroutine.generator.overview) Overview [[coroutine.generator.overview]](coroutine.generator.overview)

[1](#coroutine.generator.overview-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18041)

Class template generator presents
a view of the elements yielded by the evaluation of a coroutine[.](#coroutine.generator.overview-1.sentence-1)

[2](#coroutine.generator.overview-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18045)

A generator generates a sequence of elements by
repeatedly resuming the coroutine from which it was returned[.](#coroutine.generator.overview-2.sentence-1)

Elements of the sequence are produced by the coroutine
each time a co_yield statement is evaluated[.](#coroutine.generator.overview-2.sentence-2)

When the co_yield statement is of the formco_yield elements_of(r),
each element of the range r is successively produced as an element of the sequence[.](#coroutine.generator.overview-2.sentence-3)

[*Example [1](#coroutine.generator.overview-example-1)*: generator<int> ints(int start = 0) {while (true)co_yield start++;}void f() {for (auto i : ints() | views::take(3)) cout << i << ' '; // prints 0 1 2} â *end example*]

### [25.8.2](#generator.syn) Header <generator> synopsis [[generator.syn]](generator.syn)

[ð](#header:%3cgenerator%3e)

namespace std {// [[coro.generator.class]](#class "25.8.3 Class template generator"), class template generatortemplate<class Ref, class Val = void, class Allocator = void>class generator; namespace pmr {template<class Ref, class Val = void>using generator = std::generator<Ref, Val, polymorphic_allocator<>>; }}

### [25.8.3](#class) Class template generator [[coro.generator.class]](coro.generator.class)

namespace std {template<class Ref, class Val = void, class Allocator = void>class [generator](#lib:generator "25.8.3 Class template generator [coro.generator.class]") : public ranges::view_interface<generator<Ref, Val, Allocator>> {private:using *value* = conditional_t<is_void_v<Val>, remove_cvref_t<Ref>, Val>; // *exposition only*using *reference* = conditional_t<is_void_v<Val>, Ref&&, Ref>; // *exposition only*// [[coro.generator.iterator]](#iterator "25.8.6 Class generator​::​iterator"), class generator​::​*iterator*class *iterator*; // *exposition only*public:using yielded = conditional_t<is_reference_v<*reference*>, *reference*, const *reference*&>; // [[coro.generator.promise]](#promise "25.8.5 Class generator​::​promise_­type"), class generator​::​promise_typeclass promise_type;

 generator(const generator&) = delete;
 generator(generator&& other) noexcept; ~generator();

 generator& operator=(generator other) noexcept; *iterator* begin();
 default_sentinel_t end() const noexcept; private: coroutine_handle<promise_type> *coroutine_* = nullptr; // *exposition only* unique_ptr<stack<coroutine_handle<>>> *active_*; // *exposition only*};}

[1](#class-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18121)

*Mandates*: 

- [(1.1)](#class-1.1)

  If Allocator is not void,allocator_traits<Allocator>​::​pointer is a pointer type[.](#class-1.1.sentence-1)

- [(1.2)](#class-1.2)

  *value* is a cv-unqualified object type[.](#class-1.2.sentence-1)

- [(1.3)](#class-1.3)

  *reference* is either a reference type, or
a cv-unqualified object type that models [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_­constructible [concept.copyconstructible]")[.](#class-1.3.sentence-1)

- [(1.4)](#class-1.4)

  Let RRef denote remove_reference_t<*reference*>&& if *reference* is a reference type,
and *reference* otherwise[.](#class-1.4.sentence-1)
  Each of:
  * [(1.4.1)](#class-1.4.1)

[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_­reference_­with [concept.commonref]")<*reference*&&, *value*&>,

  * [(1.4.2)](#class-1.4.2)

[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_­reference_­with [concept.commonref]")<*reference*&&, RRef&&>, and

  * [(1.4.3)](#class-1.4.3)

[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_­reference_­with [concept.commonref]")<RRef&&, const *value*&>

is modeled[.](#class-1.4.sentence-2)
  [*Note [1](#class-note-1)*:
  These requirements ensure the exposition-only *iterator* type
can model [indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]") and thus [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]")[.](#class-1.4.sentence-3)
 â *end note*]

[2](#class-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18149)

If Allocator is not void,
it shall meet the *Cpp17Allocator* requirements[.](#class-2.sentence-1)

[3](#class-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18153)

Specializations of generator model[view](range.view#concept:view "25.4.5 Views [range.view]") and [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")[.](#class-3.sentence-1)

[4](#class-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18157)

The behavior of a program that adds a specialization
for generator is undefined[.](#class-4.sentence-1)

### [25.8.4](#members) Members [[coro.generator.members]](coro.generator.members)

[ð](#lib:generator,constructor)

`generator(generator&& other) noexcept;
`

[1](#members-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18169)

*Effects*: Initializes *coroutine_* withexchange(other.*coroutine_*, {}) and*active_* withexchange(​other.*active_*, nullptr)[.](#members-1.sentence-1)

[2](#members-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18176)

[*Note [1](#members-note-1)*:

Iterators previously obtained from other are not invalidated;
they become iterators into *this[.](#members-2.sentence-1)

â *end note*]

[ð](#lib:generator,destructor)

`~generator();
`

[3](#members-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18189)

*Effects*: Equivalent to:if (*coroutine_*) {*coroutine_*.destroy();}

[4](#members-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18198)

[*Note [2](#members-note-2)*:

Ownership of recursively yielded generators
is held in awaitable objects
in the coroutine frame of the yielding generator,
so destroying the root generator
effectively destroys the entire stack of yielded generators[.](#members-4.sentence-1)

â *end note*]

[ð](#lib:operator=,generator)

`generator& operator=(generator other) noexcept;
`

[5](#members-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18214)

*Effects*: Equivalent to:swap(*coroutine_*, other.*coroutine_*);
swap(*active_*, other.*active_*);

[6](#members-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18222)

*Returns*: *this[.](#members-6.sentence-1)

[7](#members-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18226)

[*Note [3](#members-note-3)*:

Iterators previously obtained from other are not invalidated;
they become iterators into *this[.](#members-7.sentence-1)

â *end note*]

[ð](#lib:begin,generator)

`iterator begin();
`

[8](#members-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18239)

*Preconditions*: *coroutine_* refers to a coroutine
suspended at its initial suspend point ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4 Coroutine definitions"))[.](#members-8.sentence-1)

[9](#members-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18244)

*Effects*: Pushes *coroutine_* into **active_*,
then evaluates *coroutine_*.resume()[.](#members-9.sentence-1)

[10](#members-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18249)

*Returns*: An *iterator* object
whose member *coroutine_* refers to the same coroutine as does*coroutine_*[.](#members-10.sentence-1)

[11](#members-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18256)

[*Note [4](#members-note-4)*:

A program that calls begin more than once on the same generator
has undefined behavior[.](#members-11.sentence-1)

â *end note*]

[ð](#lib:end,generator)

`default_sentinel_t end() const noexcept;
`

[12](#members-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18269)

*Returns*: default_sentinel[.](#members-12.sentence-1)

### [25.8.5](#promise) Class generator​::​promise_type [[coro.generator.promise]](coro.generator.promise)

namespace std {template<class Ref, class Val, class Allocator>class generator<Ref, Val, Allocator>::promise_type {public: generator get_return_object() noexcept;

 suspend_always initial_suspend() const noexcept { return {}; }auto final_suspend() noexcept;

 suspend_always yield_value(yielded val) noexcept; auto yield_value(const remove_reference_t<yielded>& lval)requires is_rvalue_reference_v<yielded> &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_­from [concept.constructible]")<remove_cvref_t<yielded>, const remove_reference_t<yielded>&>; template<class R2, class V2, class Alloc2, class Unused>requires [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<typename generator<R2, V2, Alloc2>::yielded, yielded>auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept; template<class R2, class V2, class Alloc2, class Unused>requires [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<typename generator<R2, V2, Alloc2>::yielded, yielded>auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&, Unused> g) noexcept; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Alloc>requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<ranges::range_reference_t<R>, yielded>auto yield_value(ranges::elements_of<R, Alloc> r); void await_transform() = delete; void return_void() const noexcept {}void unhandled_exception(); void* operator new(size_t size)requires [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<Allocator, void> || [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_­initializable [concept.default.init]")<Allocator>; template<class Alloc, class... Args>void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...); template<class This, class Alloc, class... Args>void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc, const Args&...); void operator delete(void* pointer, size_t size) noexcept; private: add_pointer_t<yielded> *value_* = nullptr; // *exposition only* exception_ptr *except_*; // *exposition only*};}

[ð](#lib:get_return_object,generator::promise_type)

`generator get_return_object() noexcept;
`

[1](#promise-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18333)

*Returns*: A generator object whose member *coroutine_* is coroutine_handle<promise_type>​::​​from_promise(*this),
and whose member *active_* points to an empty stack[.](#promise-1.sentence-1)

[ð](#lib:final_suspend,generator::promise_type)

`auto final_suspend() noexcept;
`

[2](#promise-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18346)

*Preconditions*: A handle referring to the coroutine
whose promise object is *this is at the top of **active_* of some generator object x[.](#promise-2.sentence-1)

This function is called by that coroutine
upon reaching its final suspend point ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4 Coroutine definitions"))[.](#promise-2.sentence-2)

[3](#promise-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18355)

*Returns*: An awaitable object of unspecified type ([[expr.await]](expr.await "7.6.2.4 Await"))
whose member functions arrange for the
calling coroutine to be suspended,
pop the coroutine handle
from the top of *x.*active_*,
and resume execution of the coroutine referred to byx.*active_*->top() if *x.*active_* is not empty[.](#promise-3.sentence-1)

If it is empty, control flow returns to the
current coroutine caller or resumer ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4 Coroutine definitions"))[.](#promise-3.sentence-2)

[ð](#lib:yield_value,generator::promise_type)

`suspend_always yield_value(yielded val) noexcept;
`

[4](#promise-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18375)

*Effects*: Equivalent to *value_* = addressof(val)[.](#promise-4.sentence-1)

[5](#promise-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18379)

*Returns*: {}[.](#promise-5.sentence-1)

[ð](#lib:yield_value,generator::promise_type_)

`auto yield_value(const remove_reference_t<yielded>& lval)
  requires is_rvalue_reference_v<yielded> &&
    [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_­from [concept.constructible]")<remove_cvref_t<yielded>, const remove_reference_t<yielded>&>;
`

[6](#promise-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18392)

*Preconditions*: A handle referring to the coroutine
whose promise object is *this is at the top of **active_* of some generator object[.](#promise-6.sentence-1)

[7](#promise-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18399)

*Returns*: An awaitable object of an unspecified type ([[expr.await]](expr.await "7.6.2.4 Await"))
that stores an object of type remove_cvref_t<yielded> direct-non-list-initialized with lval,
whose member functions arrange for*value_* to point to that stored object
and then suspend the coroutine[.](#promise-7.sentence-1)

[8](#promise-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18408)

*Throws*: Any exception thrown by the initialization of the stored object[.](#promise-8.sentence-1)

[9](#promise-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18412)

*Remarks*: A [*yield-expression*](expr.yield#nt:yield-expression "7.6.17 Yielding a value [expr.yield]") that calls this function
has type void ([[expr.yield]](expr.yield "7.6.17 Yielding a value"))[.](#promise-9.sentence-1)

[ð](#lib:yield_value,generator::promise_type__)

`template<class R2, class V2, class Alloc2, class Unused>
  requires [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<typename generator<R2, V2, Alloc2>::yielded, yielded>
  auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept;
template<class R2, class V2, class Alloc2, class Unused>
  requires [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<typename generator<R2, V2, Alloc2>::yielded, yielded>
  auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&, Unused> g) noexcept;
`

[10](#promise-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18429)

*Preconditions*: A handle referring to the coroutine
whose promise object is *this is at the top of **active_* of some generator object x[.](#promise-10.sentence-1)

The coroutine referred to byg.range.*coroutine_* is suspended at its initial suspend point[.](#promise-10.sentence-2)

[11](#promise-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18439)

*Returns*: An awaitable object of an unspecified type ([[expr.await]](expr.await "7.6.2.4 Await"))
into which g.range is moved,
whose member await_ready returns false,
whose member await_suspend pushes g.range.*coroutine_* into *x.*active_* and resumes execution of the coroutine referred to
by g.range.​*coroutine_*, and
whose member await_resume evaluatesrethrow_exception(*except_*) if bool(*except_*) is true[.](#promise-11.sentence-1)

If bool(*except_*) is false,
the await_resume member has no effects[.](#promise-11.sentence-2)

[12](#promise-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18456)

*Remarks*: A [*yield-expression*](expr.yield#nt:yield-expression "7.6.17 Yielding a value [expr.yield]") that calls one of these functions
has type void ([[expr.yield]](expr.yield "7.6.17 Yielding a value"))[.](#promise-12.sentence-1)

[ð](#lib:yield_value,generator::promise_type___)

`template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Alloc>
  requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<ranges::range_reference_t<R>, yielded>
  auto yield_value(ranges::elements_of<R, Alloc> r);
`

[13](#promise-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18470)

*Effects*: Equivalent to:auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t<R> i, ranges::sentinel_t<R> s)-> generator<yielded, void, Alloc> {for (; i != s; ++i) {co_yield static_cast<yielded>(*i); }};return yield_value(ranges::elements_of(nested( allocator_arg, r.allocator, ranges::begin(r.range), ranges::end(r.range))));

[14](#promise-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18484)

[*Note [1](#promise-note-1)*:

A [*yield-expression*](expr.yield#nt:yield-expression "7.6.17 Yielding a value [expr.yield]") that calls this function
has type void ([[expr.yield]](expr.yield "7.6.17 Yielding a value"))[.](#promise-14.sentence-1)

â *end note*]

[ð](#lib:unhandled_exception,generator::promise_type)

`void unhandled_exception();
`

[15](#promise-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18497)

*Preconditions*: A handle referring to the coroutine whose promise object is *this is at the top of **active_* of some generator object x[.](#promise-15.sentence-1)

[16](#promise-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18503)

*Effects*: If the handle referring to the coroutine
whose promise object is *this is the sole element of *x.*active_*,
equivalent to throw,
otherwise, assigns current_exception() to *except_*[.](#promise-16.sentence-1)

[ð](#lib:operator_new,generator::promise_type)

`void* operator new(size_t size)
  requires [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<Allocator, void> || [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_­initializable [concept.default.init]")<Allocator>;

template<class Alloc, class... Args>
  void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...);

template<class This, class Alloc, class... Args>
  void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc,
                     const Args&...);
`

[17](#promise-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18526)

Let A be

- [(17.1)](#promise-17.1)

Allocator, if it is not void,

- [(17.2)](#promise-17.2)

Alloc for the overloads with a template parameter Alloc, or

- [(17.3)](#promise-17.3)

allocator<void> otherwise[.](#promise-17.sentence-1)

Let B be allocator_traits<A>​::​template rebind_alloc<U> where U is an unspecified type whose size and alignment
are both __STDCPP_DEFAULT_NEW_ALIGNMENT__[.](#promise-17.sentence-2)

[18](#promise-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18540)

*Mandates*: allocator_traits<B>​::​pointer is a pointer type[.](#promise-18.sentence-1)

For the overloads with a template parameter Alloc,[same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<Allocator, void> || [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const Alloc&, Allocator> is modeled[.](#promise-18.sentence-2)

[19](#promise-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18547)

*Effects*: Initializes an allocator b of type B with A(alloc),
for the overloads with a function parameter alloc,
and with A() otherwise[.](#promise-19.sentence-1)

Uses b to allocate storage for the smallest array
of U sufficient to provide storage for
a coroutine state of size size, and
unspecified additional state necessary to ensure thatoperator delete can later deallocate this memory block
with an allocator equal to b[.](#promise-19.sentence-2)

[20](#promise-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18559)

*Returns*: A pointer to the allocated storage[.](#promise-20.sentence-1)

[ð](#lib:operator_delete,generator::promise_type)

`void operator delete(void* pointer, size_t size) noexcept;
`

[21](#promise-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18570)

*Preconditions*: pointer was returned from an invocation of
one of the above overloads of operator new with a size argument equal to size[.](#promise-21.sentence-1)

[22](#promise-22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18576)

*Effects*: Deallocates the storage pointed to by pointer using an allocator equivalent to that used to allocate it[.](#promise-22.sentence-1)

### [25.8.6](#iterator) Class generator​::​*iterator* [[coro.generator.iterator]](coro.generator.iterator)

namespace std {template<class Ref, class Val, class Allocator>class generator<Ref, Val, Allocator>::*iterator* {public:using value_type = *value*; using difference_type = ptrdiff_t; *iterator*(*iterator*&& other) noexcept; *iterator*& operator=(*iterator*&& other) noexcept; *reference* operator*() const noexcept(is_nothrow_copy_constructible_v<*reference*>); *iterator*& operator++(); void operator++(int); friend bool operator==(const *iterator*& i, default_sentinel_t); private: coroutine_handle<promise_type> *coroutine_*; // *exposition only*};}

[ð](#lib:generator::iterator,constructor)

`iterator(iterator&& other) noexcept;
`

[1](#iterator-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18613)

*Effects*: Initializes *coroutine_* with exchange(other.*coroutine_*, {})[.](#iterator-1.sentence-1)

[ð](#lib:operator=,generator::iterator)

`iterator& operator=(iterator&& other) noexcept;
`

[2](#iterator-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18625)

*Effects*: Equivalent to*coroutine_* = exchange(other.*coroutine_*, {})[.](#iterator-2.sentence-1)

[3](#iterator-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18630)

*Returns*: *this[.](#iterator-3.sentence-1)

[ð](#lib:operator*,generator::iterator)

`reference operator*() const noexcept(is_nothrow_copy_constructible_v<reference>);
`

[4](#iterator-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18641)

*Preconditions*: For some generator object x,*coroutine_* is in *x.*active_* andx.*active_*->top() refers to
a suspended coroutine with promise object p[.](#iterator-4.sentence-1)

[5](#iterator-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18648)

*Effects*: Equivalent to:return static_cast<*reference*>(*p.*value_*);

[ð](#lib:operator++,generator::iterator)

`iterator& operator++();
`

[6](#iterator-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18660)

*Preconditions*: For some generator object x,*coroutine_* is in *x.*active_*[.](#iterator-6.sentence-1)

[7](#iterator-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18665)

*Effects*: Equivalent to x.*active_*->top().resume()[.](#iterator-7.sentence-1)

[8](#iterator-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18669)

*Returns*: *this[.](#iterator-8.sentence-1)

[ð](#lib:operator++,generator::iterator_)

`void operator++(int);
`

[9](#iterator-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18680)

*Effects*: Equivalent to ++*this[.](#iterator-9.sentence-1)

[ð](#lib:operator==,generator::iterator)

`friend bool operator==(const iterator& i, default_sentinel_t);
`

[10](#iterator-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18691)

*Effects*: Equivalent to: return i.*coroutine_*.done();
