ladybird/Libraries/LibJS/Bytecode/IdentifierTable.h
Jelle Raaijmakers e123d48043 AK: Add SentinelOptional
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.
2026-03-20 12:03:36 +01:00

55 lines
1.4 KiB
C++

/*
* Copyright (c) 2021, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/DistinctNumeric.h>
#include <AK/Utf16FlyString.h>
#include <AK/Vector.h>
namespace JS::Bytecode {
struct IdentifierTableIndex {
static constexpr u32 invalid = 0xffffffffu;
bool is_valid() const { return value != invalid; }
u32 value { 0 };
};
class IdentifierTable {
AK_MAKE_NONMOVABLE(IdentifierTable);
AK_MAKE_NONCOPYABLE(IdentifierTable);
public:
IdentifierTable() = default;
IdentifierTableIndex insert(Utf16FlyString);
Utf16FlyString const& get(IdentifierTableIndex) const;
void dump() const;
bool is_empty() const { return m_identifiers.is_empty(); }
ReadonlySpan<Utf16FlyString const> identifiers() const { return m_identifiers; }
private:
Vector<Utf16FlyString> m_identifiers;
};
}
namespace AK {
template<>
struct SentinelOptionalTraits<JS::Bytecode::IdentifierTableIndex> {
static constexpr JS::Bytecode::IdentifierTableIndex sentinel_value() { return { JS::Bytecode::IdentifierTableIndex::invalid }; }
static constexpr bool is_sentinel(JS::Bytecode::IdentifierTableIndex const& value) { return !value.is_valid(); }
};
template<>
class Optional<JS::Bytecode::IdentifierTableIndex> : public SentinelOptional<JS::Bytecode::IdentifierTableIndex> {
public:
using SentinelOptional::SentinelOptional;
};
}