expected: add 'unexpected' constructor

This commit is contained in:
Danny Robson 2019-03-05 12:17:02 +11:00
parent 5aefb2f82a
commit b7e883903c

View File

@ -22,8 +22,22 @@ namespace cruft {
};
template <typename ErrorT>
class unexpected {
public:
unexpected (ErrorT && _value): m_value (std::move (_value)) { ; }
unexpected (ErrorT const &_value): m_value (_value) { ; }
ErrorT& value (void)& { return m_value; }
ErrorT&& value (void)&& { return std::move (m_value); }
private:
ErrorT m_value;
};
template <typename ValueT, typename ErrorT>
struct expected {
struct [[nodiscard]] expected {
using value_type = ValueT;
using error_type = ErrorT;
@ -33,9 +47,9 @@ namespace cruft {
m_valid = true;
}
expected (ErrorT &&_error)
expected (unexpected<ErrorT> &&_error)
{
::new (&m_store.error) ErrorT (std::move (_error));
::new (&m_store.error) unexpected<ErrorT> (std::move (_error));
}
~expected ()
@ -44,7 +58,7 @@ namespace cruft {
m_store.value.~ValueT ();
m_valid = false;
} else {
m_store.error.~ErrorT ();
m_store.error.~unexpected<ErrorT> ();
}
}
@ -69,7 +83,7 @@ namespace cruft {
{
if (m_valid)
throw bad_expected_access {};
return m_store.error;
return m_store.error.value ();
}
ErrorT&&
@ -77,7 +91,7 @@ namespace cruft {
{
if (m_valid)
throw bad_expected_access {};
return std::move (m_store.error);
return std::move (m_store.error.value ());
}
ValueT* operator-> (void)& { return &value (); }
@ -92,7 +106,9 @@ namespace cruft {
return expected (std::invoke (func, args..., value ()));
}
explicit operator bool() const noexcept { return m_valid; }
bool has_value (void) const noexcept { return m_valid; }
explicit operator bool() const noexcept { return has_value (); }
private:
union storage_t {
@ -101,9 +117,9 @@ namespace cruft {
char defer;
ValueT value;
ErrorT error;
unexpected<ErrorT> error;
} m_store;
bool m_valid = false;
};
};
}