NVIDIA / stdexec

`std::execution`, the proposed C++ framework for asynchronous and parallel programming.
Apache License 2.0
1.56k stars 159 forks source link

Add `sender_of<S, T>` concept #50

Closed brycelelbach closed 3 years ago

brycelelbach commented 3 years ago

I want to be able to write an algorithm that only accepts senders that send a particular type, e.g. something like this:

std::execution::sender_of<std::span<std::byte>> auto
async_read(std::execution::sender_of<std::span<std::byte>> auto buffer, handle_type handle);
lewissbaker commented 3 years ago

I think this concept should at least support packs of values. i.e. sender_of<S, Values...>

Would such a concept require that the value_types was exactly Variant<Tuple<Values...>> or would it only require that it accepts a receiver whose only set_value() overload can be called with an argument pack of type Values&&...?

The difference is that the latter would be a bit more relaxed in the set of senders it accepts as it allows some implicit conversions between the produced values and the received values. e.g. a sender that called set_value() with an int would pass the sender_of<float> concept as an int would be implicitly converted to a float if the receiver's set_value() implementation took an argument of type float.

It would also allow senders that did not send any values. For example, something that always only ever called set_error or set_done, like the never_sender in libunifex.

brycelelbach commented 3 years ago

@griwes asks if I want it to be precise - e.g. that sender_of<S, Values...> is only satisfied by sender that /only/ sends precisely Values... (modulo decltype/cv/etc).

@griwes e.g. is this concept "this sender sometimes sends those" or "this sender always sends this".

Looking at where I want to use this, I believe that I want it to mean "this sender can only send these values types". E.g. async_read in this example will fail to compile if you pass it a sender that sends something other than span<byte>: https://brycelelbach.github.io/wg21_p2300_std_execution/std_execution.html#example-async-dynamically-sized-read

@mjgarland agrees on the value of being able to make this assertion. He's frequently wanted it when writing pseudo code.

@griwes says this is a simple concept to write.