Repository navigation
exec(fork_join): coalesce empty and unary calls - #2302
romintomasetti wants to merge 3 commits into
Conversation
|
@RobertLeahy @ericniebler Could you please have a look? Thanks! |
|
|
||
| /// Unary closure. | ||
| template <STDEXEC::sender Sndr, class Closure> requires (!STDEXEC::sender<Closure>) | ||
| constexpr auto operator()(Sndr&& sndr, Closure&& clsr) const noexcept(STDEXEC::__nothrow_decay_copyable<Closure>) |
There was a problem hiding this comment.
I don't think this noexcept is correct. Just because Closure can be decay-copied doesn't mean binding it together with something of type Sndr can't.
There was a problem hiding this comment.
Indeed! How would you do it, apart from
noexcept(noexcept(static_cast<Sndr&&>(sndr) | static_cast<Closure&&>(clsr)))?
There was a problem hiding this comment.
Use inspiration from include/stdexec/__detail/__sender_adaptor_closure.hpp?
There was a problem hiding this comment.
Done. What do you think?
1a93249 to
376da8c
Compare
376da8c to
e910941
Compare
Signed-off-by: romintomasetti <romin.tomasetti@gmail.com>
e910941 to
91e17da
Compare
| /// Multiple closures. | ||
| auto multiple = STDEXEC::just() | exec::fork_join(then, then); | ||
| STATIC_REQUIRE(exec::sender_for<decltype(multiple), exec::fork_join_t>); | ||
| STATIC_REQUIRE(!noexcept(exec::fork_join(STDEXEC::just(), then, then))); |
There was a problem hiding this comment.
We could also omit this line. Because it seems the reason is that the function has no noexcept clause, rather than that one operations may throw.
There was a problem hiding this comment.
Yeah, but at least it's tested.
There was a problem hiding this comment.
I would expect constructing such an exec::fork_join sender not to throw, which noexcept is missing that prevents that?
There was a problem hiding this comment.
There are 2 functions in the fork_join_t struct I haven't touched yet.
There was a problem hiding this comment.
My two cents would be to add the noexcept clause and flip the static_assert here.
We could write something like (perhaps there's a way to make it less verbose with other concepts from __concepts.hpp):
noexcept(STDEXEC::__nothrow_decay_copyable<Closures..., Sndr>
&& (std::is_nothrow_move_constructible_v<STDEXEC::__decay_t<Closures>> && ...)
&& std::is_nothrow_move_constructible_v<STDEXEC::__decay_t<Sndr>>)
The last two checks would be needed for the moves here:
stdexec/include/stdexec/__detail/__basic_sender.hpp
Lines 460 to 470 in f4c123f
There was a problem hiding this comment.
we should probably fix __make_sexpr_t to perfectly forward the arguments and give it a noexcept clause. i can make a PR for that.
There was a problem hiding this comment.
That change has now landed and i have merged it into this PR, so the noexcept clause here can be simply noexcept(STDEXEC::__nothrow_decay_copyable<Closures..., Sndr>).
There was a problem hiding this comment.
Ok! Thank you very much for the pr and merging it here. To write the noexcept clause, one remaining question seems to be whether we should take into account the move of the __tuple that fork_join constructs and then passes to __make_sexpr?
Similar to NVIDIA#2124. See P4269R1. Signed-off-by: romintomasetti <romin.tomasetti@gmail.com>
91e17da to
e43b788
Compare
exec::fork_join(sndr, clsr)is given a single closure, do no attempt to wrap it in the (thereby useless)fork_joinmachinery. Returnsndr | clsr.exec::fork_join(sndr)is given no closure, it behaves likesndr.As a drive-by, I've added a few
noexcepttothen.Similar to:
See P4269R1.