Description
In some algorithms I want to be able to store some state in a parent operation-state and then pass a receiver to child operations whose get_env()
returns a queryable
that resolves a certain query from the operation-state.
e.g. Consider a simple algorithm something like:
template<typename Receiver, typename ChildSender, typename Allocator>
struct with_allocator_op {
struct child_env {
with_allocator_op* op;
decltype(auto) query(auto tag) const
noexcept(noexcept(std::declval<Receiver>().get_env().query(tag)))
requires queryable_for<receiver_env_t<Receiver>, decltype(tag)> {
return std::execution::get_env(op->receiver).query(tag);
}
Allocator query(get_allocator_t) const noexcept {
return op->allocator;
}
};
struct child_receiver {
with_allocator_op* op;
template<typename... Vs> void set_value(Vs&&... vs) noexcept {
op->receiver.set_value(std::forward<Vs>(vs)...);
}
template<typename E> void set_error(E&& e) noexcept {
op->receiver.set_error(std::forward<E>(e));
}
void set_stopped() noexcept { op->receiver.set_stopped(); }
child_env get_env() const noexcept {
return child_env{op};
}
};
void start() noexcept { child_op.start(); }
Receiver receiver;
Allocator allocator;
connect_result_t<ChildSender, child_receiver> child_op;
};
However, since the receiver that I connect the ChildSender
to in this case has an environment whose type depends on the with_allocator_op
type, which in turn depends on the Receiver
, there is no way for the corresponding with_allocator_sender
that produces this operation state upon connect to implement the get_completion_signatures()
query accurately, as it cannot pass through the exact environment type to the get_completion_signatures()
query on the ChildSender
type.
Is this something we want to be able to support?
It seems like it might be necessary to solve #229.
If we want to support this I think we would require one of two approaches:
- Go back to making
get_completion_signatures()
take the receiver type rather than the environment type and solve the circular dependencies some other way. - Require
get_completion_signatures()
to produce the same set of completion-signatures for any environment type that has an equivalent set of supported queries.
This would, however, make it impossible to implement something likelet_env()
whose completion-signatures would depend on the exact environment type rather than the set of queries that the environment supports.
If we don't want to support this then we are basically restricted to environment aggregation, with the potential performance issues described in #229.