`default_domain::sender_transform()` applied to an rvalue should return an xvalue instead of a prvalue
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 2.4k
- Forks
- 270
- Avg merge
- 3d 6h
- Merged PRs (30d)
- 39
Description
The specification in P2300 says that sender_transform() should be expression equivalent to std::forward<Sndr>(sndr) if the tag_of_t<Sndr> doesn't have its own sender_transform() overload.
However, the current implementation is forcibly returning a prvalue that requires move-constructing the input sender.
I think we need to change the line as follows so it returns an xvalue when passed an rvalue
-return static_cast<_Sender>(static_cast<_Sender&&>(__sndr));
+return static_cast<_Sender&&>(__sndr);
We may also want to update some algorithms to avoid making copies / take advantage of copy-elision in cases when we are using the default-domain which has a no-op eager sender_transform.
e.g. see finally() algorithm implementation:
https://github.com/NVIDIA/stdexec/blob/4e573c3617a045c7b58ca007df373f6721f839dd/include/exec/finally.hpp#L306-314
This first constructs the default finally-sender using __make_sexpr<finally_t> which necessarily moves the input senders into this sender. But then because it passes through transform_sender, we can't take advantage of copy-elision and so in cases where the domain does not have a transform for the input sender, we end up having to do a move when returning from operator() anyway.
I think to get around this extra copy you'd need to do something like:
if constexpr (domain_has_customization_for<Domain, SenderType>) {
return stdexec::transform_sender(domain, __make_sexpr<CPO>(...), env);
} else {
return __make_sexpr<CPO>(...);
}
Alternatively, we could have transform_sender() take a lambda that produces the sender and then we can do copy-elision on return path through both transform_sender and operator().
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with include/stdexec/__detail/__domain.hpp at lines 106-134 and compare the default sender_transform behavior with the P2300 expression-equivalence requirement for rvalues. Then inspect exec/finally.hpp at lines 306-314 to assess the stated extra moves and determine whether the relevant algorithms can preserve copy elision. Done means the rvalue path and affected default-domain algorithm paths avoid the unnecessary move without changing customization behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend-api-design, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100