facebookexperimental / facebookexperimental/libunifex
Reference value types and when_all
- Dominant language
- C++
- Stars
- 1.7k
- Forks
- 210
- PR merge metrics
- No merged PRs in 30d
Description
# Current behavior
`when_all` decays the value types from upstream operations to determine it's storage.
# Expected behavior
Reference values passed by upstream to be "stored" by `reference_wrapper`, using pointers, or the like, and unwrapped prior to being passed to downstream operations.
# Why is this a problem?
That means that lvalue references sent from upstream operations are copy constructed into storage.
Consequently,
1. surprising (and potentially expensive) copies are made
2. senders of references to non-copyable types cannot be used with `when_all`.
# Minimum Reproducing Example
Compiler explorer link: https://godbolt.org/z/Wacxf3
```c++
#include
#include
#include
#include
int main() {
struct foo {
foo() = default;
foo(const foo&) = delete;
};
struct receiver {
void set_value(foo&) noexcept { std::cout << "success" << std::endl; }
[[noreturn]] void set_error(std::exception_ptr) noexcept {
std::terminate();
}
[[noreturn]] void set_done() noexcept {
std::terminate();
}
};
foo instance;
auto s = unifex::when_all(unifex::just(&instance) | unifex::transform([](foo* ptr) -> foo& { return *ptr; }));
auto r = receiver{};
auto os = unifex::connect(std::move(s), std::move(r));
unifex::start(os);
};
```
Contributor guide
Assessment
This issue has not been assessed yet.