exec.schedule.from/p11 specifies shedule_from
's completion operation as follows:
[]<class Tag, class... Args>(auto, auto& state, auto& rcvr, Tag, Args&&... args) noexcept -> void { using result_t = decayed-tuple<Tag, Args...>; constexpr bool nothrow = is_nothrow_constructible_v<result_t, Tag, Args...>; try { state.async-result.template emplace<result_t>(Tag(), std::forward<Args>(args)...); } catch (...) { if constexpr (!nothrow) { set_error(std::move(rcvr), current_exception()); return; } } start(state.op-state); };
so if emplacing the result tuple throws, set_error
is immediately called on the downstream receiver. no attempt is made to post the completion to the specified scheduler. this is probably not the right behavior.
the right thing, i think, is to catch the exception, emplace the exception_ptr
into the async-result
variant, and then start the schedule operation, as shown below:
[]<class Tag, class... Args>(auto, auto& state, auto& rcvr, Tag, Args&&... args) noexcept -> void { using result_t = decayed-tuple<Tag, Args...>; constexpr bool nothrow = is_nothrow_constructible_v<result_t, Tag, Args...>; try { state.async-result.template emplace<result_t>(Tag(), std::forward<Args>(args)...); } catch(...) { if constexpr (nothrow) state.async-result.template emplace<tuple<set_error_t, exception_ptr>>(set_error, current_exception()); } } start(state.op-state); }
we also need to change how we specify the variant type of state.async-result
:
Let Sigs be a pack of the arguments to the completion_signatures specialization named by completion_signatures_of_t<child-type<Sndr>, -env_of_t<Rcvr>>. Let as-tuple be an alias template that transforms -a completion signature Tag(Args...) into the tuple specialization -decayed-tuple<Tag, Args...>. Then variant_t denotes the type -variant<monostate, as-tuple<Sigs>...>, except with duplicate types -removed. +env_of_t<Rcvr>>. Let as-tuple be an alias template such that +as-tuple<Tag(Args...)> denotes the tuple specialization +decayed-tuple<Tag, Args...>, and let is-nothrow-decay-copy-sig be +a variable template such that is-nothrow-decay-copy-sig<Tag(Args...)> +is a core constant expression of type bool const and whose value +is true if the types Args... are all nothrow decay-copyable, and false +otherwise. Let error-completion be a pack consisting of the type +set_error_t(exception_ptr) if (is-nothrow-decay-copy-sig<Sigs> &&...) +is false, and an empty pack otherwise. Then variant_t denotes the type +variant<monostate, as-tuple<Sigs>..., error-completion...>, except +with duplicate types removed.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4