[coro.generator.promise]

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

## 25.8 Range generators [[coro.generator]](coro.generator#promise)

### 25.8.5 Class generator​::​promise_type [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](#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[.](#1.sentence-1)

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

`auto final_suspend() noexcept;
`

[2](#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[.](#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"))[.](#2.sentence-2)

[3](#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[.](#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"))[.](#3.sentence-2)

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

`suspend_always yield_value(yielded val) noexcept;
`

[4](#4)

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

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

[5](#5)

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

*Returns*: {}[.](#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](#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[.](#6.sentence-1)

[7](#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[.](#7.sentence-1)

[8](#8)

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

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

[9](#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"))[.](#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](#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[.](#10.sentence-1)

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

[11](#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[.](#11.sentence-1)

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

[12](#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"))[.](#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](#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](#14)

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

[*Note [1](#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"))[.](#14.sentence-1)

â *end note*]

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

`void unhandled_exception();
`

[15](#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[.](#15.sentence-1)

[16](#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_*[.](#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](#17)

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

Let A be

- [(17.1)](#17.1)

Allocator, if it is not void,

- [(17.2)](#17.2)

Alloc for the overloads with a template parameter Alloc, or

- [(17.3)](#17.3)

allocator<void> otherwise[.](#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__[.](#17.sentence-2)

[18](#18)

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

*Mandates*: allocator_traits<B>​::​pointer is a pointer type[.](#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[.](#18.sentence-2)

[19](#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[.](#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[.](#19.sentence-2)

[20](#20)

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

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

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

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

[21](#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[.](#21.sentence-1)

[22](#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[.](#22.sentence-1)
