2017-05-31 10:26 GMT+02:00 Gavin Lambert via Boost
template<typename T> class outcome { public: bool has_value() const { return !!m_value; } T& value() { ensure(); return m_value.value(); }
//bool has_error() const { return !!m_error; } const error_code& error() const { return m_error; }
//bool has_exception() const { return !!m_exception; } const exception_ptr& exception() const { return m_exception; }
void ensure() const { if (m_exception) { rethrow_exception(m_exception); } if (m_error) { throw system_error(m_error); } }
void set(none_t) { m_value = none; m_error = error_code(); m_exception = nullptr; } void set(const T& val) { m_value = val; m_error = error_code(); m_exception = nullptr; } void set(error_code err) { m_value = none; m_error = err; m_exception = nullptr; } void set(exception_ptr ep) { m_value = none; m_error = ep ? error_code(errc::has_exception) : error_code(); m_exception = ep; }
private: optional<T> m_value; error_code m_error; exception_ptr m_exception; };
(Don't get too hung up on the specifics. This is a sketch, not a real implementation. I've obviously omitted things that a real implementation would need such as more const methods and move support, and construction and assignment rather than using set methods. The focus is on variant vs. non-variant.)
Anyway, the point is that this could actually transport multiple things; in particular as above both an error_code and an exception_ptr; perhaps set(error_code) could construct an exception as well, although I've explained elsewhere why I don't like that option.
In your mental model what is the interpretation of the situation when you have both an error_code and an exception_ptr? Regards, &rzej;