facebookexperimental / facebookexperimental/libunifex

Reference value types and when_all

Open
#234 1 comment 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.