This is in connection with Vicente's question: what exception safety should we expect of copy assignment of `expected`?
Vicente's paper promises a never empty guarantee. So if during a transition of state during assignment the new state's assignment operator throws, the previous state in the Expected is preserved. Outcome master branch doesn't implement that. Outcome develop branch does.
First, let's consider the use case for `expected`, where we want to disable exception handling altogether. This means `T` or `E` cannot throw on any operation.
Vicente's paper allows T to throw during move or copy. E must be nothrow move. This makes possible the never empty guarantee.
So my view, as of today, is not to strive for a strong or even never-empty guarantee. Provide a conditional guarantee, if types T and E don't throw, you get no-fail guarantee. If they do, you only have a basic guarantee: you can destroy, assign to, or maybe call valueless_by_exception(). Nothing more. I think `std::variant` made the optimal choice.
std::variant could provide a never empty guarantee without increasing storage required if it imposed restrictions on its types e.g. all but one of the possible types must have nothrow move construction. If it were allowed to double the storage required, it could use Anthony Williams' double buffer technique to ensure never empty guarantee. This eliminates the need for valueless_by_exception() entirely. None of this affects Expected nor Outcome. Outcome hard codes EC and E, and both those types are guaranteed nothrow move constructible, so we can guarantee we never lose a previous state if assignment of a new state throws. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/