uvco 0.1
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Friends | List of all members
uvco::MultiPromise< T > Class Template Reference

#include <multipromise.h>

Classes

struct  MultiPromiseAwaiter_
 

Public Types

using promise_type = Generator<T>
 

Public Member Functions

 MultiPromise (MultiPromise< T > &&) noexcept=default
 An unfulfilled MultiPromise.
 
MultiPromiseoperator= (const MultiPromise< T > &)=delete
 
MultiPromiseoperator= (MultiPromise< T > &&) noexcept=delete
 
 MultiPromise (const MultiPromise< T > &other)=default
 
 ~MultiPromise ()
 
Promise< std::optional< T > > next ()
 
MultiPromiseAwaiter_ operator co_await () const
 
bool ready ()
 
void cancel ()
 

Protected Types

using PromiseCore_ = MultiPromiseCore<T>
 
using SharedCore_ = std::shared_ptr<PromiseCore_>
 

Protected Member Functions

 MultiPromise (SharedCore_ core)
 

Protected Attributes

SharedCore_ core_
 

Friends

template<typename U >
class Generator
 

Detailed Description

template<typename T>
class uvco::MultiPromise< T >

A MultiPromise is like a Promise, except that it can resolve more than just once. A coroutine returning a MultiPromise (called a "generator coroutine") uses co_yield to return values to the awaiting coroutine. For example in the Udp class, a method exists which generates packets.

As an adapter, for example for SelectSet, the next() method returns a promise returning the next yielded value.

NOTE: currently uses a shared_ptr PromiseCore, due to issues with inheritance. It is expected that normal Promise<T> will be used most frequently, therefore the lack of optimization is not as grave.

Member Typedef Documentation

◆ promise_type

template<typename T >
using uvco::MultiPromise< T >::promise_type = Generator<T>

Part of the coroutine protocol: the MultiPromise is both return type and promise type.

◆ PromiseCore_

template<typename T >
using uvco::MultiPromise< T >::PromiseCore_ = MultiPromiseCore<T>
protected

◆ SharedCore_

template<typename T >
using uvco::MultiPromise< T >::SharedCore_ = std::shared_ptr<PromiseCore_>
protected

Constructor & Destructor Documentation

◆ MultiPromise() [1/3]

template<typename T >
uvco::MultiPromise< T >::MultiPromise ( MultiPromise< T > &&  )
defaultnoexcept

An unfulfilled MultiPromise.

It doesn't make sense to yield void. For that, just ues a normal coroutine (Promise<void>) and repeatedly call it.

◆ MultiPromise() [2/3]

template<typename T >
uvco::MultiPromise< T >::MultiPromise ( const MultiPromise< T > &  other)
default

◆ ~MultiPromise()

template<typename T >
uvco::MultiPromise< T >::~MultiPromise ( )
inline
153 {
154 // Us and the coroutine frame; but we're about to be destroyed
155 if (core_.use_count() == 2) {
156 // -> cancel generator. Because the coroutine frame keeps a reference to
157 // the core, we can't do this in the core's destructor.
158 PromiseCore_ *weakCore = core_.get();
159 core_.reset();
160 // The core's dtor is called while cancelGenerator runs.
161 weakCore->cancelGenerator();
162 }
163 }
MultiPromiseCore< T > PromiseCore_
Definition multipromise.h:137
SharedCore_ core_
Definition multipromise.h:259

◆ MultiPromise() [3/3]

template<typename T >
uvco::MultiPromise< T >::MultiPromise ( SharedCore_  core)
inlineexplicitprotected
257: core_{std::move(core)} {}

Member Function Documentation

◆ cancel()

template<typename T >
void uvco::MultiPromise< T >::cancel ( )
inline

Immediately cancel the suspended generator coroutine. This will drop all stack variables inside the generator (and run their destructors), and ensure that the generator will never resume from the currently yielded value.

cancel() is called automatically once the (last) MultiPromise instance referring to a coroutine is destroyed.

(This can be solved by distinguishing between the returned object and the promise object, which may be part of a future refactor. In that case, the generator's promise object should only contain a weak reference to this MultiPromiseCore, and the caller contains a strong reference. The core's destructor cancels the generator once the caller doesn't require it anymore.)

197{ core_->cancelGenerator(); }

◆ next()

template<typename T >
Promise< std::optional< T > > uvco::MultiPromise< T >::next ( )
inline

Obtain the next value yielded by a generator coroutine. This is less efficient than awaiting the multipromise directly.

167{ co_return (co_await *this); }

◆ operator co_await()

template<typename T >
MultiPromiseAwaiter_ uvco::MultiPromise< T >::operator co_await ( ) const
inline

Return an awaiter for this MultiPromise, which resumes the waiting coroutine once the generator yields its next value.

Used when co_awaiting a MultiPromise created by a generator coroutine. The awaiter handles the actual suspension and resumption.

174 {
175 BOOST_ASSERT(core_);
176 return MultiPromiseAwaiter_{core_};
177 }

◆ operator=() [1/2]

template<typename T >
MultiPromise & uvco::MultiPromise< T >::operator= ( const MultiPromise< T > &  )
delete

◆ operator=() [2/2]

template<typename T >
MultiPromise & uvco::MultiPromise< T >::operator= ( MultiPromise< T > &&  )
deletenoexcept

◆ ready()

template<typename T >
bool uvco::MultiPromise< T >::ready ( )
inline

Returns true if a value is available, or the generator has returned or thrown.

181{ return core_->slot.has_value() || core_->isTerminated(); }

Friends And Related Symbol Documentation

◆ Generator

template<typename T >
template<typename U >
friend class Generator
friend

Member Data Documentation

◆ core_

template<typename T >
SharedCore_ uvco::MultiPromise< T >::core_
protected

The documentation for this class was generated from the following file: