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