diff --git a/Libraries/LibJS/Bytecode/IdentifierTable.h b/Libraries/LibJS/Bytecode/IdentifierTable.h index 84501d3ae63..44018d6bbe8 100644 --- a/Libraries/LibJS/Bytecode/IdentifierTable.h +++ b/Libraries/LibJS/Bytecode/IdentifierTable.h @@ -13,7 +13,8 @@ namespace JS::Bytecode { struct IdentifierTableIndex { - bool is_valid() const { return value != NumericLimits::max(); } + static constexpr u32 invalid = 0xffffffffu; + bool is_valid() const { return value != invalid; } u32 value { 0 }; }; @@ -34,3 +35,102 @@ private: }; } + +namespace AK { +template<> +class Optional : public OptionalBase { + template + friend class Optional; + +public: + using ValueType = JS::Bytecode::IdentifierTableIndex; + + Optional() = default; + + template V> + Optional(V) { } + + Optional(Optional const& other) + { + if (other.has_value()) + m_value = other.m_value; + } + + Optional(Optional&& other) + : m_value(other.m_value) + { + } + + template + requires(!IsSame>) + explicit(!IsConvertible) Optional(U&& value) + requires(!IsSame, Optional> && IsConstructible) + : m_value(forward(value)) + { + } + + template V> + Optional& operator=(V) + { + clear(); + return *this; + } + + Optional& operator=(Optional const& other) + { + if (this != &other) { + clear(); + m_value = other.m_value; + } + return *this; + } + + Optional& operator=(Optional&& other) + { + if (this != &other) { + clear(); + m_value = other.m_value; + } + return *this; + } + + void clear() + { + m_value.value = JS::Bytecode::IdentifierTableIndex::invalid; + } + + [[nodiscard]] bool has_value() const + { + return m_value.is_valid(); + } + + [[nodiscard]] JS::Bytecode::IdentifierTableIndex& value() & + { + VERIFY(has_value()); + return m_value; + } + + [[nodiscard]] JS::Bytecode::IdentifierTableIndex const& value() const& + { + VERIFY(has_value()); + return m_value; + } + + [[nodiscard]] JS::Bytecode::IdentifierTableIndex value() && + { + return release_value(); + } + + [[nodiscard]] JS::Bytecode::IdentifierTableIndex release_value() + { + VERIFY(has_value()); + JS::Bytecode::IdentifierTableIndex released_value = m_value; + clear(); + return released_value; + } + +private: + JS::Bytecode::IdentifierTableIndex m_value { JS::Bytecode::IdentifierTableIndex::invalid }; +}; + +}