
Niall Douglas wrote:
future<T> already adds the ability to store exception_ptr. There is no need to store another exception_ptr in the value. Niall's type is exactly equivalent to future<expected<T, error_code>>, as I already said (twice).
exception_ptr unfortunately must always do an atomic write to memory. That always forces code to be generated, and very substantially reduces optimisation opportunities because state must be reloaded around the exception_ptr.
This, and the mandatory memory allocation, is a big reason current futures are not suitable for high performance ASIO.
I also want a big semantic change that error returns are not exceptional. We hugely underuse std::error_code in STL C++ unfortunately. I am not one of those people who believes exceptions are evil, and ban them in the language as all the new system languages seem to. I also have no love for forcing everything through the return code as with C and Rust, but I do think there is a middle ground between good outcomes, bad outcomes, and exceptional outcomes which is easy to program, easy to conceptualise, and easy on the compiler.
There could be a misunderstanding. When I say that your type is future<expected<T, error_code>>, I don't mean any specific future or expected implementations such as std::future or boost::expected. What I mean is a future-like type, having the interface of std/boost::future, and an expected-like type, having (a subset of) the interface of std/boost::expected. You could still implement your own future<> and expected<> if the existing ones are unfit. My point is purely that these are independent concepts and there is no real need to couple them into one type, with a hardcoded error_code to boot. So far, you've stated that you like that your type is constructible from T, error_code or exception_ptr. I suppose a future<expected<T, error_code>> may not be as convenient. Are there other ways in which the interface of future<expected<T, error_code>> is deficient?