mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2026-04-18 18:00:31 +00:00
We specialize `Optional<T>` for value types that inherently support some kind of "empty" value or whose value range allow for a unlikely to be useful sentinel value that can mean "empty", instead of the boolean flag a regular Optional<T> needs to store. Because of padding, this often means saving 4 to 8 bytes per instance. By extending the new `SentinelOptional<T, Traits>`, these specializations are significantly simplified to just having to define what the sentinel value is, and how to identify a sentinel value.
61 lines
1.5 KiB
C++
61 lines
1.5 KiB
C++
/*
|
|
* Copyright (c) 2025, Andreas Kling <andreas@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/DistinctNumeric.h>
|
|
#include <AK/Vector.h>
|
|
#include <LibJS/Runtime/PropertyKey.h>
|
|
|
|
namespace JS::Bytecode {
|
|
|
|
struct PropertyKeyTableIndex {
|
|
static constexpr u32 invalid = 0xffffffffu;
|
|
bool is_valid() const { return value != invalid; }
|
|
u32 value { 0 };
|
|
};
|
|
|
|
class PropertyKeyTable {
|
|
AK_MAKE_NONMOVABLE(PropertyKeyTable);
|
|
AK_MAKE_NONCOPYABLE(PropertyKeyTable);
|
|
|
|
public:
|
|
PropertyKeyTable() = default;
|
|
|
|
PropertyKeyTableIndex insert(PropertyKey);
|
|
PropertyKey const& get(PropertyKeyTableIndex) const;
|
|
void dump() const;
|
|
bool is_empty() const { return m_property_keys.is_empty(); }
|
|
|
|
ReadonlySpan<PropertyKey const> property_keys() const { return m_property_keys; }
|
|
|
|
void visit_edges(GC::Cell::Visitor& visitor)
|
|
{
|
|
for (auto& key : m_property_keys)
|
|
key.visit_edges(visitor);
|
|
}
|
|
|
|
private:
|
|
Vector<PropertyKey> m_property_keys;
|
|
};
|
|
|
|
}
|
|
|
|
namespace AK {
|
|
|
|
template<>
|
|
struct SentinelOptionalTraits<JS::Bytecode::PropertyKeyTableIndex> {
|
|
static constexpr JS::Bytecode::PropertyKeyTableIndex sentinel_value() { return { JS::Bytecode::PropertyKeyTableIndex::invalid }; }
|
|
static constexpr bool is_sentinel(JS::Bytecode::PropertyKeyTableIndex const& value) { return !value.is_valid(); }
|
|
};
|
|
|
|
template<>
|
|
class Optional<JS::Bytecode::PropertyKeyTableIndex> : public SentinelOptional<JS::Bytecode::PropertyKeyTableIndex> {
|
|
public:
|
|
using SentinelOptional::SentinelOptional;
|
|
};
|
|
|
|
}
|