98 lines
2.2 KiB
C++
98 lines
2.2 KiB
C++
|
/*
|
||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||
|
*
|
||
|
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
|
||
|
*/
|
||
|
|
||
|
#include <exception>
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
namespace cruft {
|
||
|
class bad_expected_access : public std::exception {
|
||
|
public:
|
||
|
char const* what (void) const noexcept override
|
||
|
{
|
||
|
return "bad_expected_access";
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
template <typename ValueT, typename ErrorT>
|
||
|
struct expected {
|
||
|
using value_type = ValueT;
|
||
|
using error_type = ErrorT;
|
||
|
|
||
|
expected (ValueT &&_value)
|
||
|
{
|
||
|
::new (&m_store.value) ValueT (std::move (_value));
|
||
|
m_valid = true;
|
||
|
}
|
||
|
|
||
|
expected (ErrorT &&_error)
|
||
|
{
|
||
|
::new (&m_store.error) ErrorT (std::move (_error));
|
||
|
}
|
||
|
|
||
|
~expected ()
|
||
|
{
|
||
|
if (m_valid) {
|
||
|
m_store.value.~ValueT ();
|
||
|
m_valid = false;
|
||
|
} else {
|
||
|
m_store.error.~ErrorT ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ValueT&
|
||
|
value (void)&
|
||
|
{
|
||
|
if (!m_valid)
|
||
|
throw bad_expected_access {};
|
||
|
return m_store.value;
|
||
|
}
|
||
|
|
||
|
ValueT&&
|
||
|
value (void)&&
|
||
|
{
|
||
|
if (!m_valid)
|
||
|
throw bad_expected_access {};
|
||
|
return std::move (m_store.value);
|
||
|
}
|
||
|
|
||
|
ErrorT&
|
||
|
error (void)&
|
||
|
{
|
||
|
if (m_valid)
|
||
|
throw bad_expected_access {};
|
||
|
return m_store.error;
|
||
|
}
|
||
|
|
||
|
ErrorT&&
|
||
|
error (void)&&
|
||
|
{
|
||
|
if (m_valid)
|
||
|
throw bad_expected_access {};
|
||
|
return std::move (m_store.error);
|
||
|
}
|
||
|
|
||
|
ValueT* operator-> (void)& { return &value (); }
|
||
|
ValueT& operator* (void)& { return value (); }
|
||
|
|
||
|
operator bool() const noexcept;
|
||
|
|
||
|
private:
|
||
|
union storage_t {
|
||
|
storage_t () {};
|
||
|
~storage_t () {};
|
||
|
|
||
|
char defer;
|
||
|
ValueT value;
|
||
|
ErrorT error;
|
||
|
} m_store;
|
||
|
|
||
|
bool m_valid = false;
|
||
|
};
|
||
|
};
|