diff --git a/AK/HashTable.h b/AK/HashTable.h index 5a9d98eb006..f74dfa54877 100644 --- a/AK/HashTable.h +++ b/AK/HashTable.h @@ -111,7 +111,12 @@ private: using Bucket = SinglyLinkedList; public: - HashTable() {} + HashTable() { } + HashTable(size_t capacity) + : m_buckets(new Bucket[capacity]) + , m_capacity(capacity) + { + } HashTable(const HashTable& other) { ensure_capacity(other.size()); @@ -164,6 +169,15 @@ public: HashSetResult set(const T&); HashSetResult set(T&&); + + template + void set_from(U (&from_array)[N]) + { + for (size_t i = 0; i < N; ++i) { + set(from_array[i]); + } + } + bool contains(const T&) const; void clear(); diff --git a/AK/StdLibExtras.h b/AK/StdLibExtras.h index b47a465fd16..4b38a7764c6 100644 --- a/AK/StdLibExtras.h +++ b/AK/StdLibExtras.h @@ -40,6 +40,13 @@ inline constexpr unsigned round_up_to_power_of_two(unsigned value, unsigned powe namespace AK { + +template +constexpr SizeType array_size(T (&)[N]) +{ + return N; +} + template inline constexpr T min(const T& a, const T& b) { @@ -497,6 +504,7 @@ using CopyConst = } using AK::AddConst; +using AK::array_size; using AK::ceil_div; using AK::clamp; using AK::Conditional; diff --git a/Libraries/LibGUI/CppLexer.cpp b/Libraries/LibGUI/CppLexer.cpp index ec7a62d5fd3..48ef9ce879a 100644 --- a/Libraries/LibGUI/CppLexer.cpp +++ b/Libraries/LibGUI/CppLexer.cpp @@ -26,6 +26,7 @@ #include "CppLexer.h" #include +#include #include #include @@ -67,150 +68,158 @@ static bool is_valid_nonfirst_character_of_identifier(char ch) return is_valid_first_character_of_identifier(ch) || isdigit(ch); } +constexpr const char* s_known_keywords[] = { + "alignas", + "alignof", + "and", + "and_eq", + "asm", + "bitand", + "bitor", + "bool", + "break", + "case", + "catch", + "class", + "compl", + "const", + "const_cast", + "constexpr", + "continue", + "decltype", + "default", + "delete", + "do", + "dynamic_cast", + "else", + "enum", + "explicit", + "export", + "extern", + "false", + "final", + "for", + "friend", + "goto", + "if", + "inline", + "mutable", + "namespace", + "new", + "noexcept", + "not", + "not_eq", + "nullptr", + "operator", + "or", + "or_eq", + "override", + "private", + "protected", + "public", + "register", + "reinterpret_cast", + "return", + "signed", + "sizeof", + "static", + "static_assert", + "static_cast", + "struct", + "switch", + "template", + "this", + "thread_local", + "throw", + "true", + "try", + "typedef", + "typeid", + "typename", + "union", + "using", + "virtual", + "volatile", + "while", + "xor", + "xor_eq" +}; + +constexpr const char* s_known_types[] = { + "ByteBuffer", + "CircularDeque", + "CircularQueue", + "Deque", + "DoublyLinkedList", + "FileSystemPath", + "FixedArray", + "Function", + "HashMap", + "HashTable", + "IPv4Address", + "InlineLinkedList", + "IntrusiveList", + "JsonArray", + "JsonObject", + "JsonValue", + "MappedFile", + "NetworkOrdered", + "NonnullOwnPtr", + "NonnullOwnPtrVector", + "NonnullRefPtr", + "NonnullRefPtrVector", + "Optional", + "OwnPtr", + "RefPtr", + "Result", + "ScopeGuard", + "SinglyLinkedList", + "String", + "StringBuilder", + "StringImpl", + "StringView", + "Utf8View", + "Vector", + "WeakPtr", + "auto", + "char", + "char16_t", + "char32_t", + "char8_t", + "double", + "float", + "i16", + "i32", + "i64", + "i8", + "int", + "int", + "long", + "short", + "signed", + "u16", + "u32", + "u64", + "u8", + "unsigned", + "void", + "wchar_t" +}; + static bool is_keyword(const StringView& string) { - static HashTable keywords; + static HashTable keywords(array_size(s_known_keywords)); if (keywords.is_empty()) { - keywords.set("alignas"); - keywords.set("alignof"); - keywords.set("and"); - keywords.set("and_eq"); - keywords.set("asm"); - keywords.set("bitand"); - keywords.set("bitor"); - keywords.set("bool"); - keywords.set("break"); - keywords.set("case"); - keywords.set("catch"); - keywords.set("class"); - keywords.set("compl"); - keywords.set("const"); - keywords.set("const_cast"); - keywords.set("constexpr"); - keywords.set("continue"); - keywords.set("decltype"); - keywords.set("default"); - keywords.set("delete"); - keywords.set("do"); - keywords.set("dynamic_cast"); - keywords.set("else"); - keywords.set("enum"); - keywords.set("explicit"); - keywords.set("export"); - keywords.set("extern"); - keywords.set("false"); - keywords.set("final"); - keywords.set("for"); - keywords.set("friend"); - keywords.set("goto"); - keywords.set("if"); - keywords.set("inline"); - keywords.set("mutable"); - keywords.set("namespace"); - keywords.set("new"); - keywords.set("noexcept"); - keywords.set("not"); - keywords.set("not_eq"); - keywords.set("nullptr"); - keywords.set("operator"); - keywords.set("or"); - keywords.set("or_eq"); - keywords.set("override"); - keywords.set("private"); - keywords.set("protected"); - keywords.set("public"); - keywords.set("register"); - keywords.set("reinterpret_cast"); - keywords.set("return"); - keywords.set("signed"); - keywords.set("sizeof"); - keywords.set("static"); - keywords.set("static_assert"); - keywords.set("static_cast"); - keywords.set("struct"); - keywords.set("switch"); - keywords.set("template"); - keywords.set("this"); - keywords.set("thread_local"); - keywords.set("throw"); - keywords.set("true"); - keywords.set("try"); - keywords.set("typedef"); - keywords.set("typeid"); - keywords.set("typename"); - keywords.set("union"); - keywords.set("using"); - keywords.set("virtual"); - keywords.set("volatile"); - keywords.set("while"); - keywords.set("xor"); - keywords.set("xor_eq"); + keywords.set_from(s_known_keywords); } return keywords.contains(string); } static bool is_known_type(const StringView& string) { - static HashTable types; + static HashTable types(array_size(s_known_types)); if (types.is_empty()) { - types.set("ByteBuffer"); - types.set("CircularDeque"); - types.set("CircularQueue"); - types.set("Deque"); - types.set("DoublyLinkedList"); - types.set("FileSystemPath"); - types.set("FixedArray"); - types.set("Function"); - types.set("HashMap"); - types.set("HashTable"); - types.set("IPv4Address"); - types.set("InlineLinkedList"); - types.set("IntrusiveList"); - types.set("JsonArray"); - types.set("JsonObject"); - types.set("JsonValue"); - types.set("MappedFile"); - types.set("NetworkOrdered"); - types.set("NonnullOwnPtr"); - types.set("NonnullOwnPtrVector"); - types.set("NonnullRefPtr"); - types.set("NonnullRefPtrVector"); - types.set("Optional"); - types.set("OwnPtr"); - types.set("RefPtr"); - types.set("Result"); - types.set("ScopeGuard"); - types.set("SinglyLinkedList"); - types.set("String"); - types.set("StringBuilder"); - types.set("StringImpl"); - types.set("StringView"); - types.set("Utf8View"); - types.set("Vector"); - types.set("WeakPtr"); - types.set("auto"); - types.set("char"); - types.set("char16_t"); - types.set("char32_t"); - types.set("char8_t"); - types.set("double"); - types.set("float"); - types.set("i16"); - types.set("i32"); - types.set("i64"); - types.set("i8"); - types.set("int"); - types.set("int"); - types.set("long"); - types.set("short"); - types.set("signed"); - types.set("u16"); - types.set("u32"); - types.set("u64"); - types.set("u8"); - types.set("unsigned"); - types.set("void"); - types.set("wchar_t"); + types.set_from(s_known_types); } return types.contains(string); }