mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 20:15:17 +00:00
AK: Add rvalue-ref qualifiers for Optional's value() and value_or()
This avoids a value copy when calling value() or value_or() on a temporary Optional. This is very common when using the HashMap::get() API like this: auto value = hash_map.get(key).value_or(fallback_value);
This commit is contained in:
parent
0b36499f46
commit
7dda773426
Notes:
sideshowbarker
2024-07-18 04:49:24 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/7dda7734268
2 changed files with 36 additions and 3 deletions
|
@ -127,18 +127,23 @@ public:
|
|||
|
||||
[[nodiscard]] ALWAYS_INLINE bool has_value() const { return m_has_value; }
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE T& value()
|
||||
[[nodiscard]] ALWAYS_INLINE T& value() &
|
||||
{
|
||||
VERIFY(m_has_value);
|
||||
return *__builtin_launder(reinterpret_cast<T*>(&m_storage));
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE T const& value() const
|
||||
[[nodiscard]] ALWAYS_INLINE T const& value() const&
|
||||
{
|
||||
VERIFY(m_has_value);
|
||||
return *__builtin_launder(reinterpret_cast<T const*>(&m_storage));
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE T value() &&
|
||||
{
|
||||
return release_value();
|
||||
}
|
||||
|
||||
[[nodiscard]] T release_value()
|
||||
{
|
||||
VERIFY(m_has_value);
|
||||
|
@ -148,13 +153,20 @@ public:
|
|||
return released_value;
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE T value_or(T const& fallback) const
|
||||
[[nodiscard]] ALWAYS_INLINE T value_or(T const& fallback) const&
|
||||
{
|
||||
if (m_has_value)
|
||||
return value();
|
||||
return fallback;
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE T value_or(T&& fallback) &&
|
||||
{
|
||||
if (m_has_value)
|
||||
return move(value());
|
||||
return move(fallback);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE T const& operator*() const { return value(); }
|
||||
ALWAYS_INLINE T& operator*() { return value(); }
|
||||
|
||||
|
|
|
@ -34,6 +34,27 @@ TEST_CASE(move_optional)
|
|||
EXPECT_EQ(x.has_value(), false);
|
||||
}
|
||||
|
||||
TEST_CASE(optional_rvalue_ref_qualified_getters)
|
||||
{
|
||||
struct DontCopyMe {
|
||||
DontCopyMe() { }
|
||||
~DontCopyMe() = default;
|
||||
DontCopyMe(DontCopyMe&&) = default;
|
||||
DontCopyMe& operator=(DontCopyMe&&) = default;
|
||||
DontCopyMe(DontCopyMe const&) = delete;
|
||||
DontCopyMe& operator=(DontCopyMe const&) = delete;
|
||||
|
||||
int x { 13 };
|
||||
};
|
||||
|
||||
auto make_an_optional = []() -> Optional<DontCopyMe> {
|
||||
return DontCopyMe {};
|
||||
};
|
||||
|
||||
EXPECT_EQ(make_an_optional().value().x, 13);
|
||||
EXPECT_EQ(make_an_optional().value_or(DontCopyMe {}).x, 13);
|
||||
}
|
||||
|
||||
TEST_CASE(optional_leak_1)
|
||||
{
|
||||
struct Structure {
|
||||
|
|
Loading…
Add table
Reference in a new issue