non-resumable / immediately returning (expected<T, E>)
set_result
lacks {initial,final}_suspend? (currently unspecified)
internally-resumable / eventually returning (future<T>)
set_result
externally-resumable (generator<T>)
yield_value
mutually-resumable / eventually returning (async_generator<T>)
yield_value
struct cancellable_handle {
// 18.11.2.1 construct/reset
cancellable_handle() noexcept;
cancellable_handle(std::nullptr_t) noexcept;
cancellable_handle& operator=(nullptr_t) noexcept;
// 18.11.2.3 capacity
explicit operator bool() const noexcept;
// {cancellation}
void destroy() const;
};
template <>
struct resumable_handle<void> : cancellable_handle {
// 18.11.2.1 construct/reset
using cancellable_handle::cancellable_handle;
resumable_handle& operator=(nullptr_t) noexcept;
// 18.11.2.2 export/import
static resumable_handle from_address(void* addr) noexcept;
void* to_address() const noexcept;
// 18.11.2.4 resumption
void operator()() const;
void resume() const;
// 18.11.2.5 completion check
bool done() const noexcept;
};
template <>
struct resumable_handle<ExternallyResumable<P>> : resumable_handle<> {
// 18.11.2.1 construct/reset
using resumable_handle<>::resumable_handle;
resumable_handle& operator=(nullptr_t) noexcept;
// 18.11.2.6 export/import
static resumable_handle from_promise(Promise*) noexcept;
Promise& promise() noexcept;
Promise const& promise() const noexcept;
};
template <>
struct resumable_handle<InternallyResumable<P>> : cancellable_handle {
...
};
~~~~~~~~~
Yes, it can work with optional and expected. Though to make the experience truly awesome, we would need to introduce some mechanism that can express whether a return object of a resumable function can express expansion of a particular monadic class.
optional<T> can represent either a value or the absence of value
expected<T> can represent either a value or the absence of value with a reason why not
future<T> can represent, please wait, a value or the absence of value with a reason why not
Thus in a resumable function returning a future<T>, it is fine to await on expression of any type that can be represented by the future, thus, you can await on optional, expected, future or some other async construct.
If a resumable function returns expected<T> or optional<T>, awaiting on an expression which type represents value not here yet, should not be possible.
At the moment, I don't have a mechanism in the proposal to deal with that.
I am looking for suggestions and ideas.
I have a half-baked idea that I am not sure I like that looks something like that:
if resumable promise does not contain initial_suspend and final_suspend members, that means that resumable function cannot be suspended.
There also should be a trait, let say, "suspendable<T>" that will default to "true_type", for arbitrary awaitable type, but, for optional and expected will say false.
When the compiler figures out that resumable promise does not support suspension (absence of initial_suspend / final_suspend members), it will not compile your code, if you await on an expression of any type for which suspendable says true.
Hi Shahms:Your resumable function classification and identifying the case where we would like to get a compile time error is spot on.I think in addition to "no initial_suspend / final_suspend" that will mark the resumable function as "can never suspend", we need to also have traits that can explain that awaiting on certain types must never result in suspension.Say:is_suspendable_v<T> == true for arbitrary type T, but, for optional and expected you will specialize it to be:is_suspendable_v<optional<T>> == false.
I am not sure how suggested changes to resumable_handle will help, as resumable_handle is what compiler gives to the library, not, the other way around.
GorP.S.Here a post from vcblog on related matter:~~~~~~~~~
Yes, it can work with optional and expected. Though to make the experience truly awesome, we would need to introduce some mechanism that can express whether a return object of a resumable function can express expansion of a particular monadic class.
optional<T> can represent either a value or the absence of value
expected<T> can represent either a value or the absence of value with a reason why not
future<T> can represent, please wait, a value or the absence of value with a reason why not
Thus in a resumable function returning a future<T>, it is fine to await on expression of any type that can be represented by the future, thus, you can await on optional, expected, future or some other async construct.
If a resumable function returns expected<T> or optional<T>, awaiting on an expression which type represents value not here yet, should not be possible.
At the moment, I don't have a mechanism in the proposal to deal with that.
I am looking for suggestions and ideas.
I have a half-baked idea that I am not sure I like that looks something like that:
if resumable promise does not contain initial_suspend and final_suspend members, that means that resumable function cannot be suspended.
There also should be a trait, let say, "suspendable<T>" that will default to "true_type", for arbitrary awaitable type, but, for optional and expected will say false.
When the compiler figures out that resumable promise does not support suspension (absence of initial_suspend / final_suspend members), it will not compile your code, if you await on an expression of any type for which suspendable says true.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.