Commit 8af59d1f98
Changed files (25)
lib
src
test
src
lib/compiler/aro/aro/LangOpts.zig
@@ -47,7 +47,7 @@ pub const Standard = enum {
/// Working Draft for ISO C23 with GNU extensions
gnu23,
- const NameMap = std.ComptimeStringMap(Standard, .{
+ const NameMap = std.StaticStringMap(Standard).initComptime(.{
.{ "c89", .c89 }, .{ "c90", .c89 }, .{ "iso9899:1990", .c89 },
.{ "iso9899:199409", .iso9899 }, .{ "gnu89", .gnu89 }, .{ "gnu90", .gnu89 },
.{ "c99", .c99 }, .{ "iso9899:1999", .c99 }, .{ "c9x", .c99 },
lib/compiler/aro/aro/Preprocessor.zig
@@ -1709,7 +1709,7 @@ fn expandFuncMacro(
}
if (!pp.comp.langopts.standard.atLeast(.c23)) break :res not_found;
- const attrs = std.ComptimeStringMap([]const u8, .{
+ const attrs = std.StaticStringMap([]const u8).initComptime(.{
.{ "deprecated", "201904L\n" },
.{ "fallthrough", "201904L\n" },
.{ "maybe_unused", "201904L\n" },
lib/compiler/aro/aro/Tokenizer.zig
@@ -872,7 +872,7 @@ pub const Token = struct {
};
}
- const all_kws = std.ComptimeStringMap(Id, .{
+ const all_kws = std.StaticStringMap(Id).initComptime(.{
.{ "auto", auto: {
@setEvalBranchQuota(3000);
break :auto .keyword_auto;
lib/compiler/resinator/errors.zig
@@ -240,7 +240,7 @@ pub const ErrorDetails = struct {
// see https://github.com/ziglang/zig/issues/15395
_: u26 = 0,
- pub const strings = std.ComptimeStringMap([]const u8, .{
+ pub const strings = std.StaticStringMap([]const u8).initComptime(.{
.{ "number", "number" },
.{ "number_expression", "number expression" },
.{ "string_literal", "quoted string literal" },
lib/compiler/resinator/rc.zig
@@ -47,7 +47,10 @@ pub const Resource = enum {
fontdir_num,
manifest_num,
- const map = std.ComptimeStringMapWithEql(Resource, .{
+ const map = std.StaticStringMapWithEql(
+ Resource,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "ACCELERATORS", .accelerators },
.{ "BITMAP", .bitmap },
.{ "CURSOR", .cursor },
@@ -67,7 +70,7 @@ pub const Resource = enum {
.{ "TOOLBAR", .toolbar },
.{ "VERSIONINFO", .versioninfo },
.{ "VXD", .vxd },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
pub fn fromString(bytes: SourceBytes) Resource {
const maybe_ordinal = res.NameOrOrdinal.maybeOrdinalFromString(bytes);
@@ -157,20 +160,26 @@ pub const OptionalStatements = enum {
menu,
style,
- pub const map = std.ComptimeStringMapWithEql(OptionalStatements, .{
+ pub const map = std.StaticStringMapWithEql(
+ OptionalStatements,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "CHARACTERISTICS", .characteristics },
.{ "LANGUAGE", .language },
.{ "VERSION", .version },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
- pub const dialog_map = std.ComptimeStringMapWithEql(OptionalStatements, .{
+ pub const dialog_map = std.StaticStringMapWithEql(
+ OptionalStatements,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "CAPTION", .caption },
.{ "CLASS", .class },
.{ "EXSTYLE", .exstyle },
.{ "FONT", .font },
.{ "MENU", .menu },
.{ "STYLE", .style },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
};
pub const Control = enum {
@@ -197,7 +206,10 @@ pub const Control = enum {
state3,
userbutton,
- pub const map = std.ComptimeStringMapWithEql(Control, .{
+ pub const map = std.StaticStringMapWithEql(
+ Control,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "AUTO3STATE", .auto3state },
.{ "AUTOCHECKBOX", .autocheckbox },
.{ "AUTORADIOBUTTON", .autoradiobutton },
@@ -220,7 +232,7 @@ pub const Control = enum {
.{ "SCROLLBAR", .scrollbar },
.{ "STATE3", .state3 },
.{ "USERBUTTON", .userbutton },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
pub fn hasTextParam(control: Control) bool {
switch (control) {
@@ -231,14 +243,17 @@ pub const Control = enum {
};
pub const ControlClass = struct {
- pub const map = std.ComptimeStringMapWithEql(res.ControlClass, .{
+ pub const map = std.StaticStringMapWithEql(
+ res.ControlClass,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "BUTTON", .button },
.{ "EDIT", .edit },
.{ "STATIC", .static },
.{ "LISTBOX", .listbox },
.{ "SCROLLBAR", .scrollbar },
.{ "COMBOBOX", .combobox },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
/// Like `map.get` but works on WTF16 strings, for use with parsed
/// string literals ("BUTTON", or even "\x42UTTON")
@@ -280,10 +295,13 @@ pub const MenuItem = enum {
menuitem,
popup,
- pub const map = std.ComptimeStringMapWithEql(MenuItem, .{
+ pub const map = std.StaticStringMapWithEql(
+ MenuItem,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "MENUITEM", .menuitem },
.{ "POPUP", .popup },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
pub fn isSeparator(bytes: []const u8) bool {
return std.ascii.eqlIgnoreCase(bytes, "SEPARATOR");
@@ -297,14 +315,17 @@ pub const MenuItem = enum {
menubarbreak,
menubreak,
- pub const map = std.ComptimeStringMapWithEql(Option, .{
+ pub const map = std.StaticStringMapWithEql(
+ Option,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "CHECKED", .checked },
.{ "GRAYED", .grayed },
.{ "HELP", .help },
.{ "INACTIVE", .inactive },
.{ "MENUBARBREAK", .menubarbreak },
.{ "MENUBREAK", .menubreak },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
};
};
@@ -312,10 +333,13 @@ pub const ToolbarButton = enum {
button,
separator,
- pub const map = std.ComptimeStringMapWithEql(ToolbarButton, .{
+ pub const map = std.StaticStringMapWithEql(
+ ToolbarButton,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "BUTTON", .button },
.{ "SEPARATOR", .separator },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
};
pub const VersionInfo = enum {
@@ -327,7 +351,10 @@ pub const VersionInfo = enum {
file_type,
file_subtype,
- pub const map = std.ComptimeStringMapWithEql(VersionInfo, .{
+ pub const map = std.StaticStringMapWithEql(
+ VersionInfo,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "FILEVERSION", .file_version },
.{ "PRODUCTVERSION", .product_version },
.{ "FILEFLAGSMASK", .file_flags_mask },
@@ -335,17 +362,20 @@ pub const VersionInfo = enum {
.{ "FILEOS", .file_os },
.{ "FILETYPE", .file_type },
.{ "FILESUBTYPE", .file_subtype },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
};
pub const VersionBlock = enum {
block,
value,
- pub const map = std.ComptimeStringMapWithEql(VersionBlock, .{
+ pub const map = std.StaticStringMapWithEql(
+ VersionBlock,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "BLOCK", .block },
.{ "VALUE", .value },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
};
/// Keywords that are be the first token in a statement and (if so) dictate how the rest
@@ -356,12 +386,15 @@ pub const TopLevelKeywords = enum {
characteristics,
stringtable,
- pub const map = std.ComptimeStringMapWithEql(TopLevelKeywords, .{
+ pub const map = std.StaticStringMapWithEql(
+ TopLevelKeywords,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "LANGUAGE", .language },
.{ "VERSION", .version },
.{ "CHARACTERISTICS", .characteristics },
.{ "STRINGTABLE", .stringtable },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
};
pub const CommonResourceAttributes = enum {
@@ -375,7 +408,10 @@ pub const CommonResourceAttributes = enum {
shared,
nonshared,
- pub const map = std.ComptimeStringMapWithEql(CommonResourceAttributes, .{
+ pub const map = std.StaticStringMapWithEql(
+ CommonResourceAttributes,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "PRELOAD", .preload },
.{ "LOADONCALL", .loadoncall },
.{ "FIXED", .fixed },
@@ -385,7 +421,7 @@ pub const CommonResourceAttributes = enum {
.{ "IMPURE", .impure },
.{ "SHARED", .shared },
.{ "NONSHARED", .nonshared },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
};
pub const AcceleratorTypeAndOptions = enum {
@@ -396,12 +432,15 @@ pub const AcceleratorTypeAndOptions = enum {
shift,
control,
- pub const map = std.ComptimeStringMapWithEql(AcceleratorTypeAndOptions, .{
+ pub const map = std.StaticStringMapWithEql(
+ AcceleratorTypeAndOptions,
+ std.static_string_map.eqlAsciiIgnoreCase,
+ ).initComptime(.{
.{ "VIRTKEY", .virtkey },
.{ "ASCII", .ascii },
.{ "NOINVERT", .noinvert },
.{ "ALT", .alt },
.{ "SHIFT", .shift },
.{ "CONTROL", .control },
- }, std.comptime_string_map.eqlAsciiIgnoreCase);
+ });
};
lib/std/crypto/Certificate.zig
@@ -19,7 +19,7 @@ pub const Algorithm = enum {
md5WithRSAEncryption,
curveEd25519,
- pub const map = std.ComptimeStringMap(Algorithm, .{
+ pub const map = std.StaticStringMap(Algorithm).initComptime(.{
.{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05 }, .sha1WithRSAEncryption },
.{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B }, .sha256WithRSAEncryption },
.{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C }, .sha384WithRSAEncryption },
@@ -52,7 +52,7 @@ pub const AlgorithmCategory = enum {
X9_62_id_ecPublicKey,
curveEd25519,
- pub const map = std.ComptimeStringMap(AlgorithmCategory, .{
+ pub const map = std.StaticStringMap(AlgorithmCategory).initComptime(.{
.{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }, .rsaEncryption },
.{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 }, .X9_62_id_ecPublicKey },
.{ &[_]u8{ 0x2B, 0x65, 0x70 }, .curveEd25519 },
@@ -73,7 +73,7 @@ pub const Attribute = enum {
pkcs9_emailAddress,
domainComponent,
- pub const map = std.ComptimeStringMap(Attribute, .{
+ pub const map = std.StaticStringMap(Attribute).initComptime(.{
.{ &[_]u8{ 0x55, 0x04, 0x03 }, .commonName },
.{ &[_]u8{ 0x55, 0x04, 0x05 }, .serialNumber },
.{ &[_]u8{ 0x55, 0x04, 0x06 }, .countryName },
@@ -94,7 +94,7 @@ pub const NamedCurve = enum {
secp521r1,
X9_62_prime256v1,
- pub const map = std.ComptimeStringMap(NamedCurve, .{
+ pub const map = std.StaticStringMap(NamedCurve).initComptime(.{
.{ &[_]u8{ 0x2B, 0x81, 0x04, 0x00, 0x22 }, .secp384r1 },
.{ &[_]u8{ 0x2B, 0x81, 0x04, 0x00, 0x23 }, .secp521r1 },
.{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }, .X9_62_prime256v1 },
@@ -130,7 +130,7 @@ pub const ExtensionId = enum {
netscape_cert_type,
netscape_comment,
- pub const map = std.ComptimeStringMap(ExtensionId, .{
+ pub const map = std.StaticStringMap(ExtensionId).initComptime(.{
.{ &[_]u8{ 0x55, 0x04, 0x03 }, .commonName },
.{ &[_]u8{ 0x55, 0x1D, 0x01 }, .authority_key_identifier },
.{ &[_]u8{ 0x55, 0x1D, 0x07 }, .subject_alt_name },
lib/std/fs/test.zig
@@ -1641,7 +1641,7 @@ test "walker" {
// iteration order of walker is undefined, so need lookup maps to check against
- const expected_paths = std.ComptimeStringMap(void, .{
+ const expected_paths = std.StaticStringMap(void).initComptime(.{
.{"dir1"},
.{"dir2"},
.{"dir3"},
@@ -1651,7 +1651,7 @@ test "walker" {
.{"dir3" ++ fs.path.sep_str ++ "sub2" ++ fs.path.sep_str ++ "subsub1"},
});
- const expected_basenames = std.ComptimeStringMap(void, .{
+ const expected_basenames = std.StaticStringMap(void).initComptime(.{
.{"dir1"},
.{"dir2"},
.{"dir3"},
@@ -1661,8 +1661,8 @@ test "walker" {
.{"subsub1"},
});
- for (expected_paths.kvs) |kv| {
- try tmp.dir.makePath(kv.key);
+ for (expected_paths.keys()) |key| {
+ try tmp.dir.makePath(key);
}
var walker = try tmp.dir.walk(testing.allocator);
lib/std/http/Client.zig
@@ -1570,7 +1570,7 @@ pub const RequestOptions = struct {
};
fn validateUri(uri: Uri, arena: Allocator) !struct { Connection.Protocol, Uri } {
- const protocol_map = std.ComptimeStringMap(Connection.Protocol, .{
+ const protocol_map = std.StaticStringMap(Connection.Protocol).initComptime(.{
.{ "http", .plain },
.{ "ws", .plain },
.{ "https", .tls },
lib/std/zig/AstGen.zig
@@ -10125,7 +10125,7 @@ fn calleeExpr(
}
}
-const primitive_instrs = std.ComptimeStringMap(Zir.Inst.Ref, .{
+const primitive_instrs = std.StaticStringMap(Zir.Inst.Ref).initComptime(.{
.{ "anyerror", .anyerror_type },
.{ "anyframe", .anyframe_type },
.{ "anyopaque", .anyopaque_type },
@@ -10173,14 +10173,14 @@ const primitive_instrs = std.ComptimeStringMap(Zir.Inst.Ref, .{
comptime {
// These checks ensure that std.zig.primitives stays in sync with the primitive->Zir map.
const primitives = std.zig.primitives;
- for (primitive_instrs.kvs) |kv| {
- if (!primitives.isPrimitive(kv.key)) {
- @compileError("std.zig.isPrimitive() is not aware of Zir instr '" ++ @tagName(kv.value) ++ "'");
+ for (primitive_instrs.keys(), primitive_instrs.values()) |key, value| {
+ if (!primitives.isPrimitive(key)) {
+ @compileError("std.zig.isPrimitive() is not aware of Zir instr '" ++ @tagName(value) ++ "'");
}
}
- for (primitives.names.kvs) |kv| {
- if (primitive_instrs.get(kv.key) == null) {
- @compileError("std.zig.primitives entry '" ++ kv.key ++ "' does not have a corresponding Zir instr");
+ for (primitives.names.keys()) |key| {
+ if (primitive_instrs.get(key) == null) {
+ @compileError("std.zig.primitives entry '" ++ key ++ "' does not have a corresponding Zir instr");
}
}
}
lib/std/zig/BuiltinFn.zig
@@ -160,7 +160,7 @@ param_count: ?u8,
pub const list = list: {
@setEvalBranchQuota(3000);
- break :list std.ComptimeStringMap(@This(), .{
+ break :list std.StaticStringMap(@This()).initComptime(.{
.{
"@addWithOverflow",
.{
lib/std/zig/primitives.zig
@@ -2,7 +2,7 @@ const std = @import("std");
/// Set of primitive type and value names.
/// Does not include `_` or integer type names.
-pub const names = std.ComptimeStringMap(void, .{
+pub const names = std.StaticStringMap(void).initComptime(.{
.{"anyerror"},
.{"anyframe"},
.{"anyopaque"},
lib/std/zig/render.zig
@@ -2886,11 +2886,11 @@ fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote
// If we read the whole thing, we have to do further checks.
const longest_keyword_or_primitive_len = comptime blk: {
var longest = 0;
- for (primitives.names.kvs) |kv| {
- if (kv.key.len > longest) longest = kv.key.len;
+ for (primitives.names.keys()) |key| {
+ if (key.len > longest) longest = key.len;
}
- for (std.zig.Token.keywords.kvs) |kv| {
- if (kv.key.len > longest) longest = kv.key.len;
+ for (std.zig.Token.keywords.keys()) |key| {
+ if (key.len > longest) longest = key.len;
}
break :blk longest;
};
lib/std/zig/tokenizer.zig
@@ -9,7 +9,7 @@ pub const Token = struct {
end: usize,
};
- pub const keywords = std.ComptimeStringMap(Tag, .{
+ pub const keywords = std.StaticStringMap(Tag).initComptime(.{
.{ "addrspace", .keyword_addrspace },
.{ "align", .keyword_align },
.{ "allowzero", .keyword_allowzero },
lib/std/comptime_string_map.zig
@@ -1,320 +0,0 @@
-const std = @import("std.zig");
-const mem = std.mem;
-
-/// Comptime string map optimized for small sets of disparate string keys.
-/// Works by separating the keys by length at comptime and only checking strings of
-/// equal length at runtime.
-///
-/// `kvs_list` expects a list of `struct { []const u8, V }` (key-value pair) tuples.
-/// You can pass `struct { []const u8 }` (only keys) tuples if `V` is `void`.
-pub fn ComptimeStringMap(
- comptime V: type,
- comptime kvs_list: anytype,
-) type {
- return ComptimeStringMapWithEql(V, kvs_list, defaultEql);
-}
-
-/// Like `std.mem.eql`, but takes advantage of the fact that the lengths
-/// of `a` and `b` are known to be equal.
-pub fn defaultEql(a: []const u8, b: []const u8) bool {
- if (a.ptr == b.ptr) return true;
- for (a, b) |a_elem, b_elem| {
- if (a_elem != b_elem) return false;
- }
- return true;
-}
-
-/// Like `std.ascii.eqlIgnoreCase` but takes advantage of the fact that
-/// the lengths of `a` and `b` are known to be equal.
-pub fn eqlAsciiIgnoreCase(a: []const u8, b: []const u8) bool {
- if (a.ptr == b.ptr) return true;
- for (a, b) |a_c, b_c| {
- if (std.ascii.toLower(a_c) != std.ascii.toLower(b_c)) return false;
- }
- return true;
-}
-
-/// ComptimeStringMap, but accepts an equality function (`eql`).
-/// The `eql` function is only called to determine the equality
-/// of equal length strings. Any strings that are not equal length
-/// are never compared using the `eql` function.
-pub fn ComptimeStringMapWithEql(
- comptime V: type,
- comptime kvs_list: anytype,
- comptime eql: fn (a: []const u8, b: []const u8) bool,
-) type {
- const empty_list = kvs_list.len == 0;
- const precomputed = blk: {
- @setEvalBranchQuota(1500);
- const KV = struct {
- key: []const u8,
- value: V,
- };
- if (empty_list)
- break :blk .{};
- var sorted_kvs: [kvs_list.len]KV = undefined;
- for (kvs_list, 0..) |kv, i| {
- if (V != void) {
- sorted_kvs[i] = .{ .key = kv.@"0", .value = kv.@"1" };
- } else {
- sorted_kvs[i] = .{ .key = kv.@"0", .value = {} };
- }
- }
-
- const SortContext = struct {
- kvs: []KV,
-
- pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
- return ctx.kvs[a].key.len < ctx.kvs[b].key.len;
- }
-
- pub fn swap(ctx: @This(), a: usize, b: usize) void {
- return std.mem.swap(KV, &ctx.kvs[a], &ctx.kvs[b]);
- }
- };
- mem.sortUnstableContext(0, sorted_kvs.len, SortContext{ .kvs = &sorted_kvs });
-
- const min_len = sorted_kvs[0].key.len;
- const max_len = sorted_kvs[sorted_kvs.len - 1].key.len;
- var len_indexes: [max_len + 1]usize = undefined;
- var len: usize = 0;
- var i: usize = 0;
- while (len <= max_len) : (len += 1) {
- // find the first keyword len == len
- while (len > sorted_kvs[i].key.len) {
- i += 1;
- }
- len_indexes[len] = i;
- }
- break :blk .{
- .min_len = min_len,
- .max_len = max_len,
- .sorted_kvs = sorted_kvs,
- .len_indexes = len_indexes,
- };
- };
-
- return struct {
- /// Array of `struct { key: []const u8, value: V }` where `value` is `void{}` if `V` is `void`.
- /// Sorted by `key` length.
- pub const kvs = precomputed.sorted_kvs;
-
- /// Checks if the map has a value for the key.
- pub fn has(str: []const u8) bool {
- return get(str) != null;
- }
-
- /// Returns the value for the key if any, else null.
- pub fn get(str: []const u8) ?V {
- if (empty_list)
- return null;
-
- return precomputed.sorted_kvs[getIndex(str) orelse return null].value;
- }
-
- pub fn getIndex(str: []const u8) ?usize {
- if (empty_list)
- return null;
-
- if (str.len < precomputed.min_len or str.len > precomputed.max_len)
- return null;
-
- var i = precomputed.len_indexes[str.len];
- while (true) {
- const kv = precomputed.sorted_kvs[i];
- if (kv.key.len != str.len)
- return null;
- if (eql(kv.key, str))
- return i;
- i += 1;
- if (i >= precomputed.sorted_kvs.len)
- return null;
- }
- }
- };
-}
-
-const TestEnum = enum {
- A,
- B,
- C,
- D,
- E,
-};
-
-test "list literal of list literals" {
- const map = ComptimeStringMap(TestEnum, .{
- .{ "these", .D },
- .{ "have", .A },
- .{ "nothing", .B },
- .{ "incommon", .C },
- .{ "samelen", .E },
- });
-
- try testMap(map);
-
- // Default comparison is case sensitive
- try std.testing.expect(null == map.get("NOTHING"));
-}
-
-test "array of structs" {
- const KV = struct { []const u8, TestEnum };
- const map = ComptimeStringMap(TestEnum, [_]KV{
- .{ "these", .D },
- .{ "have", .A },
- .{ "nothing", .B },
- .{ "incommon", .C },
- .{ "samelen", .E },
- });
-
- try testMap(map);
-}
-
-test "slice of structs" {
- const KV = struct { []const u8, TestEnum };
- const slice: []const KV = &[_]KV{
- .{ "these", .D },
- .{ "have", .A },
- .{ "nothing", .B },
- .{ "incommon", .C },
- .{ "samelen", .E },
- };
- const map = ComptimeStringMap(TestEnum, slice);
-
- try testMap(map);
-}
-
-fn testMap(comptime map: anytype) !void {
- try std.testing.expectEqual(TestEnum.A, map.get("have").?);
- try std.testing.expectEqual(TestEnum.B, map.get("nothing").?);
- try std.testing.expect(null == map.get("missing"));
- try std.testing.expectEqual(TestEnum.D, map.get("these").?);
- try std.testing.expectEqual(TestEnum.E, map.get("samelen").?);
-
- try std.testing.expect(!map.has("missing"));
- try std.testing.expect(map.has("these"));
-
- try std.testing.expect(null == map.get(""));
- try std.testing.expect(null == map.get("averylongstringthathasnomatches"));
-}
-
-test "void value type, slice of structs" {
- const KV = struct { []const u8 };
- const slice: []const KV = &[_]KV{
- .{"these"},
- .{"have"},
- .{"nothing"},
- .{"incommon"},
- .{"samelen"},
- };
- const map = ComptimeStringMap(void, slice);
-
- try testSet(map);
-
- // Default comparison is case sensitive
- try std.testing.expect(null == map.get("NOTHING"));
-}
-
-test "void value type, list literal of list literals" {
- const map = ComptimeStringMap(void, .{
- .{"these"},
- .{"have"},
- .{"nothing"},
- .{"incommon"},
- .{"samelen"},
- });
-
- try testSet(map);
-}
-
-fn testSet(comptime map: anytype) !void {
- try std.testing.expectEqual({}, map.get("have").?);
- try std.testing.expectEqual({}, map.get("nothing").?);
- try std.testing.expect(null == map.get("missing"));
- try std.testing.expectEqual({}, map.get("these").?);
- try std.testing.expectEqual({}, map.get("samelen").?);
-
- try std.testing.expect(!map.has("missing"));
- try std.testing.expect(map.has("these"));
-
- try std.testing.expect(null == map.get(""));
- try std.testing.expect(null == map.get("averylongstringthathasnomatches"));
-}
-
-test "ComptimeStringMapWithEql" {
- const map = ComptimeStringMapWithEql(TestEnum, .{
- .{ "these", .D },
- .{ "have", .A },
- .{ "nothing", .B },
- .{ "incommon", .C },
- .{ "samelen", .E },
- }, eqlAsciiIgnoreCase);
-
- try testMap(map);
- try std.testing.expectEqual(TestEnum.A, map.get("HAVE").?);
- try std.testing.expectEqual(TestEnum.E, map.get("SameLen").?);
- try std.testing.expect(null == map.get("SameLength"));
-
- try std.testing.expect(map.has("ThESe"));
-}
-
-test "empty" {
- const m1 = ComptimeStringMap(usize, .{});
- try std.testing.expect(null == m1.get("anything"));
-
- const m2 = ComptimeStringMapWithEql(usize, .{}, eqlAsciiIgnoreCase);
- try std.testing.expect(null == m2.get("anything"));
-}
-
-test "redundant entries" {
- const map = ComptimeStringMap(TestEnum, .{
- .{ "redundant", .D },
- .{ "theNeedle", .A },
- .{ "redundant", .B },
- .{ "re" ++ "dundant", .C },
- .{ "redun" ++ "dant", .E },
- });
-
- // No promises about which one you get:
- try std.testing.expect(null != map.get("redundant"));
-
- // Default map is not case sensitive:
- try std.testing.expect(null == map.get("REDUNDANT"));
-
- try std.testing.expectEqual(TestEnum.A, map.get("theNeedle").?);
-}
-
-test "redundant insensitive" {
- const map = ComptimeStringMapWithEql(TestEnum, .{
- .{ "redundant", .D },
- .{ "theNeedle", .A },
- .{ "redundanT", .B },
- .{ "RE" ++ "dundant", .C },
- .{ "redun" ++ "DANT", .E },
- }, eqlAsciiIgnoreCase);
-
- // No promises about which result you'll get ...
- try std.testing.expect(null != map.get("REDUNDANT"));
- try std.testing.expect(null != map.get("ReDuNdAnT"));
-
- try std.testing.expectEqual(TestEnum.A, map.get("theNeedle").?);
-}
-
-test "comptime-only value" {
- const map = std.ComptimeStringMap(type, .{
- .{ "a", struct {
- pub const foo = 1;
- } },
- .{ "b", struct {
- pub const foo = 2;
- } },
- .{ "c", struct {
- pub const foo = 3;
- } },
- });
-
- try std.testing.expect(map.get("a").?.foo == 1);
- try std.testing.expect(map.get("b").?.foo == 2);
- try std.testing.expect(map.get("c").?.foo == 3);
- try std.testing.expect(map.get("d") == null);
-}
lib/std/meta.zig
@@ -19,7 +19,7 @@ pub const isTag = @compileError("deprecated; use 'tagged_value == @field(E, tag_
/// Returns the variant of an enum type, `T`, which is named `str`, or `null` if no such variant exists.
pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
- // Using ComptimeStringMap here is more performant, but it will start to take too
+ // Using StaticStringMap here is more performant, but it will start to take too
// long to compile if the enum is large enough, due to the current limits of comptime
// performance when doing things like constructing lookup maps at comptime.
// TODO The '100' here is arbitrary and should be increased when possible:
@@ -34,7 +34,7 @@ pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
}
break :build_kvs kvs_array[0..];
};
- const map = std.ComptimeStringMap(T, kvs);
+ const map = std.StaticStringMap(T).initComptime(kvs);
return map.get(str);
} else {
inline for (@typeInfo(T).Enum.fields) |enumField| {
lib/std/static_string_map.zig
@@ -0,0 +1,502 @@
+const std = @import("std.zig");
+const mem = std.mem;
+
+/// Static string map optimized for small sets of disparate string keys.
+/// Works by separating the keys by length at initialization and only checking
+/// strings of equal length at runtime.
+pub fn StaticStringMap(comptime V: type) type {
+ return StaticStringMapWithEql(V, defaultEql);
+}
+
+/// Like `std.mem.eql`, but takes advantage of the fact that the lengths
+/// of `a` and `b` are known to be equal.
+pub fn defaultEql(a: []const u8, b: []const u8) bool {
+ if (a.ptr == b.ptr) return true;
+ for (a, b) |a_elem, b_elem| {
+ if (a_elem != b_elem) return false;
+ }
+ return true;
+}
+
+/// Like `std.ascii.eqlIgnoreCase` but takes advantage of the fact that
+/// the lengths of `a` and `b` are known to be equal.
+pub fn eqlAsciiIgnoreCase(a: []const u8, b: []const u8) bool {
+ if (a.ptr == b.ptr) return true;
+ for (a, b) |a_c, b_c| {
+ if (std.ascii.toLower(a_c) != std.ascii.toLower(b_c)) return false;
+ }
+ return true;
+}
+
+/// StaticStringMap, but accepts an equality function (`eql`).
+/// The `eql` function is only called to determine the equality
+/// of equal length strings. Any strings that are not equal length
+/// are never compared using the `eql` function.
+pub fn StaticStringMapWithEql(
+ comptime V: type,
+ comptime eql: fn (a: []const u8, b: []const u8) bool,
+) type {
+ return struct {
+ kvs: *const KVs = &empty_kvs,
+ len_indexes: [*]const u32 = &empty_len_indexes,
+ len_indexes_len: u32 = 0,
+ min_len: u32 = std.math.maxInt(u32),
+ max_len: u32 = 0,
+
+ pub const KV = struct {
+ key: []const u8,
+ value: V,
+ };
+
+ const Self = @This();
+ const KVs = struct {
+ keys: [*]const []const u8,
+ values: [*]const V,
+ len: u32,
+ };
+ const empty_kvs = KVs{
+ .keys = &empty_keys,
+ .values = &empty_vals,
+ .len = 0,
+ };
+ const empty_len_indexes = [0]u32{};
+ const empty_keys = [0][]const u8{};
+ const empty_vals = [0]V{};
+
+ /// Returns a map backed by static, comptime allocated memory.
+ ///
+ /// `kvs_list` must be either a list of `struct { []const u8, V }`
+ /// (key-value pair) tuples, or a list of `struct { []const u8 }`
+ /// (only keys) tuples if `V` is `void`.
+ pub inline fn initComptime(comptime kvs_list: anytype) Self {
+ comptime {
+ @setEvalBranchQuota(30 * kvs_list.len);
+ var self = Self{};
+ if (kvs_list.len == 0)
+ return self;
+
+ var sorted_keys: [kvs_list.len][]const u8 = undefined;
+ var sorted_vals: [kvs_list.len]V = undefined;
+
+ self.initSortedKVs(kvs_list, &sorted_keys, &sorted_vals);
+ const final_keys = sorted_keys;
+ const final_vals = sorted_vals;
+ self.kvs = &.{
+ .keys = &final_keys,
+ .values = &final_vals,
+ .len = @intCast(kvs_list.len),
+ };
+
+ var len_indexes: [self.max_len + 1]u32 = undefined;
+ self.initLenIndexes(&len_indexes);
+ const final_len_indexes = len_indexes;
+ self.len_indexes = &final_len_indexes;
+ self.len_indexes_len = @intCast(len_indexes.len);
+ return self;
+ }
+ }
+
+ /// Returns a map backed by memory allocated with `allocator`.
+ ///
+ /// Handles `kvs_list` the same way as `initComptime()`.
+ pub fn init(kvs_list: anytype, allocator: mem.Allocator) !Self {
+ var self = Self{};
+ if (kvs_list.len == 0)
+ return self;
+
+ const sorted_keys = try allocator.alloc([]const u8, kvs_list.len);
+ errdefer allocator.free(sorted_keys);
+ const sorted_vals = try allocator.alloc(V, kvs_list.len);
+ errdefer allocator.free(sorted_vals);
+ const kvs = try allocator.create(KVs);
+ errdefer allocator.destroy(kvs);
+
+ self.initSortedKVs(kvs_list, sorted_keys, sorted_vals);
+ kvs.* = .{
+ .keys = sorted_keys.ptr,
+ .values = sorted_vals.ptr,
+ .len = kvs_list.len,
+ };
+ self.kvs = kvs;
+
+ const len_indexes = try allocator.alloc(u32, self.max_len + 1);
+ self.initLenIndexes(len_indexes);
+ self.len_indexes = len_indexes.ptr;
+ self.len_indexes_len = @intCast(len_indexes.len);
+ return self;
+ }
+
+ /// this method should only be used with init() and not with initComptime().
+ pub fn deinit(self: Self, allocator: mem.Allocator) void {
+ allocator.free(self.len_indexes[0..self.len_indexes_len]);
+ allocator.free(self.kvs.keys[0..self.kvs.len]);
+ allocator.free(self.kvs.values[0..self.kvs.len]);
+ allocator.destroy(self.kvs);
+ }
+
+ const SortContext = struct {
+ keys: [][]const u8,
+ vals: []V,
+
+ pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
+ return ctx.keys[a].len < ctx.keys[b].len;
+ }
+
+ pub fn swap(ctx: @This(), a: usize, b: usize) void {
+ std.mem.swap([]const u8, &ctx.keys[a], &ctx.keys[b]);
+ std.mem.swap(V, &ctx.vals[a], &ctx.vals[b]);
+ }
+ };
+
+ fn initSortedKVs(
+ self: *Self,
+ kvs_list: anytype,
+ sorted_keys: [][]const u8,
+ sorted_vals: []V,
+ ) void {
+ for (kvs_list, 0..) |kv, i| {
+ sorted_keys[i] = kv.@"0";
+ sorted_vals[i] = if (V == void) {} else kv.@"1";
+ self.min_len = @intCast(@min(self.min_len, kv.@"0".len));
+ self.max_len = @intCast(@max(self.max_len, kv.@"0".len));
+ }
+ mem.sortUnstableContext(0, sorted_keys.len, SortContext{
+ .keys = sorted_keys,
+ .vals = sorted_vals,
+ });
+ }
+
+ fn initLenIndexes(self: Self, len_indexes: []u32) void {
+ var len: usize = 0;
+ var i: u32 = 0;
+ while (len <= self.max_len) : (len += 1) {
+ // find the first keyword len == len
+ while (len > self.kvs.keys[i].len) {
+ i += 1;
+ }
+ len_indexes[len] = i;
+ }
+ }
+
+ /// Checks if the map has a value for the key.
+ pub fn has(self: Self, str: []const u8) bool {
+ return self.get(str) != null;
+ }
+
+ /// Returns the value for the key if any, else null.
+ pub fn get(self: Self, str: []const u8) ?V {
+ if (self.kvs.len == 0)
+ return null;
+
+ return self.kvs.values[self.getIndex(str) orelse return null];
+ }
+
+ pub fn getIndex(self: Self, str: []const u8) ?usize {
+ const kvs = self.kvs.*;
+ if (kvs.len == 0)
+ return null;
+
+ if (str.len < self.min_len or str.len > self.max_len)
+ return null;
+
+ var i = self.len_indexes[str.len];
+ while (true) {
+ const key = kvs.keys[i];
+ if (key.len != str.len)
+ return null;
+ if (eql(key, str))
+ return i;
+ i += 1;
+ if (i >= kvs.len)
+ return null;
+ }
+ }
+
+ /// Returns the longest key, value pair where key is a prefix of `str`
+ /// else null.
+ pub fn getLongestPrefix(self: Self, str: []const u8) ?KV {
+ if (self.kvs.len == 0)
+ return null;
+ const i = self.getLongestPrefixIndex(str) orelse return null;
+ const kvs = self.kvs.*;
+ return .{
+ .key = kvs.keys[i],
+ .value = kvs.values[i],
+ };
+ }
+
+ pub fn getLongestPrefixIndex(self: Self, str: []const u8) ?usize {
+ if (self.kvs.len == 0)
+ return null;
+
+ if (str.len < self.min_len)
+ return null;
+
+ var len = @min(self.max_len, str.len);
+ while (len >= self.min_len) : (len -= 1) {
+ if (self.getIndex(str[0..len])) |i|
+ return i;
+ }
+ return null;
+ }
+
+ pub fn keys(self: Self) []const []const u8 {
+ const kvs = self.kvs.*;
+ return kvs.keys[0..kvs.len];
+ }
+
+ pub fn values(self: Self) []const V {
+ const kvs = self.kvs.*;
+ return kvs.values[0..kvs.len];
+ }
+ };
+}
+
+const TestEnum = enum { A, B, C, D, E };
+const TestMap = StaticStringMap(TestEnum);
+const TestKV = struct { []const u8, TestEnum };
+const TestMapVoid = StaticStringMap(void);
+const TestKVVoid = struct { []const u8 };
+const TestMapWithEql = StaticStringMapWithEql(TestEnum, eqlAsciiIgnoreCase);
+const testing = std.testing;
+const test_alloc = testing.allocator;
+
+test "list literal of list literals" {
+ const slice = [_]TestKV{
+ .{ "these", .D },
+ .{ "have", .A },
+ .{ "nothing", .B },
+ .{ "incommon", .C },
+ .{ "samelen", .E },
+ };
+ const map = TestMap.initComptime(slice);
+ try testMap(map);
+ // Default comparison is case sensitive
+ try testing.expect(null == map.get("NOTHING"));
+
+ // runtime init(), deinit()
+ const map_rt = try TestMap.init(slice, test_alloc);
+ defer map_rt.deinit(test_alloc);
+ try testMap(map_rt);
+ // Default comparison is case sensitive
+ try testing.expect(null == map_rt.get("NOTHING"));
+}
+
+test "array of structs" {
+ const slice = [_]TestKV{
+ .{ "these", .D },
+ .{ "have", .A },
+ .{ "nothing", .B },
+ .{ "incommon", .C },
+ .{ "samelen", .E },
+ };
+
+ try testMap(TestMap.initComptime(slice));
+}
+
+test "slice of structs" {
+ const slice = [_]TestKV{
+ .{ "these", .D },
+ .{ "have", .A },
+ .{ "nothing", .B },
+ .{ "incommon", .C },
+ .{ "samelen", .E },
+ };
+
+ try testMap(TestMap.initComptime(slice));
+}
+
+fn testMap(map: anytype) !void {
+ try testing.expectEqual(TestEnum.A, map.get("have").?);
+ try testing.expectEqual(TestEnum.B, map.get("nothing").?);
+ try testing.expect(null == map.get("missing"));
+ try testing.expectEqual(TestEnum.D, map.get("these").?);
+ try testing.expectEqual(TestEnum.E, map.get("samelen").?);
+
+ try testing.expect(!map.has("missing"));
+ try testing.expect(map.has("these"));
+
+ try testing.expect(null == map.get(""));
+ try testing.expect(null == map.get("averylongstringthathasnomatches"));
+}
+
+test "void value type, slice of structs" {
+ const slice = [_]TestKVVoid{
+ .{"these"},
+ .{"have"},
+ .{"nothing"},
+ .{"incommon"},
+ .{"samelen"},
+ };
+ const map = TestMapVoid.initComptime(slice);
+ try testSet(map);
+ // Default comparison is case sensitive
+ try testing.expect(null == map.get("NOTHING"));
+}
+
+test "void value type, list literal of list literals" {
+ const slice = [_]TestKVVoid{
+ .{"these"},
+ .{"have"},
+ .{"nothing"},
+ .{"incommon"},
+ .{"samelen"},
+ };
+
+ try testSet(TestMapVoid.initComptime(slice));
+}
+
+fn testSet(map: TestMapVoid) !void {
+ try testing.expectEqual({}, map.get("have").?);
+ try testing.expectEqual({}, map.get("nothing").?);
+ try testing.expect(null == map.get("missing"));
+ try testing.expectEqual({}, map.get("these").?);
+ try testing.expectEqual({}, map.get("samelen").?);
+
+ try testing.expect(!map.has("missing"));
+ try testing.expect(map.has("these"));
+
+ try testing.expect(null == map.get(""));
+ try testing.expect(null == map.get("averylongstringthathasnomatches"));
+}
+
+fn testStaticStringMapWithEql(map: TestMapWithEql) !void {
+ try testMap(map);
+ try testing.expectEqual(TestEnum.A, map.get("HAVE").?);
+ try testing.expectEqual(TestEnum.E, map.get("SameLen").?);
+ try testing.expect(null == map.get("SameLength"));
+ try testing.expect(map.has("ThESe"));
+}
+
+test "StaticStringMapWithEql" {
+ const slice = [_]TestKV{
+ .{ "these", .D },
+ .{ "have", .A },
+ .{ "nothing", .B },
+ .{ "incommon", .C },
+ .{ "samelen", .E },
+ };
+
+ try testStaticStringMapWithEql(TestMapWithEql.initComptime(slice));
+}
+
+test "empty" {
+ const m1 = StaticStringMap(usize).initComptime(.{});
+ try testing.expect(null == m1.get("anything"));
+
+ const m2 = StaticStringMapWithEql(usize, eqlAsciiIgnoreCase).initComptime(.{});
+ try testing.expect(null == m2.get("anything"));
+
+ const m3 = try StaticStringMap(usize).init(.{}, test_alloc);
+ try testing.expect(null == m3.get("anything"));
+
+ const m4 = try StaticStringMapWithEql(usize, eqlAsciiIgnoreCase).init(.{}, test_alloc);
+ try testing.expect(null == m4.get("anything"));
+}
+
+test "redundant entries" {
+ const slice = [_]TestKV{
+ .{ "redundant", .D },
+ .{ "theNeedle", .A },
+ .{ "redundant", .B },
+ .{ "re" ++ "dundant", .C },
+ .{ "redun" ++ "dant", .E },
+ };
+ const map = TestMap.initComptime(slice);
+
+ // No promises about which one you get:
+ try testing.expect(null != map.get("redundant"));
+
+ // Default map is not case sensitive:
+ try testing.expect(null == map.get("REDUNDANT"));
+
+ try testing.expectEqual(TestEnum.A, map.get("theNeedle").?);
+}
+
+test "redundant insensitive" {
+ const slice = [_]TestKV{
+ .{ "redundant", .D },
+ .{ "theNeedle", .A },
+ .{ "redundanT", .B },
+ .{ "RE" ++ "dundant", .C },
+ .{ "redun" ++ "DANT", .E },
+ };
+
+ const map = TestMapWithEql.initComptime(slice);
+
+ // No promises about which result you'll get ...
+ try testing.expect(null != map.get("REDUNDANT"));
+ try testing.expect(null != map.get("ReDuNdAnT"));
+ try testing.expectEqual(TestEnum.A, map.get("theNeedle").?);
+}
+
+test "comptime-only value" {
+ const map = StaticStringMap(type).initComptime(.{
+ .{ "a", struct {
+ pub const foo = 1;
+ } },
+ .{ "b", struct {
+ pub const foo = 2;
+ } },
+ .{ "c", struct {
+ pub const foo = 3;
+ } },
+ });
+
+ try testing.expect(map.get("a").?.foo == 1);
+ try testing.expect(map.get("b").?.foo == 2);
+ try testing.expect(map.get("c").?.foo == 3);
+ try testing.expect(map.get("d") == null);
+}
+
+test "getLongestPrefix" {
+ const slice = [_]TestKV{
+ .{ "a", .A },
+ .{ "aa", .B },
+ .{ "aaa", .C },
+ .{ "aaaa", .D },
+ };
+
+ const map = TestMap.initComptime(slice);
+
+ try testing.expectEqual(null, map.getLongestPrefix(""));
+ try testing.expectEqual(null, map.getLongestPrefix("bar"));
+ try testing.expectEqualStrings("aaaa", map.getLongestPrefix("aaaabar").?.key);
+ try testing.expectEqualStrings("aaa", map.getLongestPrefix("aaabar").?.key);
+}
+
+test "getLongestPrefix2" {
+ const slice = [_]struct { []const u8, u8 }{
+ .{ "one", 1 },
+ .{ "two", 2 },
+ .{ "three", 3 },
+ .{ "four", 4 },
+ .{ "five", 5 },
+ .{ "six", 6 },
+ .{ "seven", 7 },
+ .{ "eight", 8 },
+ .{ "nine", 9 },
+ };
+ const map = StaticStringMap(u8).initComptime(slice);
+
+ try testing.expectEqual(1, map.get("one"));
+ try testing.expectEqual(null, map.get("o"));
+ try testing.expectEqual(null, map.get("onexxx"));
+ try testing.expectEqual(9, map.get("nine"));
+ try testing.expectEqual(null, map.get("n"));
+ try testing.expectEqual(null, map.get("ninexxx"));
+ try testing.expectEqual(null, map.get("xxx"));
+
+ try testing.expectEqual(1, map.getLongestPrefix("one").?.value);
+ try testing.expectEqual(1, map.getLongestPrefix("onexxx").?.value);
+ try testing.expectEqual(null, map.getLongestPrefix("o"));
+ try testing.expectEqual(null, map.getLongestPrefix("on"));
+ try testing.expectEqual(9, map.getLongestPrefix("nine").?.value);
+ try testing.expectEqual(9, map.getLongestPrefix("ninexxx").?.value);
+ try testing.expectEqual(null, map.getLongestPrefix("n"));
+ try testing.expectEqual(null, map.getLongestPrefix("xxx"));
+}
+
+test "long kvs_list doesn't exceed @setEvalBranchQuota" {
+ _ = TestMapVoid.initComptime([1]TestKVVoid{.{"x"}} ** 1_000);
+}
lib/std/std.zig
@@ -16,8 +16,8 @@ pub const BufMap = @import("buf_map.zig").BufMap;
pub const BufSet = @import("buf_set.zig").BufSet;
/// Deprecated: use `process.Child`.
pub const ChildProcess = @import("child_process.zig").ChildProcess;
-pub const ComptimeStringMap = comptime_string_map.ComptimeStringMap;
-pub const ComptimeStringMapWithEql = comptime_string_map.ComptimeStringMapWithEql;
+pub const StaticStringMap = static_string_map.StaticStringMap;
+pub const StaticStringMapWithEql = static_string_map.StaticStringMapWithEql;
pub const DoublyLinkedList = @import("linked_list.zig").DoublyLinkedList;
pub const DynLib = @import("dynamic_library.zig").DynLib;
pub const DynamicBitSet = bit_set.DynamicBitSet;
@@ -62,7 +62,7 @@ pub const builtin = @import("builtin.zig");
pub const c = @import("c.zig");
pub const coff = @import("coff.zig");
pub const compress = @import("compress.zig");
-pub const comptime_string_map = @import("comptime_string_map.zig");
+pub const static_string_map = @import("static_string_map.zig");
pub const crypto = @import("crypto.zig");
pub const debug = @import("debug.zig");
pub const dwarf = @import("dwarf.zig");
src/codegen/c.zig
@@ -116,7 +116,7 @@ const ValueRenderLocation = enum {
const BuiltinInfo = enum { none, bits };
-const reserved_idents = std.ComptimeStringMap(void, .{
+const reserved_idents = std.StaticStringMap(void).initComptime(.{
// C language
.{ "alignas", {
@setEvalBranchQuota(4000);
src/link/Wasm/types.zig
@@ -244,7 +244,7 @@ pub const Feature = struct {
}
};
-pub const known_features = std.ComptimeStringMap(Feature.Tag, .{
+pub const known_features = std.StaticStringMap(Feature.Tag).initComptime(.{
.{ "atomics", .atomics },
.{ "bulk-memory", .bulk_memory },
.{ "exception-handling", .exception_handling },
src/Compilation.zig
@@ -265,7 +265,7 @@ pub const CRTFile = struct {
/// Supported languages for "zig clang -x <lang>".
/// Loosely based on llvm-project/clang/include/clang/Driver/Types.def
-pub const LangToExt = std.ComptimeStringMap(FileExt, .{
+pub const LangToExt = std.StaticStringMap(FileExt).initComptime(.{
.{ "c", .c },
.{ "c-header", .h },
.{ "c++", .cpp },
src/translate_c.zig
@@ -671,7 +671,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
return addTopLevelDecl(c, var_name, node);
}
-const builtin_typedef_map = std.ComptimeStringMap([]const u8, .{
+const builtin_typedef_map = std.StaticStringMap([]const u8).initComptime(.{
.{ "uint8_t", "u8" },
.{ "int8_t", "i8" },
.{ "uint16_t", "u16" },
test/src/Cases.zig
@@ -993,7 +993,7 @@ const TestManifest = struct {
config_map: std.StringHashMap([]const u8),
trailing_bytes: []const u8 = "",
- const valid_keys = std.ComptimeStringMap(void, .{
+ const valid_keys = std.StaticStringMap(void).initComptime(.{
.{ "is_test", {} },
.{ "output_mode", {} },
.{ "target", {} },
tools/gen_spirv_spec.zig
@@ -45,7 +45,7 @@ const OperandKindMap = std.ArrayHashMap(StringPair, OperandKind, StringPairConte
/// Khronos made it so that these names are not defined explicitly, so
/// we need to hardcode it (like they did).
/// See https://github.com/KhronosGroup/SPIRV-Registry/
-const set_names = std.ComptimeStringMap([]const u8, .{
+const set_names = std.StaticStringMap([]const u8).initComptime(.{
.{ "opencl.std.100", "OpenCL.std" },
.{ "glsl.std.450", "GLSL.std.450" },
.{ "opencl.debuginfo.100", "OpenCL.DebugInfo.100" },
tools/generate_linux_syscalls.zig
@@ -9,7 +9,7 @@ const fmt = std.fmt;
const zig = std.zig;
const fs = std.fs;
-const stdlib_renames = std.ComptimeStringMap([]const u8, .{
+const stdlib_renames = std.StaticStringMap([]const u8).initComptime(.{
// Most 64-bit archs.
.{ "newfstatat", "fstatat64" },
// POWER.
CMakeLists.txt
@@ -222,7 +222,7 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/lib/std/c/linux.zig"
"${CMAKE_SOURCE_DIR}/lib/std/child_process.zig"
"${CMAKE_SOURCE_DIR}/lib/std/coff.zig"
- "${CMAKE_SOURCE_DIR}/lib/std/comptime_string_map.zig"
+ "${CMAKE_SOURCE_DIR}/lib/std/static_string_map.zig"
"${CMAKE_SOURCE_DIR}/lib/std/crypto.zig"
"${CMAKE_SOURCE_DIR}/lib/std/crypto/blake3.zig"
"${CMAKE_SOURCE_DIR}/lib/std/crypto/siphash.zig"