util: Implement Expected::value()&& and Expected::error()&&

They are currently unused, but implementing them is closer to the
std::expected.
This commit is contained in:
MarcoFalke 2025-12-09 09:26:17 +01:00
parent fac4800959
commit fab9721430
No known key found for this signature in database
2 changed files with 27 additions and 12 deletions

View File

@ -43,6 +43,13 @@ BOOST_AUTO_TEST_CASE(expected_value)
BOOST_CHECK_EQUAL(read->x, 45);
}
BOOST_AUTO_TEST_CASE(expected_value_rvalue)
{
Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(5)};
const auto moved{std::move(no_copy).value()};
BOOST_CHECK_EQUAL(*moved, 5);
}
BOOST_AUTO_TEST_CASE(expected_value_or)
{
Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(1)};
@ -81,6 +88,20 @@ BOOST_AUTO_TEST_CASE(expected_error)
BOOST_CHECK_EQUAL(read.error(), "fail1");
}
BOOST_AUTO_TEST_CASE(expected_error_rvalue)
{
{
Expected<int, std::unique_ptr<int>> nocopy_err{Unexpected{std::make_unique<int>(7)}};
const auto moved{std::move(nocopy_err).error()};
BOOST_CHECK_EQUAL(*moved, 7);
}
{
Expected<void, std::unique_ptr<int>> void_nocopy_err{Unexpected{std::make_unique<int>(9)}};
const auto moved{std::move(void_nocopy_err).error()};
BOOST_CHECK_EQUAL(*moved, 9);
}
}
BOOST_AUTO_TEST_CASE(unexpected_error_accessors)
{
Unexpected u{std::make_unique<int>(-1)};

View File

@ -57,20 +57,21 @@ public:
constexpr bool has_value() const noexcept { return m_data.index() == 0; }
constexpr explicit operator bool() const noexcept { return has_value(); }
constexpr const T& value() const LIFETIMEBOUND
constexpr const T& value() const& LIFETIMEBOUND
{
if (!has_value()) {
throw BadExpectedAccess{};
}
return std::get<0>(m_data);
}
constexpr T& value() LIFETIMEBOUND
constexpr T& value() & LIFETIMEBOUND
{
if (!has_value()) {
throw BadExpectedAccess{};
}
return std::get<0>(m_data);
}
constexpr T&& value() && LIFETIMEBOUND { return std::move(value()); }
template <class U>
T value_or(U&& default_value) const&
@ -83,16 +84,9 @@ public:
return has_value() ? std::move(value()) : std::forward<U>(default_value);
}
constexpr const E& error() const LIFETIMEBOUND
{
assert(!has_value());
return std::get<1>(m_data);
}
constexpr E& error() LIFETIMEBOUND
{
assert(!has_value());
return std::get<1>(m_data);
}
constexpr const E& error() const& noexcept LIFETIMEBOUND { return *Assert(std::get_if<1>(&m_data)); }
constexpr E& error() & noexcept LIFETIMEBOUND { return *Assert(std::get_if<1>(&m_data)); }
constexpr E&& error() && noexcept LIFETIMEBOUND { return std::move(error()); }
constexpr T& operator*() noexcept LIFETIMEBOUND { return value(); }
constexpr const T& operator*() const noexcept LIFETIMEBOUND { return value(); }