On 30/05/2017 11:25, Vicente J. Botet Escriba wrote:
Le 29/05/2017 à 17:05, Niall Douglas a écrit :
- error_type& .error_raw() - reinterpret_cast
evidently we don't like the _raw suffix. .error_unsafe(), .unsafe_error(), .unchecked_error() all work for me too. How likes any of those? Who prefers error() to throw if there is a value? or return by value and return E{} when there is a value and I don't know hat when there is an exception_ptr? FWIW, my preferred options would be (which I think were the originals): Thanks, you are the first (I believe) that supported the proposed interface, but maybe I'm wrong.
- 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) Would you like to extract the error code from the stored exception If
Le 30/05/2017 à 01:41, Gavin Lambert via Boost a écrit : the exception had an error_code() function? So the error codes must contain also the success codes. And now we don't know if errc::no_value means success or failure. Wondering id make_error_code isn't more appropriated. I know you don't like long names, but this is what the function is doing.
- exception() returns nullptr if holding value or error or empty
Why not create an exception when there is not, for the other cases? When you say that return nullptr you mean that it returns an exception_ptr with a nullptr in. This seems like safe and reasonable default and permit code to always extract a exception even on success. Without this interface we can say the it is UB to have an exception_ptr with a nullptr stored in an outcome. Now that we can get one of those, it is much difficult to reason about.
These seem like safe and reasonable defaults and permits code to always extract an error_code or exception_ptr even on success, which can aid certain interop scenarios with older APIs and otherwise simplify caller logic. I agree with you "This seem like safe" but I'm not sure it is. I'm not against the semantic of these wide functions and even the one I gave above. If people prefer the shorter names for the wide contract I could live with that. But I would like a single semantic for functions with the same name.
I would prefer that unchecked_* (or whatever) versions did not exist as then nobody would accidentally call them and perhaps introduce UB. But I'm not strongly opposed to them.
They introduce UB of course and static analysis tools are there to check for some of the most current cases even before I run my program. This allows to have a sorter program that is more understandable. At run-time the library could use some kind of contract programming so that the checks are done when configured and so you get the bad usage as soon as possible. So you are not one of those that needs the more efficient interface. When you know the precondition is satisfied, why do you want to pay for additional checks on the library and on the user code? If you provide the minimal interface the user can built on top of it whatever he needs. Not providing it will imply that all will pay for. At the end what we need is the SumType interface: alternative index and direct narrow access and/or visitation of a variant< ...> and some kind of trait that associates an index to success or failure. Vicente