1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 06:17:35 +00:00

AK: Inline Optional functions more aggressively

This turns into much less code in the most common cases, here's why:
The normal Optional usage pattern is something like:

    auto foo = get_me_an_optional();
    if (foo.has_value())
        do_stuff_with(foo.value());

In this typical scenario, we check has_value() before calling value().
Without inlining, value() will double-check has_value() itself and
assert if it fails. Inlining allows the compiler to optimize all of
this away.
This commit is contained in:
Andreas Kling 2020-04-12 20:37:51 +02:00
parent c84b8e597a
commit 26a8984d03

View file

@ -105,12 +105,12 @@ public:
return *this; return *this;
} }
~Optional() [[gnu::always_inline]] inline ~Optional()
{ {
clear(); clear();
} }
void clear() [[gnu::always_inline]] inline void clear()
{ {
if (m_has_value) { if (m_has_value) {
value().~T(); value().~T();
@ -119,17 +119,17 @@ public:
} }
SET_TYPESTATE(consumed) SET_TYPESTATE(consumed)
bool has_value() const { return m_has_value; } [[gnu::always_inline]] inline bool has_value() const { return m_has_value; }
CALLABLE_WHEN(consumed) CALLABLE_WHEN(consumed)
T& value() [[gnu::always_inline]] inline T& value()
{ {
ASSERT(m_has_value); ASSERT(m_has_value);
return *reinterpret_cast<T*>(&m_storage); return *reinterpret_cast<T*>(&m_storage);
} }
CALLABLE_WHEN(consumed) CALLABLE_WHEN(consumed)
const T& value() const [[gnu::always_inline]] inline const T& value() const
{ {
return value_without_consume_state(); return value_without_consume_state();
} }
@ -144,7 +144,7 @@ public:
return released_value; return released_value;
} }
T value_or(const T& fallback) const [[gnu::always_inline]] inline T value_or(const T& fallback) const
{ {
if (m_has_value) if (m_has_value)
return value(); return value();
@ -153,7 +153,7 @@ public:
private: private:
// Call when we don't want to alter the consume state // Call when we don't want to alter the consume state
const T& value_without_consume_state() const [[gnu::always_inline]] inline const T& value_without_consume_state() const
{ {
ASSERT(m_has_value); ASSERT(m_has_value);
return *reinterpret_cast<const T*>(&m_storage); return *reinterpret_cast<const T*>(&m_storage);