On 30/05/2017 21:12, Andrzej Krzemienski via Boost wrote:
2017-05-30 15:18 GMT+02:00 Niall Douglas via Boost
: - value() throws if holding error or exception (or empty)
- error() returns E{} if holding value or E{errc::has_exception} if holding exception, or E{errc::no_value} if empty (names made up on the spot, doesn't matter)
The current behaviour is "always throw on observing empty". That's what makes empty special (and it traps unintentional propagation of empty).
- exception() returns nullptr if holding value or error or empty
The current behaviour is to return null exception_ptr if valued (so if(eptr) would be false i.e. "no exception here"), std::make_exception_ptr(std::system_error(error())) if errored, throw on empty.
So an errored state is also an excepted state, but an excepted state is never an errored state. has_exception() returns true for either errored or excepted states.
But is there some mental model behind this decision?
Of course. exception <= error < value. So errors are exceptions, but exceptions are not errors. empty is the wildcard. It is modelled like NaN in floating-point, it propagates in a dominant fashion unless you explicitly deal with it.
std::make_exception_ptr(std::system_error(error())) is fairly cheap, a few thousand CPU cycles. std::exception_ptr's are heavy anyway.
Or are these decisions, what to return in tricky cases are only driven by performance?
If you are using result<T> instead of outcome<T>, it is assumed that you must feel an exception_ptr to be too expensive and/or you are not using exceptions at all. outcome<T> implicitly converts from result<T> on demand, so some code you can write without exception_ptr, some with, and the two interoperate seamlessly by all funnelling into outcome<T>. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/