ladybird/Libraries/LibJS/Bytecode/StringTable.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

53 lines
1.2 KiB
C++

/*
* Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/DistinctNumeric.h>
#include <AK/Utf16String.h>
#include <AK/Vector.h>
namespace JS::Bytecode {
struct StringTableIndex {
static constexpr u32 invalid = 0xffffffffu;
bool is_valid() const { return value != invalid; }
u32 value { 0 };
};
class StringTable {
AK_MAKE_NONMOVABLE(StringTable);
AK_MAKE_NONCOPYABLE(StringTable);
public:
StringTable() = default;
StringTableIndex insert(Utf16String);
Utf16String const& get(StringTableIndex) const;
void dump() const;
bool is_empty() const { return m_strings.is_empty(); }
private:
Vector<Utf16String> m_strings;
};
}
namespace AK {
template<>
struct SentinelOptionalTraits<JS::Bytecode::StringTableIndex> {
static constexpr JS::Bytecode::StringTableIndex sentinel_value() { return { JS::Bytecode::StringTableIndex::invalid }; }
static constexpr bool is_sentinel(JS::Bytecode::StringTableIndex const& value) { return !value.is_valid(); }
};
template<>
class Optional<JS::Bytecode::StringTableIndex> : public SentinelOptional<JS::Bytecode::StringTableIndex> {
public:
using SentinelOptional::SentinelOptional;
};
}