Files
2025-10-25 03:02:53 +03:00

13 KiB
Raw Permalink Blame History

[coro.generator.promise]

25 Ranges library [ranges]

25.8 Range generators [coro.generator]

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& lval)requires is_rvalue_reference_v &&constructible_from<remove_cvref_t, const remove_reference_t&>; template<class R2, class V2, class Alloc2, class Unused>requires same_as<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<typename generator<R2, V2, Alloc2>::yielded, yielded>auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&, Unused> g) noexcept; template<ranges::input_range R, class Alloc>requires convertible_to<ranges::range_reference_t, 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<Allocator, void> || default_initializable; 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 value_ = nullptr; // exposition only exception_ptr except_; // exposition only};}

🔗

generator get_return_object() noexcept;

1

#

Returns: A generator object whose member coroutine_ is coroutine_handle<promise_type>::from_promise(*this), and whose member active_ points to an empty stack.

🔗

auto final_suspend() noexcept;

2

#

Preconditions: A handle referring to the coroutine whose promise object is *this is at the top of *active_ of some generator object x.

This function is called by that coroutine upon reaching its final suspend point ([dcl.fct.def.coroutine]).

3

#

Returns: An awaitable object of unspecified type ([expr.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.

If it is empty, control flow returns to the current coroutine caller or resumer ([dcl.fct.def.coroutine]).

🔗

suspend_always yield_value(yielded val) noexcept;

4

#

Effects: Equivalent to value_ = addressof(val).

5

#

Returns: {}.

🔗

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

6

#

Preconditions: A handle referring to the coroutine whose promise object is *this is at the top of *active_ of some generator object.

7

#

Returns: An awaitable object of an unspecified type ([expr.await]) that stores an object of type remove_cvref_t direct-non-list-initialized with lval, whose member functions arrange forvalue_ to point to that stored object and then suspend the coroutine.

8

#

Throws: Any exception thrown by the initialization of the stored object.

9

#

Remarks: A yield-expression that calls this function has type void ([expr.yield]).

🔗

template<class R2, class V2, class Alloc2, class Unused> requires [same_as](concept.same#concept:same_as "18.4.2Concept 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.2Concept 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

#

Preconditions: A handle referring to the coroutine whose promise object is *this is at the top of *active_ of some generator object x.

The coroutine referred to byg.range.coroutine_ is suspended at its initial suspend point.

11

#

Returns: An awaitable object of an unspecified type ([expr.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.

If bool(except_) is false, the await_resume member has no effects.

12

#

Remarks: A yield-expression that calls one of these functions has type void ([expr.yield]).

🔗

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

13

#

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

14

#

[Note 1:

A yield-expression that calls this function has type void ([expr.yield]).

— end note]

🔗

void unhandled_exception();

15

#

Preconditions: A handle referring to the coroutine whose promise object is *this is at the top of *active_ of some generator object x.

16

#

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_.

🔗

`void* operator new(size_t size) requires same_as<Allocator, void> || default_initializable;

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

#

Let A be

Allocator, if it is not void,

Alloc for the overloads with a template parameter Alloc, or

allocator otherwise.

Let B be allocator_traits::template rebind_alloc where U is an unspecified type whose size and alignment are both STDCPP_DEFAULT_NEW_ALIGNMENT.

18

#

Mandates: allocator_traits::pointer is a pointer type.

For the overloads with a template parameter Alloc,same_as<Allocator, void> || convertible_to<const Alloc&, Allocator> is modeled.

19

#

Effects: Initializes an allocator b of type B with A(alloc), for the overloads with a function parameter alloc, and with A() otherwise.

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.

20

#

Returns: A pointer to the allocated storage.

🔗

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

21

#

Preconditions: pointer was returned from an invocation of one of the above overloads of operator new with a size argument equal to size.

22

#

Effects: Deallocates the storage pointed to by pointer using an allocator equivalent to that used to allocate it.