| author | |
| committer | |
| log | c3a862522bbb59ee23a53e0562c402283db59b9c |
| tree | b14399fc672d911c11f6e9f14fb911f818b67d67 |
| parent | 0606af509f9a7f5e6bc458940aa9529d73232fc4 |
And deprecate all the API names except for:
* `std.array_hash_map.Auto`
* `std.array_hash_map.String`
* `std.array_hash_map.Custom`26 files changed, 271 insertions(+), 725 deletions(-)
lib/std/Build.zig+12-12| ... | @@ -86,10 +86,10 @@ libc_runtimes_dir: ?[]const u8 = null, | ... | @@ -86,10 +86,10 @@ libc_runtimes_dir: ?[]const u8 = null, |
| 86 | 86 | ||
| 87 | dep_prefix: []const u8 = "", | 87 | dep_prefix: []const u8 = "", |
| 88 | 88 | ||
| 89 | modules: std.StringArrayHashMap(*Module), | 89 | modules: std.array_hash_map.String(*Module), |
| 90 | 90 | ||
| 91 | named_writefiles: std.StringArrayHashMap(*Step.WriteFile), | 91 | named_writefiles: std.array_hash_map.String(*Step.WriteFile), |
| 92 | named_lazy_paths: std.StringArrayHashMap(LazyPath), | 92 | named_lazy_paths: std.array_hash_map.String(LazyPath), |
| 93 | /// The hash of this instance's package. `""` means that this is the root package. | 93 | /// The hash of this instance's package. `""` means that this is the root package. |
| 94 | pkg_hash: []const u8, | 94 | pkg_hash: []const u8, |
| 95 | /// A mapping from dependency names to package hashes. | 95 | /// A mapping from dependency names to package hashes. |
| ... | @@ -312,9 +312,9 @@ pub fn create( | ... | @@ -312,9 +312,9 @@ pub fn create( |
| 312 | }, | 312 | }, |
| 313 | .install_path = undefined, | 313 | .install_path = undefined, |
| 314 | .args = null, | 314 | .args = null, |
| 315 | .modules = .init(arena), | 315 | .modules = .empty, |
| 316 | .named_writefiles = .init(arena), | 316 | .named_writefiles = .empty, |
| 317 | .named_lazy_paths = .init(arena), | 317 | .named_lazy_paths = .empty, |
| 318 | .pkg_hash = "", | 318 | .pkg_hash = "", |
| 319 | .available_deps = available_deps, | 319 | .available_deps = available_deps, |
| 320 | .release_mode = .off, | 320 | .release_mode = .off, |
| ... | @@ -405,9 +405,9 @@ fn createChildOnly( | ... | @@ -405,9 +405,9 @@ fn createChildOnly( |
| 405 | .enable_wine = parent.enable_wine, | 405 | .enable_wine = parent.enable_wine, |
| 406 | .libc_runtimes_dir = parent.libc_runtimes_dir, | 406 | .libc_runtimes_dir = parent.libc_runtimes_dir, |
| 407 | .dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }), | 407 | .dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }), |
| 408 | .modules = .init(allocator), | 408 | .modules = .empty, |
| 409 | .named_writefiles = .init(allocator), | 409 | .named_writefiles = .empty, |
| 410 | .named_lazy_paths = .init(allocator), | 410 | .named_lazy_paths = .empty, |
| 411 | .pkg_hash = pkg_hash, | 411 | .pkg_hash = pkg_hash, |
| 412 | .available_deps = pkg_deps, | 412 | .available_deps = pkg_deps, |
| 413 | .release_mode = parent.release_mode, | 413 | .release_mode = parent.release_mode, |
| ... | @@ -908,7 +908,7 @@ pub const AssemblyOptions = struct { | ... | @@ -908,7 +908,7 @@ pub const AssemblyOptions = struct { |
| 908 | /// `createModule` can be used instead to create a private module. | 908 | /// `createModule` can be used instead to create a private module. |
| 909 | pub fn addModule(b: *Build, name: []const u8, options: Module.CreateOptions) *Module { | 909 | pub fn addModule(b: *Build, name: []const u8, options: Module.CreateOptions) *Module { |
| 910 | const module = Module.create(b, options); | 910 | const module = Module.create(b, options); |
| 911 | b.modules.put(b.dupe(name), module) catch @panic("OOM"); | 911 | b.modules.put(b.graph.arena, b.dupe(name), module) catch @panic("OOM"); |
| 912 | return module; | 912 | return module; |
| 913 | } | 913 | } |
| 914 | 914 | ||
| ... | @@ -1056,12 +1056,12 @@ pub fn addWriteFile(b: *Build, file_path: []const u8, data: []const u8) *Step.Wr | ... | @@ -1056,12 +1056,12 @@ pub fn addWriteFile(b: *Build, file_path: []const u8, data: []const u8) *Step.Wr |
| 1056 | 1056 | ||
| 1057 | pub fn addNamedWriteFiles(b: *Build, name: []const u8) *Step.WriteFile { | 1057 | pub fn addNamedWriteFiles(b: *Build, name: []const u8) *Step.WriteFile { |
| 1058 | const wf = Step.WriteFile.create(b); | 1058 | const wf = Step.WriteFile.create(b); |
| 1059 | b.named_writefiles.put(b.dupe(name), wf) catch @panic("OOM"); | 1059 | b.named_writefiles.put(b.graph.arena, b.dupe(name), wf) catch @panic("OOM"); |
| 1060 | return wf; | 1060 | return wf; |
| 1061 | } | 1061 | } |
| 1062 | 1062 | ||
| 1063 | pub fn addNamedLazyPath(b: *Build, name: []const u8, lp: LazyPath) void { | 1063 | pub fn addNamedLazyPath(b: *Build, name: []const u8, lp: LazyPath) void { |
| 1064 | b.named_lazy_paths.put(b.dupe(name), lp.dupe(b)) catch @panic("OOM"); | 1064 | b.named_lazy_paths.put(b.graph.arena, b.dupe(name), lp.dupe(b)) catch @panic("OOM"); |
| 1065 | } | 1065 | } |
| 1066 | 1066 | ||
| 1067 | /// Creates a step for mutating files inside a temporary directory created lazily | 1067 | /// Creates a step for mutating files inside a temporary directory created lazily |
lib/std/Build/Step/CheckObject.zig+3-3| ... | @@ -1814,16 +1814,16 @@ const ElfDumper = struct { | ... | @@ -1814,16 +1814,16 @@ const ElfDumper = struct { |
| 1814 | files.putAssumeCapacityNoClobber(object.off - @sizeOf(elf.ar_hdr), object.name); | 1814 | files.putAssumeCapacityNoClobber(object.off - @sizeOf(elf.ar_hdr), object.name); |
| 1815 | } | 1815 | } |
| 1816 | 1816 | ||
| 1817 | var symbols = std.AutoArrayHashMap(usize, std.array_list.Managed([]const u8)).init(ctx.gpa); | 1817 | var symbols: std.array_hash_map.Auto(usize, std.array_list.Managed([]const u8)) = .empty; |
| 1818 | defer { | 1818 | defer { |
| 1819 | for (symbols.values()) |*value| { | 1819 | for (symbols.values()) |*value| { |
| 1820 | value.deinit(); | 1820 | value.deinit(); |
| 1821 | } | 1821 | } |
| 1822 | symbols.deinit(); | 1822 | symbols.deinit(ctx.gpa); |
| 1823 | } | 1823 | } |
| 1824 | 1824 | ||
| 1825 | for (ctx.symtab.items) |entry| { | 1825 | for (ctx.symtab.items) |entry| { |
| 1826 | const gop = try symbols.getOrPut(@intCast(entry.off)); | 1826 | const gop = try symbols.getOrPut(ctx.gpa, @intCast(entry.off)); |
| 1827 | if (!gop.found_existing) { | 1827 | if (!gop.found_existing) { |
| 1828 | gop.value_ptr.* = std.array_list.Managed([]const u8).init(ctx.gpa); | 1828 | gop.value_ptr.* = std.array_list.Managed([]const u8).init(ctx.gpa); |
| 1829 | } | 1829 | } |
lib/std/Build/Step/ConfigHeader.zig+34-32| ... | @@ -38,7 +38,7 @@ pub const Value = union(enum) { | ... | @@ -38,7 +38,7 @@ pub const Value = union(enum) { |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | step: Step, | 40 | step: Step, |
| 41 | values: std.StringArrayHashMap(Value), | 41 | values: std.array_hash_map.String(Value), |
| 42 | /// This directory contains the generated file under the name `include_path`. | 42 | /// This directory contains the generated file under the name `include_path`. |
| 43 | generated_dir: std.Build.GeneratedFile, | 43 | generated_dir: std.Build.GeneratedFile, |
| 44 | 44 | ||
| ... | @@ -95,7 +95,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader { | ... | @@ -95,7 +95,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader { |
| 95 | .first_ret_addr = options.first_ret_addr orelse @returnAddress(), | 95 | .first_ret_addr = options.first_ret_addr orelse @returnAddress(), |
| 96 | }), | 96 | }), |
| 97 | .style = options.style, | 97 | .style = options.style, |
| 98 | .values = .init(owner.allocator), | 98 | .values = .empty, |
| 99 | 99 | ||
| 100 | .max_bytes = options.max_bytes, | 100 | .max_bytes = options.max_bytes, |
| 101 | .include_path = include_path, | 101 | .include_path = include_path, |
| ... | @@ -110,7 +110,8 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader { | ... | @@ -110,7 +110,8 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader { |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | pub fn addIdent(config_header: *ConfigHeader, name: []const u8, value: []const u8) void { | 112 | pub fn addIdent(config_header: *ConfigHeader, name: []const u8, value: []const u8) void { |
| 113 | config_header.values.put(name, .{ .ident = value }) catch @panic("OOM"); | 113 | const arena = config_header.step.owner.allocator; |
| 114 | config_header.values.put(arena, name, .{ .ident = value }) catch @panic("OOM"); | ||
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | pub fn addValue(config_header: *ConfigHeader, name: []const u8, comptime T: type, value: T) void { | 117 | pub fn addValue(config_header: *ConfigHeader, name: []const u8, comptime T: type, value: T) void { |
| ... | @@ -131,43 +132,44 @@ pub fn getOutputFile(ch: *ConfigHeader) std.Build.LazyPath { | ... | @@ -131,43 +132,44 @@ pub fn getOutputFile(ch: *ConfigHeader) std.Build.LazyPath { |
| 131 | } | 132 | } |
| 132 | 133 | ||
| 133 | fn addValueInner(config_header: *ConfigHeader, name: []const u8, comptime T: type, value: T) !void { | 134 | fn addValueInner(config_header: *ConfigHeader, name: []const u8, comptime T: type, value: T) !void { |
| 135 | const arena = config_header.step.owner.allocator; | ||
| 134 | switch (@typeInfo(T)) { | 136 | switch (@typeInfo(T)) { |
| 135 | .null => { | 137 | .null => { |
| 136 | try config_header.values.put(name, .undef); | 138 | try config_header.values.put(arena, name, .undef); |
| 137 | }, | 139 | }, |
| 138 | .void => { | 140 | .void => { |
| 139 | try config_header.values.put(name, .defined); | 141 | try config_header.values.put(arena, name, .defined); |
| 140 | }, | 142 | }, |
| 141 | .bool => { | 143 | .bool => { |
| 142 | try config_header.values.put(name, .{ .boolean = value }); | 144 | try config_header.values.put(arena, name, .{ .boolean = value }); |
| 143 | }, | 145 | }, |
| 144 | .int => { | 146 | .int => { |
| 145 | try config_header.values.put(name, .{ .int = value }); | 147 | try config_header.values.put(arena, name, .{ .int = value }); |
| 146 | }, | 148 | }, |
| 147 | .comptime_int => { | 149 | .comptime_int => { |
| 148 | try config_header.values.put(name, .{ .int = value }); | 150 | try config_header.values.put(arena, name, .{ .int = value }); |
| 149 | }, | 151 | }, |
| 150 | .@"enum", .enum_literal => { | 152 | .@"enum", .enum_literal => { |
| 151 | try config_header.values.put(name, .{ .ident = @tagName(value) }); | 153 | try config_header.values.put(arena, name, .{ .ident = @tagName(value) }); |
| 152 | }, | 154 | }, |
| 153 | .optional => { | 155 | .optional => { |
| 154 | if (value) |x| { | 156 | if (value) |x| { |
| 155 | return addValueInner(config_header, name, @TypeOf(x), x); | 157 | return addValueInner(config_header, name, @TypeOf(x), x); |
| 156 | } else { | 158 | } else { |
| 157 | try config_header.values.put(name, .undef); | 159 | try config_header.values.put(arena, name, .undef); |
| 158 | } | 160 | } |
| 159 | }, | 161 | }, |
| 160 | .pointer => |ptr| { | 162 | .pointer => |ptr| { |
| 161 | switch (@typeInfo(ptr.child)) { | 163 | switch (@typeInfo(ptr.child)) { |
| 162 | .array => |array| { | 164 | .array => |array| { |
| 163 | if (ptr.size == .one and array.child == u8) { | 165 | if (ptr.size == .one and array.child == u8) { |
| 164 | try config_header.values.put(name, .{ .string = value }); | 166 | try config_header.values.put(arena, name, .{ .string = value }); |
| 165 | return; | 167 | return; |
| 166 | } | 168 | } |
| 167 | }, | 169 | }, |
| 168 | .int => { | 170 | .int => { |
| 169 | if (ptr.size == .slice and ptr.child == u8) { | 171 | if (ptr.size == .slice and ptr.child == u8) { |
| 170 | try config_header.values.put(name, .{ .string = value }); | 172 | try config_header.values.put(arena, name, .{ .string = value }); |
| 171 | return; | 173 | return; |
| 172 | } | 174 | } |
| 173 | }, | 175 | }, |
| ... | @@ -218,8 +220,8 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -218,8 +220,8 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 218 | }); | 220 | }); |
| 219 | }; | 221 | }; |
| 220 | switch (config_header.style) { | 222 | switch (config_header.style) { |
| 221 | .autoconf_undef => try render_autoconf_undef(step, contents, bw, config_header.values, src_path), | 223 | .autoconf_undef => try render_autoconf_undef(step, contents, bw, &config_header.values, src_path), |
| 222 | .autoconf_at => try render_autoconf_at(step, contents, &aw, config_header.values, src_path), | 224 | .autoconf_at => try render_autoconf_at(step, contents, &aw, &config_header.values, src_path), |
| 223 | else => unreachable, | 225 | else => unreachable, |
| 224 | } | 226 | } |
| 225 | }, | 227 | }, |
| ... | @@ -282,7 +284,7 @@ fn render_autoconf_undef( | ... | @@ -282,7 +284,7 @@ fn render_autoconf_undef( |
| 282 | step: *Step, | 284 | step: *Step, |
| 283 | contents: []const u8, | 285 | contents: []const u8, |
| 284 | bw: *Writer, | 286 | bw: *Writer, |
| 285 | values: std.StringArrayHashMap(Value), | 287 | values: *const std.array_hash_map.String(Value), |
| 286 | src_path: []const u8, | 288 | src_path: []const u8, |
| 287 | ) !void { | 289 | ) !void { |
| 288 | const build = step.owner; | 290 | const build = step.owner; |
| ... | @@ -334,7 +336,7 @@ fn render_autoconf_at( | ... | @@ -334,7 +336,7 @@ fn render_autoconf_at( |
| 334 | step: *Step, | 336 | step: *Step, |
| 335 | contents: []const u8, | 337 | contents: []const u8, |
| 336 | aw: *Writer.Allocating, | 338 | aw: *Writer.Allocating, |
| 337 | values: std.StringArrayHashMap(Value), | 339 | values: *const std.array_hash_map.String(Value), |
| 338 | src_path: []const u8, | 340 | src_path: []const u8, |
| 339 | ) !void { | 341 | ) !void { |
| 340 | const build = step.owner; | 342 | const build = step.owner; |
| ... | @@ -373,7 +375,7 @@ fn render_autoconf_at( | ... | @@ -373,7 +375,7 @@ fn render_autoconf_at( |
| 373 | if (!last_line) try bw.writeByte('\n'); | 375 | if (!last_line) try bw.writeByte('\n'); |
| 374 | } | 376 | } |
| 375 | 377 | ||
| 376 | for (values.unmanaged.entries.slice().items(.key), used) |name, u| { | 378 | for (values.entries.slice().items(.key), used) |name, u| { |
| 377 | if (!u) { | 379 | if (!u) { |
| 378 | try step.addError("{s}: error: config header value unused: '{s}'", .{ src_path, name }); | 380 | try step.addError("{s}: error: config header value unused: '{s}'", .{ src_path, name }); |
| 379 | any_errors = true; | 381 | any_errors = true; |
| ... | @@ -387,14 +389,14 @@ fn render_cmake( | ... | @@ -387,14 +389,14 @@ fn render_cmake( |
| 387 | step: *Step, | 389 | step: *Step, |
| 388 | contents: []const u8, | 390 | contents: []const u8, |
| 389 | bw: *Writer, | 391 | bw: *Writer, |
| 390 | values: std.StringArrayHashMap(Value), | 392 | values: std.array_hash_map.String(Value), |
| 391 | src_path: []const u8, | 393 | src_path: []const u8, |
| 392 | ) !void { | 394 | ) !void { |
| 393 | const build = step.owner; | 395 | const build = step.owner; |
| 394 | const allocator = build.allocator; | 396 | const allocator = build.allocator; |
| 395 | 397 | ||
| 396 | var values_copy = try values.clone(); | 398 | var values_copy = try values.clone(allocator); |
| 397 | defer values_copy.deinit(); | 399 | defer values_copy.deinit(allocator); |
| 398 | 400 | ||
| 399 | var any_errors = false; | 401 | var any_errors = false; |
| 400 | var line_index: u32 = 0; | 402 | var line_index: u32 = 0; |
| ... | @@ -523,7 +525,7 @@ fn render_cmake( | ... | @@ -523,7 +525,7 @@ fn render_cmake( |
| 523 | fn render_blank( | 525 | fn render_blank( |
| 524 | gpa: std.mem.Allocator, | 526 | gpa: std.mem.Allocator, |
| 525 | bw: *Writer, | 527 | bw: *Writer, |
| 526 | defines: std.StringArrayHashMap(Value), | 528 | defines: std.array_hash_map.String(Value), |
| 527 | include_path: []const u8, | 529 | include_path: []const u8, |
| 528 | include_guard_override: ?[]const u8, | 530 | include_guard_override: ?[]const u8, |
| 529 | ) !void { | 531 | ) !void { |
| ... | @@ -555,7 +557,7 @@ fn render_blank( | ... | @@ -555,7 +557,7 @@ fn render_blank( |
| 555 | , .{include_guard_name}); | 557 | , .{include_guard_name}); |
| 556 | } | 558 | } |
| 557 | 559 | ||
| 558 | fn render_nasm(bw: *Writer, defines: std.StringArrayHashMap(Value)) !void { | 560 | fn render_nasm(bw: *Writer, defines: std.array_hash_map.String(Value)) !void { |
| 559 | for (defines.keys(), defines.values()) |name, value| try renderValueNasm(bw, name, value); | 561 | for (defines.keys(), defines.values()) |name, value| try renderValueNasm(bw, name, value); |
| 560 | } | 562 | } |
| 561 | 563 | ||
| ... | @@ -586,7 +588,7 @@ fn renderValueNasm(bw: *Writer, name: []const u8, value: Value) !void { | ... | @@ -586,7 +588,7 @@ fn renderValueNasm(bw: *Writer, name: []const u8, value: Value) !void { |
| 586 | fn expand_variables_autoconf_at( | 588 | fn expand_variables_autoconf_at( |
| 587 | bw: *Writer, | 589 | bw: *Writer, |
| 588 | contents: []const u8, | 590 | contents: []const u8, |
| 589 | values: std.StringArrayHashMap(Value), | 591 | values: *const std.array_hash_map.String(Value), |
| 590 | used: []bool, | 592 | used: []bool, |
| 591 | ) !void { | 593 | ) !void { |
| 592 | const valid_varname_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; | 594 | const valid_varname_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; |
| ... | @@ -612,7 +614,7 @@ fn expand_variables_autoconf_at( | ... | @@ -612,7 +614,7 @@ fn expand_variables_autoconf_at( |
| 612 | try bw.writeAll(key); | 614 | try bw.writeAll(key); |
| 613 | return error.MissingValue; | 615 | return error.MissingValue; |
| 614 | }; | 616 | }; |
| 615 | const value = values.unmanaged.entries.slice().items(.value)[index]; | 617 | const value = values.entries.slice().items(.value)[index]; |
| 616 | used[index] = true; | 618 | used[index] = true; |
| 617 | try bw.writeAll(contents[source_offset..curr]); | 619 | try bw.writeAll(contents[source_offset..curr]); |
| 618 | switch (value) { | 620 | switch (value) { |
| ... | @@ -633,7 +635,7 @@ fn expand_variables_autoconf_at( | ... | @@ -633,7 +635,7 @@ fn expand_variables_autoconf_at( |
| 633 | fn expand_variables_cmake( | 635 | fn expand_variables_cmake( |
| 634 | allocator: Allocator, | 636 | allocator: Allocator, |
| 635 | contents: []const u8, | 637 | contents: []const u8, |
| 636 | values: std.StringArrayHashMap(Value), | 638 | values: std.array_hash_map.String(Value), |
| 637 | ) ![]const u8 { | 639 | ) ![]const u8 { |
| 638 | var result: std.array_list.Managed(u8) = .init(allocator); | 640 | var result: std.array_list.Managed(u8) = .init(allocator); |
| 639 | errdefer result.deinit(); | 641 | errdefer result.deinit(); |
| ... | @@ -765,7 +767,7 @@ fn testReplaceVariablesAutoconfAt( | ... | @@ -765,7 +767,7 @@ fn testReplaceVariablesAutoconfAt( |
| 765 | allocator: Allocator, | 767 | allocator: Allocator, |
| 766 | contents: []const u8, | 768 | contents: []const u8, |
| 767 | expected: []const u8, | 769 | expected: []const u8, |
| 768 | values: std.StringArrayHashMap(Value), | 770 | values: std.array_hash_map.String(Value), |
| 769 | ) !void { | 771 | ) !void { |
| 770 | var aw: Writer.Allocating = .init(allocator); | 772 | var aw: Writer.Allocating = .init(allocator); |
| 771 | defer aw.deinit(); | 773 | defer aw.deinit(); |
| ... | @@ -784,7 +786,7 @@ fn testReplaceVariablesCMake( | ... | @@ -784,7 +786,7 @@ fn testReplaceVariablesCMake( |
| 784 | allocator: Allocator, | 786 | allocator: Allocator, |
| 785 | contents: []const u8, | 787 | contents: []const u8, |
| 786 | expected: []const u8, | 788 | expected: []const u8, |
| 787 | values: std.StringArrayHashMap(Value), | 789 | values: std.array_hash_map.String(Value), |
| 788 | ) !void { | 790 | ) !void { |
| 789 | const actual = try expand_variables_cmake(allocator, contents, values); | 791 | const actual = try expand_variables_cmake(allocator, contents, values); |
| 790 | defer allocator.free(actual); | 792 | defer allocator.free(actual); |
| ... | @@ -794,7 +796,7 @@ fn testReplaceVariablesCMake( | ... | @@ -794,7 +796,7 @@ fn testReplaceVariablesCMake( |
| 794 | 796 | ||
| 795 | test "expand_variables_autoconf_at simple cases" { | 797 | test "expand_variables_autoconf_at simple cases" { |
| 796 | const allocator = std.testing.allocator; | 798 | const allocator = std.testing.allocator; |
| 797 | var values: std.StringArrayHashMap(Value) = .init(allocator); | 799 | var values: std.array_hash_map.String(Value) = .init(allocator); |
| 798 | defer values.deinit(); | 800 | defer values.deinit(); |
| 799 | 801 | ||
| 800 | // empty strings are preserved | 802 | // empty strings are preserved |
| ... | @@ -890,7 +892,7 @@ test "expand_variables_autoconf_at simple cases" { | ... | @@ -890,7 +892,7 @@ test "expand_variables_autoconf_at simple cases" { |
| 890 | 892 | ||
| 891 | test "expand_variables_autoconf_at edge cases" { | 893 | test "expand_variables_autoconf_at edge cases" { |
| 892 | const allocator = std.testing.allocator; | 894 | const allocator = std.testing.allocator; |
| 893 | var values: std.StringArrayHashMap(Value) = .init(allocator); | 895 | var values: std.array_hash_map.String(Value) = .init(allocator); |
| 894 | defer values.deinit(); | 896 | defer values.deinit(); |
| 895 | 897 | ||
| 896 | // @-vars resolved only when they wrap valid characters, otherwise considered literals | 898 | // @-vars resolved only when they wrap valid characters, otherwise considered literals |
| ... | @@ -906,7 +908,7 @@ test "expand_variables_autoconf_at edge cases" { | ... | @@ -906,7 +908,7 @@ test "expand_variables_autoconf_at edge cases" { |
| 906 | 908 | ||
| 907 | test "expand_variables_cmake simple cases" { | 909 | test "expand_variables_cmake simple cases" { |
| 908 | const allocator = std.testing.allocator; | 910 | const allocator = std.testing.allocator; |
| 909 | var values: std.StringArrayHashMap(Value) = .init(allocator); | 911 | var values: std.array_hash_map.String(Value) = .init(allocator); |
| 910 | defer values.deinit(); | 912 | defer values.deinit(); |
| 911 | 913 | ||
| 912 | try values.putNoClobber("undef", .undef); | 914 | try values.putNoClobber("undef", .undef); |
| ... | @@ -994,7 +996,7 @@ test "expand_variables_cmake simple cases" { | ... | @@ -994,7 +996,7 @@ test "expand_variables_cmake simple cases" { |
| 994 | 996 | ||
| 995 | test "expand_variables_cmake edge cases" { | 997 | test "expand_variables_cmake edge cases" { |
| 996 | const allocator = std.testing.allocator; | 998 | const allocator = std.testing.allocator; |
| 997 | var values: std.StringArrayHashMap(Value) = .init(allocator); | 999 | var values: std.array_hash_map.String(Value) = .init(allocator); |
| 998 | defer values.deinit(); | 1000 | defer values.deinit(); |
| 999 | 1001 | ||
| 1000 | // special symbols | 1002 | // special symbols |
| ... | @@ -1055,7 +1057,7 @@ test "expand_variables_cmake edge cases" { | ... | @@ -1055,7 +1057,7 @@ test "expand_variables_cmake edge cases" { |
| 1055 | 1057 | ||
| 1056 | test "expand_variables_cmake escaped characters" { | 1058 | test "expand_variables_cmake escaped characters" { |
| 1057 | const allocator = std.testing.allocator; | 1059 | const allocator = std.testing.allocator; |
| 1058 | var values: std.StringArrayHashMap(Value) = .init(allocator); | 1060 | var values: std.array_hash_map.String(Value) = .init(allocator); |
| 1059 | defer values.deinit(); | 1061 | defer values.deinit(); |
| 1060 | 1062 | ||
| 1061 | try values.putNoClobber("string", Value{ .string = "text" }); | 1063 | try values.putNoClobber("string", Value{ .string = "text" }); |
lib/std/array_hash_map.zig+96-555| ... | @@ -12,27 +12,15 @@ const hash_map = @This(); | ... | @@ -12,27 +12,15 @@ const hash_map = @This(); |
| 12 | /// An `ArrayHashMap` with default hash and equal functions. | 12 | /// An `ArrayHashMap` with default hash and equal functions. |
| 13 | /// | 13 | /// |
| 14 | /// See `AutoContext` for a description of the hash and equal implementations. | 14 | /// See `AutoContext` for a description of the hash and equal implementations. |
| 15 | pub fn AutoArrayHashMap(comptime K: type, comptime V: type) type { | 15 | pub fn Auto(comptime K: type, comptime V: type) type { |
| 16 | return ArrayHashMap(K, V, AutoContext(K), !autoEqlIsCheap(K)); | 16 | return ArrayHashMap(K, V, AutoContext(K), !autoEqlIsCheap(K)); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | /// An `ArrayHashMapUnmanaged` with default hash and equal functions. | ||
| 20 | /// | ||
| 21 | /// See `AutoContext` for a description of the hash and equal implementations. | ||
| 22 | pub fn AutoArrayHashMapUnmanaged(comptime K: type, comptime V: type) type { | ||
| 23 | return ArrayHashMapUnmanaged(K, V, AutoContext(K), !autoEqlIsCheap(K)); | ||
| 24 | } | ||
| 25 | |||
| 26 | /// An `ArrayHashMap` with strings as keys. | 19 | /// An `ArrayHashMap` with strings as keys. |
| 27 | pub fn StringArrayHashMap(comptime V: type) type { | 20 | pub fn String(comptime V: type) type { |
| 28 | return ArrayHashMap([]const u8, V, StringContext, true); | 21 | return ArrayHashMap([]const u8, V, StringContext, true); |
| 29 | } | 22 | } |
| 30 | 23 | ||
| 31 | /// An `ArrayHashMapUnmanaged` with strings as keys. | ||
| 32 | pub fn StringArrayHashMapUnmanaged(comptime V: type) type { | ||
| 33 | return ArrayHashMapUnmanaged([]const u8, V, StringContext, true); | ||
| 34 | } | ||
| 35 | |||
| 36 | pub const StringContext = struct { | 24 | pub const StringContext = struct { |
| 37 | pub fn hash(self: @This(), s: []const u8) u32 { | 25 | pub fn hash(self: @This(), s: []const u8) u32 { |
| 38 | _ = self; | 26 | _ = self; |
| ... | @@ -53,454 +41,8 @@ pub fn hashString(s: []const u8) u32 { | ... | @@ -53,454 +41,8 @@ pub fn hashString(s: []const u8) u32 { |
| 53 | return @truncate(std.hash.Wyhash.hash(0, s)); | 41 | return @truncate(std.hash.Wyhash.hash(0, s)); |
| 54 | } | 42 | } |
| 55 | 43 | ||
| 56 | /// Deprecated in favor of `ArrayHashMapWithAllocator` (no code changes needed) | 44 | /// Deprecated; use `Custom`. |
| 57 | /// or `ArrayHashMapUnmanaged` (will need to update callsites to pass an | 45 | pub const ArrayHashMap = Custom; |
| 58 | /// allocator). After Zig 0.14.0 is released, `ArrayHashMapWithAllocator` will | ||
| 59 | /// be removed and `ArrayHashMapUnmanaged` will be a deprecated alias. After | ||
| 60 | /// Zig 0.15.0 is released, the deprecated alias `ArrayHashMapUnmanaged` will | ||
| 61 | /// be removed. | ||
| 62 | pub const ArrayHashMap = ArrayHashMapWithAllocator; | ||
| 63 | |||
| 64 | /// A hash table of keys and values, each stored sequentially. | ||
| 65 | /// | ||
| 66 | /// Insertion order is preserved. In general, this data structure supports the same | ||
| 67 | /// operations as `std.ArrayList`. | ||
| 68 | /// | ||
| 69 | /// Deletion operations: | ||
| 70 | /// * `swapRemove` - O(1) | ||
| 71 | /// * `orderedRemove` - O(N) | ||
| 72 | /// | ||
| 73 | /// Modifying the hash map while iterating is allowed, however, one must understand | ||
| 74 | /// the (well defined) behavior when mixing insertions and deletions with iteration. | ||
| 75 | /// | ||
| 76 | /// See `ArrayHashMapUnmanaged` for a variant of this data structure that accepts an | ||
| 77 | /// `Allocator` as a parameter when needed rather than storing it. | ||
| 78 | pub fn ArrayHashMapWithAllocator( | ||
| 79 | comptime K: type, | ||
| 80 | comptime V: type, | ||
| 81 | /// A namespace that provides these two functions: | ||
| 82 | /// * `pub fn hash(self, K) u32` | ||
| 83 | /// * `pub fn eql(self, K, K, usize) bool` | ||
| 84 | /// | ||
| 85 | /// The final `usize` in the `eql` function represents the index of the key | ||
| 86 | /// that's already inside the map. | ||
| 87 | comptime Context: type, | ||
| 88 | /// When `false`, this data structure is biased towards cheap `eql` | ||
| 89 | /// functions and avoids storing each key's hash in the table. Setting | ||
| 90 | /// `store_hash` to `true` incurs more memory cost but limits `eql` to | ||
| 91 | /// being called only once per insertion/deletion (provided there are no | ||
| 92 | /// hash collisions). | ||
| 93 | comptime store_hash: bool, | ||
| 94 | ) type { | ||
| 95 | return struct { | ||
| 96 | unmanaged: Unmanaged, | ||
| 97 | allocator: Allocator, | ||
| 98 | ctx: Context, | ||
| 99 | |||
| 100 | /// The ArrayHashMapUnmanaged type using the same settings as this managed map. | ||
| 101 | pub const Unmanaged = ArrayHashMapUnmanaged(K, V, Context, store_hash); | ||
| 102 | |||
| 103 | /// Pointers to a key and value in the backing store of this map. | ||
| 104 | /// Modifying the key is allowed only if it does not change the hash. | ||
| 105 | /// Modifying the value is allowed. | ||
| 106 | /// Entry pointers become invalid whenever this ArrayHashMap is modified, | ||
| 107 | /// unless `ensureTotalCapacity`/`ensureUnusedCapacity` was previously used. | ||
| 108 | pub const Entry = Unmanaged.Entry; | ||
| 109 | |||
| 110 | /// A KV pair which has been copied out of the backing store | ||
| 111 | pub const KV = Unmanaged.KV; | ||
| 112 | |||
| 113 | /// The Data type used for the MultiArrayList backing this map | ||
| 114 | pub const Data = Unmanaged.Data; | ||
| 115 | /// The MultiArrayList type backing this map | ||
| 116 | pub const DataList = Unmanaged.DataList; | ||
| 117 | |||
| 118 | /// The stored hash type, either u32 or void. | ||
| 119 | pub const Hash = Unmanaged.Hash; | ||
| 120 | |||
| 121 | /// getOrPut variants return this structure, with pointers | ||
| 122 | /// to the backing store and a flag to indicate whether an | ||
| 123 | /// existing entry was found. | ||
| 124 | /// Modifying the key is allowed only if it does not change the hash. | ||
| 125 | /// Modifying the value is allowed. | ||
| 126 | /// Entry pointers become invalid whenever this ArrayHashMap is modified, | ||
| 127 | /// unless `ensureTotalCapacity`/`ensureUnusedCapacity` was previously used. | ||
| 128 | pub const GetOrPutResult = Unmanaged.GetOrPutResult; | ||
| 129 | |||
| 130 | /// An Iterator over Entry pointers. | ||
| 131 | pub const Iterator = Unmanaged.Iterator; | ||
| 132 | |||
| 133 | const Self = @This(); | ||
| 134 | |||
| 135 | /// Create an ArrayHashMap instance which will use a specified allocator. | ||
| 136 | pub fn init(allocator: Allocator) Self { | ||
| 137 | if (@sizeOf(Context) != 0) | ||
| 138 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call initContext instead."); | ||
| 139 | return initContext(allocator, undefined); | ||
| 140 | } | ||
| 141 | pub fn initContext(allocator: Allocator, ctx: Context) Self { | ||
| 142 | return .{ | ||
| 143 | .unmanaged = .empty, | ||
| 144 | .allocator = allocator, | ||
| 145 | .ctx = ctx, | ||
| 146 | }; | ||
| 147 | } | ||
| 148 | |||
| 149 | /// Frees the backing allocation and leaves the map in an undefined state. | ||
| 150 | /// Note that this does not free keys or values. You must take care of that | ||
| 151 | /// before calling this function, if it is needed. | ||
| 152 | pub fn deinit(self: *Self) void { | ||
| 153 | self.unmanaged.deinit(self.allocator); | ||
| 154 | self.* = undefined; | ||
| 155 | } | ||
| 156 | |||
| 157 | /// Puts the hash map into a state where any method call that would | ||
| 158 | /// cause an existing key or value pointer to become invalidated will | ||
| 159 | /// instead trigger an assertion. | ||
| 160 | /// | ||
| 161 | /// An additional call to `lockPointers` in such state also triggers an | ||
| 162 | /// assertion. | ||
| 163 | /// | ||
| 164 | /// `unlockPointers` returns the hash map to the previous state. | ||
| 165 | pub fn lockPointers(self: *Self) void { | ||
| 166 | self.unmanaged.lockPointers(); | ||
| 167 | } | ||
| 168 | |||
| 169 | /// Undoes a call to `lockPointers`. | ||
| 170 | pub fn unlockPointers(self: *Self) void { | ||
| 171 | self.unmanaged.unlockPointers(); | ||
| 172 | } | ||
| 173 | |||
| 174 | /// Clears the map but retains the backing allocation for future use. | ||
| 175 | pub fn clearRetainingCapacity(self: *Self) void { | ||
| 176 | return self.unmanaged.clearRetainingCapacity(); | ||
| 177 | } | ||
| 178 | |||
| 179 | /// Clears the map and releases the backing allocation | ||
| 180 | pub fn clearAndFree(self: *Self) void { | ||
| 181 | return self.unmanaged.clearAndFree(self.allocator); | ||
| 182 | } | ||
| 183 | |||
| 184 | /// Returns the number of KV pairs stored in this map. | ||
| 185 | pub fn count(self: Self) usize { | ||
| 186 | return self.unmanaged.count(); | ||
| 187 | } | ||
| 188 | |||
| 189 | /// Returns the backing array of keys in this map. Modifying the map may | ||
| 190 | /// invalidate this array. Modifying this array in a way that changes | ||
| 191 | /// key hashes or key equality puts the map into an unusable state until | ||
| 192 | /// `reIndex` is called. | ||
| 193 | pub fn keys(self: Self) []K { | ||
| 194 | return self.unmanaged.keys(); | ||
| 195 | } | ||
| 196 | /// Returns the backing array of values in this map. Modifying the map | ||
| 197 | /// may invalidate this array. It is permitted to modify the values in | ||
| 198 | /// this array. | ||
| 199 | pub fn values(self: Self) []V { | ||
| 200 | return self.unmanaged.values(); | ||
| 201 | } | ||
| 202 | |||
| 203 | /// Returns an iterator over the pairs in this map. | ||
| 204 | /// Modifying the map may invalidate this iterator. | ||
| 205 | pub fn iterator(self: *const Self) Iterator { | ||
| 206 | return self.unmanaged.iterator(); | ||
| 207 | } | ||
| 208 | |||
| 209 | /// If key exists this function cannot fail. | ||
| 210 | /// If there is an existing item with `key`, then the result | ||
| 211 | /// `Entry` pointer points to it, and found_existing is true. | ||
| 212 | /// Otherwise, puts a new item with undefined value, and | ||
| 213 | /// the `Entry` pointer points to it. Caller should then initialize | ||
| 214 | /// the value (but not the key). | ||
| 215 | pub fn getOrPut(self: *Self, key: K) !GetOrPutResult { | ||
| 216 | return self.unmanaged.getOrPutContext(self.allocator, key, self.ctx); | ||
| 217 | } | ||
| 218 | pub fn getOrPutAdapted(self: *Self, key: anytype, ctx: anytype) !GetOrPutResult { | ||
| 219 | return self.unmanaged.getOrPutContextAdapted(self.allocator, key, ctx, self.ctx); | ||
| 220 | } | ||
| 221 | |||
| 222 | /// If there is an existing item with `key`, then the result | ||
| 223 | /// `Entry` pointer points to it, and found_existing is true. | ||
| 224 | /// Otherwise, puts a new item with undefined value, and | ||
| 225 | /// the `Entry` pointer points to it. Caller should then initialize | ||
| 226 | /// the value (but not the key). | ||
| 227 | /// If a new entry needs to be stored, this function asserts there | ||
| 228 | /// is enough capacity to store it. | ||
| 229 | pub fn getOrPutAssumeCapacity(self: *Self, key: K) GetOrPutResult { | ||
| 230 | return self.unmanaged.getOrPutAssumeCapacityContext(key, self.ctx); | ||
| 231 | } | ||
| 232 | pub fn getOrPutAssumeCapacityAdapted(self: *Self, key: anytype, ctx: anytype) GetOrPutResult { | ||
| 233 | return self.unmanaged.getOrPutAssumeCapacityAdapted(key, ctx); | ||
| 234 | } | ||
| 235 | pub fn getOrPutValue(self: *Self, key: K, value: V) !GetOrPutResult { | ||
| 236 | return self.unmanaged.getOrPutValueContext(self.allocator, key, value, self.ctx); | ||
| 237 | } | ||
| 238 | |||
| 239 | /// Increases capacity, guaranteeing that insertions up until the | ||
| 240 | /// `expected_count` will not cause an allocation, and therefore cannot fail. | ||
| 241 | pub fn ensureTotalCapacity(self: *Self, new_capacity: usize) !void { | ||
| 242 | return self.unmanaged.ensureTotalCapacityContext(self.allocator, new_capacity, self.ctx); | ||
| 243 | } | ||
| 244 | |||
| 245 | /// Increases capacity, guaranteeing that insertions up until | ||
| 246 | /// `additional_count` **more** items will not cause an allocation, and | ||
| 247 | /// therefore cannot fail. | ||
| 248 | pub fn ensureUnusedCapacity(self: *Self, additional_count: usize) !void { | ||
| 249 | return self.unmanaged.ensureUnusedCapacityContext(self.allocator, additional_count, self.ctx); | ||
| 250 | } | ||
| 251 | |||
| 252 | /// Returns the number of total elements which may be present before it is | ||
| 253 | /// no longer guaranteed that no allocations will be performed. | ||
| 254 | pub fn capacity(self: Self) usize { | ||
| 255 | return self.unmanaged.capacity(); | ||
| 256 | } | ||
| 257 | |||
| 258 | /// Clobbers any existing data. To detect if a put would clobber | ||
| 259 | /// existing data, see `getOrPut`. | ||
| 260 | pub fn put(self: *Self, key: K, value: V) !void { | ||
| 261 | return self.unmanaged.putContext(self.allocator, key, value, self.ctx); | ||
| 262 | } | ||
| 263 | |||
| 264 | /// Inserts a key-value pair into the hash map, asserting that no previous | ||
| 265 | /// entry with the same key is already present | ||
| 266 | pub fn putNoClobber(self: *Self, key: K, value: V) !void { | ||
| 267 | return self.unmanaged.putNoClobberContext(self.allocator, key, value, self.ctx); | ||
| 268 | } | ||
| 269 | |||
| 270 | /// Asserts there is enough capacity to store the new key-value pair. | ||
| 271 | /// Clobbers any existing data. To detect if a put would clobber | ||
| 272 | /// existing data, see `getOrPutAssumeCapacity`. | ||
| 273 | pub fn putAssumeCapacity(self: *Self, key: K, value: V) void { | ||
| 274 | return self.unmanaged.putAssumeCapacityContext(key, value, self.ctx); | ||
| 275 | } | ||
| 276 | |||
| 277 | /// Asserts there is enough capacity to store the new key-value pair. | ||
| 278 | /// Asserts that it does not clobber any existing data. | ||
| 279 | /// To detect if a put would clobber existing data, see `getOrPutAssumeCapacity`. | ||
| 280 | pub fn putAssumeCapacityNoClobber(self: *Self, key: K, value: V) void { | ||
| 281 | return self.unmanaged.putAssumeCapacityNoClobberContext(key, value, self.ctx); | ||
| 282 | } | ||
| 283 | |||
| 284 | /// Inserts a new `Entry` into the hash map, returning the previous one, if any. | ||
| 285 | pub fn fetchPut(self: *Self, key: K, value: V) !?KV { | ||
| 286 | return self.unmanaged.fetchPutContext(self.allocator, key, value, self.ctx); | ||
| 287 | } | ||
| 288 | |||
| 289 | /// Inserts a new `Entry` into the hash map, returning the previous one, if any. | ||
| 290 | /// If insertion happuns, asserts there is enough capacity without allocating. | ||
| 291 | pub fn fetchPutAssumeCapacity(self: *Self, key: K, value: V) ?KV { | ||
| 292 | return self.unmanaged.fetchPutAssumeCapacityContext(key, value, self.ctx); | ||
| 293 | } | ||
| 294 | |||
| 295 | /// Finds pointers to the key and value storage associated with a key. | ||
| 296 | pub fn getEntry(self: Self, key: K) ?Entry { | ||
| 297 | return self.unmanaged.getEntryContext(key, self.ctx); | ||
| 298 | } | ||
| 299 | pub fn getEntryAdapted(self: Self, key: anytype, ctx: anytype) ?Entry { | ||
| 300 | return self.unmanaged.getEntryAdapted(key, ctx); | ||
| 301 | } | ||
| 302 | |||
| 303 | /// Finds the index in the `entries` array where a key is stored | ||
| 304 | pub fn getIndex(self: Self, key: K) ?usize { | ||
| 305 | return self.unmanaged.getIndexContext(key, self.ctx); | ||
| 306 | } | ||
| 307 | pub fn getIndexAdapted(self: Self, key: anytype, ctx: anytype) ?usize { | ||
| 308 | return self.unmanaged.getIndexAdapted(key, ctx); | ||
| 309 | } | ||
| 310 | |||
| 311 | /// Find the value associated with a key | ||
| 312 | pub fn get(self: Self, key: K) ?V { | ||
| 313 | return self.unmanaged.getContext(key, self.ctx); | ||
| 314 | } | ||
| 315 | pub fn getAdapted(self: Self, key: anytype, ctx: anytype) ?V { | ||
| 316 | return self.unmanaged.getAdapted(key, ctx); | ||
| 317 | } | ||
| 318 | |||
| 319 | /// Find a pointer to the value associated with a key | ||
| 320 | pub fn getPtr(self: Self, key: K) ?*V { | ||
| 321 | return self.unmanaged.getPtrContext(key, self.ctx); | ||
| 322 | } | ||
| 323 | pub fn getPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*V { | ||
| 324 | return self.unmanaged.getPtrAdapted(key, ctx); | ||
| 325 | } | ||
| 326 | |||
| 327 | /// Find the actual key associated with an adapted key | ||
| 328 | pub fn getKey(self: Self, key: K) ?K { | ||
| 329 | return self.unmanaged.getKeyContext(key, self.ctx); | ||
| 330 | } | ||
| 331 | pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K { | ||
| 332 | return self.unmanaged.getKeyAdapted(key, ctx); | ||
| 333 | } | ||
| 334 | |||
| 335 | /// Find a pointer to the actual key associated with an adapted key | ||
| 336 | pub fn getKeyPtr(self: Self, key: K) ?*K { | ||
| 337 | return self.unmanaged.getKeyPtrContext(key, self.ctx); | ||
| 338 | } | ||
| 339 | pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K { | ||
| 340 | return self.unmanaged.getKeyPtrAdapted(key, ctx); | ||
| 341 | } | ||
| 342 | |||
| 343 | /// Check whether a key is stored in the map | ||
| 344 | pub fn contains(self: Self, key: K) bool { | ||
| 345 | return self.unmanaged.containsContext(key, self.ctx); | ||
| 346 | } | ||
| 347 | pub fn containsAdapted(self: Self, key: anytype, ctx: anytype) bool { | ||
| 348 | return self.unmanaged.containsAdapted(key, ctx); | ||
| 349 | } | ||
| 350 | |||
| 351 | /// If there is an `Entry` with a matching key, it is deleted from | ||
| 352 | /// the hash map, and then returned from this function. The entry is | ||
| 353 | /// removed from the underlying array by swapping it with the last | ||
| 354 | /// element. | ||
| 355 | pub fn fetchSwapRemove(self: *Self, key: K) ?KV { | ||
| 356 | return self.unmanaged.fetchSwapRemoveContext(key, self.ctx); | ||
| 357 | } | ||
| 358 | pub fn fetchSwapRemoveAdapted(self: *Self, key: anytype, ctx: anytype) ?KV { | ||
| 359 | return self.unmanaged.fetchSwapRemoveContextAdapted(key, ctx, self.ctx); | ||
| 360 | } | ||
| 361 | |||
| 362 | /// If there is an `Entry` with a matching key, it is deleted from | ||
| 363 | /// the hash map, and then returned from this function. The entry is | ||
| 364 | /// removed from the underlying array by shifting all elements forward | ||
| 365 | /// thereby maintaining the current ordering. | ||
| 366 | pub fn fetchOrderedRemove(self: *Self, key: K) ?KV { | ||
| 367 | return self.unmanaged.fetchOrderedRemoveContext(key, self.ctx); | ||
| 368 | } | ||
| 369 | pub fn fetchOrderedRemoveAdapted(self: *Self, key: anytype, ctx: anytype) ?KV { | ||
| 370 | return self.unmanaged.fetchOrderedRemoveContextAdapted(key, ctx, self.ctx); | ||
| 371 | } | ||
| 372 | |||
| 373 | /// If there is an `Entry` with a matching key, it is deleted from | ||
| 374 | /// the hash map. The entry is removed from the underlying array | ||
| 375 | /// by swapping it with the last element. Returns true if an entry | ||
| 376 | /// was removed, false otherwise. | ||
| 377 | pub fn swapRemove(self: *Self, key: K) bool { | ||
| 378 | return self.unmanaged.swapRemoveContext(key, self.ctx); | ||
| 379 | } | ||
| 380 | pub fn swapRemoveAdapted(self: *Self, key: anytype, ctx: anytype) bool { | ||
| 381 | return self.unmanaged.swapRemoveContextAdapted(key, ctx, self.ctx); | ||
| 382 | } | ||
| 383 | |||
| 384 | /// If there is an `Entry` with a matching key, it is deleted from | ||
| 385 | /// the hash map. The entry is removed from the underlying array | ||
| 386 | /// by shifting all elements forward, thereby maintaining the | ||
| 387 | /// current ordering. Returns true if an entry was removed, false otherwise. | ||
| 388 | pub fn orderedRemove(self: *Self, key: K) bool { | ||
| 389 | return self.unmanaged.orderedRemoveContext(key, self.ctx); | ||
| 390 | } | ||
| 391 | pub fn orderedRemoveAdapted(self: *Self, key: anytype, ctx: anytype) bool { | ||
| 392 | return self.unmanaged.orderedRemoveContextAdapted(key, ctx, self.ctx); | ||
| 393 | } | ||
| 394 | |||
| 395 | /// Deletes the item at the specified index in `entries` from | ||
| 396 | /// the hash map. The entry is removed from the underlying array | ||
| 397 | /// by swapping it with the last element. | ||
| 398 | pub fn swapRemoveAt(self: *Self, index: usize) void { | ||
| 399 | self.unmanaged.swapRemoveAtContext(index, self.ctx); | ||
| 400 | } | ||
| 401 | |||
| 402 | /// Deletes the item at the specified index in `entries` from | ||
| 403 | /// the hash map. The entry is removed from the underlying array | ||
| 404 | /// by shifting all elements forward, thereby maintaining the | ||
| 405 | /// current ordering. | ||
| 406 | pub fn orderedRemoveAt(self: *Self, index: usize) void { | ||
| 407 | self.unmanaged.orderedRemoveAtContext(index, self.ctx); | ||
| 408 | } | ||
| 409 | |||
| 410 | /// Create a copy of the hash map which can be modified separately. | ||
| 411 | /// The copy uses the same context and allocator as this instance. | ||
| 412 | pub fn clone(self: Self) !Self { | ||
| 413 | var other = try self.unmanaged.cloneContext(self.allocator, self.ctx); | ||
| 414 | return other.promoteContext(self.allocator, self.ctx); | ||
| 415 | } | ||
| 416 | /// Create a copy of the hash map which can be modified separately. | ||
| 417 | /// The copy uses the same context as this instance, but the specified | ||
| 418 | /// allocator. | ||
| 419 | pub fn cloneWithAllocator(self: Self, allocator: Allocator) !Self { | ||
| 420 | var other = try self.unmanaged.cloneContext(allocator, self.ctx); | ||
| 421 | return other.promoteContext(allocator, self.ctx); | ||
| 422 | } | ||
| 423 | /// Create a copy of the hash map which can be modified separately. | ||
| 424 | /// The copy uses the same allocator as this instance, but the | ||
| 425 | /// specified context. | ||
| 426 | pub fn cloneWithContext(self: Self, ctx: anytype) !ArrayHashMap(K, V, @TypeOf(ctx), store_hash) { | ||
| 427 | var other = try self.unmanaged.cloneContext(self.allocator, ctx); | ||
| 428 | return other.promoteContext(self.allocator, ctx); | ||
| 429 | } | ||
| 430 | /// Create a copy of the hash map which can be modified separately. | ||
| 431 | /// The copy uses the specified allocator and context. | ||
| 432 | pub fn cloneWithAllocatorAndContext(self: Self, allocator: Allocator, ctx: anytype) !ArrayHashMap(K, V, @TypeOf(ctx), store_hash) { | ||
| 433 | var other = try self.unmanaged.cloneContext(allocator, ctx); | ||
| 434 | return other.promoteContext(allocator, ctx); | ||
| 435 | } | ||
| 436 | |||
| 437 | /// Set the map to an empty state, making deinitialization a no-op, and | ||
| 438 | /// returning a copy of the original. | ||
| 439 | pub fn move(self: *Self) Self { | ||
| 440 | self.unmanaged.pointer_stability.assertUnlocked(); | ||
| 441 | const result = self.*; | ||
| 442 | self.unmanaged = .empty; | ||
| 443 | return result; | ||
| 444 | } | ||
| 445 | |||
| 446 | /// Recomputes stored hashes and rebuilds the key indexes. If the | ||
| 447 | /// underlying keys have been modified directly, call this method to | ||
| 448 | /// recompute the denormalized metadata necessary for the operation of | ||
| 449 | /// the methods of this map that lookup entries by key. | ||
| 450 | /// | ||
| 451 | /// One use case for this is directly calling `entries.resize()` to grow | ||
| 452 | /// the underlying storage, and then setting the `keys` and `values` | ||
| 453 | /// directly without going through the methods of this map. | ||
| 454 | /// | ||
| 455 | /// The time complexity of this operation is O(n). | ||
| 456 | pub fn reIndex(self: *Self) !void { | ||
| 457 | return self.unmanaged.reIndexContext(self.allocator, self.ctx); | ||
| 458 | } | ||
| 459 | |||
| 460 | /// Sorts the entries and then rebuilds the index. | ||
| 461 | /// `sort_ctx` must have this method: | ||
| 462 | /// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool` | ||
| 463 | /// Uses a stable sorting algorithm. | ||
| 464 | pub fn sort(self: *Self, sort_ctx: anytype) void { | ||
| 465 | return self.unmanaged.sortContext(sort_ctx, self.ctx); | ||
| 466 | } | ||
| 467 | |||
| 468 | /// Sorts the entries and then rebuilds the index. | ||
| 469 | /// `sort_ctx` must have this method: | ||
| 470 | /// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool` | ||
| 471 | /// Uses an unstable sorting algorithm. | ||
| 472 | pub fn sortUnstable(self: *Self, sort_ctx: anytype) void { | ||
| 473 | return self.unmanaged.sortUnstableContext(sort_ctx, self.ctx); | ||
| 474 | } | ||
| 475 | |||
| 476 | /// Shrinks the underlying `Entry` array to `new_len` elements and | ||
| 477 | /// discards any associated index entries. Keeps capacity the same. | ||
| 478 | /// | ||
| 479 | /// Asserts the discarded entries remain initialized and capable of | ||
| 480 | /// performing hash and equality checks. Any deinitialization of | ||
| 481 | /// discarded entries must take place *after* calling this function. | ||
| 482 | pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void { | ||
| 483 | return self.unmanaged.shrinkRetainingCapacityContext(new_len, self.ctx); | ||
| 484 | } | ||
| 485 | |||
| 486 | /// Shrinks the underlying `Entry` array to `new_len` elements and | ||
| 487 | /// discards any associated index entries. Reduces allocated capacity. | ||
| 488 | /// | ||
| 489 | /// Asserts the discarded entries remain initialized and capable of | ||
| 490 | /// performing hash and equality checks. It is a bug to call this | ||
| 491 | /// function if the discarded entries require deinitialization. For | ||
| 492 | /// that use case, `shrinkRetainingCapacity` can be used instead. | ||
| 493 | pub fn shrinkAndFree(self: *Self, new_len: usize) void { | ||
| 494 | return self.unmanaged.shrinkAndFreeContext(self.allocator, new_len, self.ctx); | ||
| 495 | } | ||
| 496 | |||
| 497 | /// Removes the last inserted `Entry` in the hash map and returns it if count is nonzero. | ||
| 498 | /// Otherwise returns null. | ||
| 499 | pub fn pop(self: *Self) ?KV { | ||
| 500 | return self.unmanaged.popContext(self.ctx); | ||
| 501 | } | ||
| 502 | }; | ||
| 503 | } | ||
| 504 | 46 | ||
| 505 | /// A hash table of keys and values, each stored sequentially. | 47 | /// A hash table of keys and values, each stored sequentially. |
| 506 | /// | 48 | /// |
| ... | @@ -522,11 +64,11 @@ pub fn ArrayHashMapWithAllocator( | ... | @@ -522,11 +64,11 @@ pub fn ArrayHashMapWithAllocator( |
| 522 | /// | 64 | /// |
| 523 | /// This type is designed to have low overhead for small numbers of entries. When | 65 | /// This type is designed to have low overhead for small numbers of entries. When |
| 524 | /// `store_hash` is `false` and the number of entries in the map is less than 9, | 66 | /// `store_hash` is `false` and the number of entries in the map is less than 9, |
| 525 | /// the overhead cost of using `ArrayHashMapUnmanaged` rather than `std.ArrayList` is | 67 | /// the overhead cost of using `ArrayHashMap` rather than `std.ArrayList` is |
| 526 | /// only a single pointer-sized integer. | 68 | /// only a single pointer-sized integer. |
| 527 | /// | 69 | /// |
| 528 | /// Default initialization of this struct is deprecated; use `.empty` instead. | 70 | /// Default initialization of this struct is deprecated; use `.empty` instead. |
| 529 | pub fn ArrayHashMapUnmanaged( | 71 | pub fn Custom( |
| 530 | comptime K: type, | 72 | comptime K: type, |
| 531 | comptime V: type, | 73 | comptime V: type, |
| 532 | /// A namespace that provides these two functions: | 74 | /// A namespace that provides these two functions: |
| ... | @@ -605,9 +147,6 @@ pub fn ArrayHashMapUnmanaged( | ... | @@ -605,9 +147,6 @@ pub fn ArrayHashMapUnmanaged( |
| 605 | index: usize, | 147 | index: usize, |
| 606 | }; | 148 | }; |
| 607 | 149 | ||
| 608 | /// The ArrayHashMap type using the same settings as this managed map. | ||
| 609 | pub const Managed = ArrayHashMap(K, V, Context, store_hash); | ||
| 610 | |||
| 611 | /// Some functions require a context only if hashes are not stored. | 150 | /// Some functions require a context only if hashes are not stored. |
| 612 | /// To keep the api simple, this type is only used internally. | 151 | /// To keep the api simple, this type is only used internally. |
| 613 | const ByIndexContext = if (store_hash) void else Context; | 152 | const ByIndexContext = if (store_hash) void else Context; |
| ... | @@ -626,21 +165,6 @@ pub fn ArrayHashMapUnmanaged( | ... | @@ -626,21 +165,6 @@ pub fn ArrayHashMapUnmanaged( |
| 626 | 165 | ||
| 627 | const Oom = Allocator.Error; | 166 | const Oom = Allocator.Error; |
| 628 | 167 | ||
| 629 | /// Convert from an unmanaged map to a managed map. After calling this, | ||
| 630 | /// the promoted map should no longer be used. | ||
| 631 | pub fn promote(self: Self, gpa: Allocator) Managed { | ||
| 632 | if (@sizeOf(Context) != 0) | ||
| 633 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call promoteContext instead."); | ||
| 634 | return self.promoteContext(gpa, undefined); | ||
| 635 | } | ||
| 636 | pub fn promoteContext(self: Self, gpa: Allocator, ctx: Context) Managed { | ||
| 637 | return .{ | ||
| 638 | .unmanaged = self, | ||
| 639 | .allocator = gpa, | ||
| 640 | .ctx = ctx, | ||
| 641 | }; | ||
| 642 | } | ||
| 643 | |||
| 644 | pub fn init(gpa: Allocator, key_list: []const K, value_list: []const V) Oom!Self { | 168 | pub fn init(gpa: Allocator, key_list: []const K, value_list: []const V) Oom!Self { |
| 645 | var self: Self = .{}; | 169 | var self: Self = .{}; |
| 646 | errdefer self.deinit(gpa); | 170 | errdefer self.deinit(gpa); |
| ... | @@ -2189,35 +1713,37 @@ const IndexHeader = struct { | ... | @@ -2189,35 +1713,37 @@ const IndexHeader = struct { |
| 2189 | }; | 1713 | }; |
| 2190 | 1714 | ||
| 2191 | test "basic hash map usage" { | 1715 | test "basic hash map usage" { |
| 2192 | var map = AutoArrayHashMap(i32, i32).init(std.testing.allocator); | 1716 | const gpa = testing.allocator; |
| 2193 | defer map.deinit(); | ||
| 2194 | 1717 | ||
| 2195 | try testing.expect((try map.fetchPut(1, 11)) == null); | 1718 | var map: Auto(i32, i32) = .empty; |
| 2196 | try testing.expect((try map.fetchPut(2, 22)) == null); | 1719 | defer map.deinit(gpa); |
| 2197 | try testing.expect((try map.fetchPut(3, 33)) == null); | 1720 | |
| 2198 | try testing.expect((try map.fetchPut(4, 44)) == null); | 1721 | try testing.expect((try map.fetchPut(gpa, 1, 11)) == null); |
| 1722 | try testing.expect((try map.fetchPut(gpa, 2, 22)) == null); | ||
| 1723 | try testing.expect((try map.fetchPut(gpa, 3, 33)) == null); | ||
| 1724 | try testing.expect((try map.fetchPut(gpa, 4, 44)) == null); | ||
| 2199 | 1725 | ||
| 2200 | try map.putNoClobber(5, 55); | 1726 | try map.putNoClobber(gpa, 5, 55); |
| 2201 | try testing.expect((try map.fetchPut(5, 66)).?.value == 55); | 1727 | try testing.expect((try map.fetchPut(gpa, 5, 66)).?.value == 55); |
| 2202 | try testing.expect((try map.fetchPut(5, 55)).?.value == 66); | 1728 | try testing.expect((try map.fetchPut(gpa, 5, 55)).?.value == 66); |
| 2203 | 1729 | ||
| 2204 | const gop1 = try map.getOrPut(5); | 1730 | const gop1 = try map.getOrPut(gpa, 5); |
| 2205 | try testing.expect(gop1.found_existing == true); | 1731 | try testing.expect(gop1.found_existing == true); |
| 2206 | try testing.expect(gop1.value_ptr.* == 55); | 1732 | try testing.expect(gop1.value_ptr.* == 55); |
| 2207 | try testing.expect(gop1.index == 4); | 1733 | try testing.expect(gop1.index == 4); |
| 2208 | gop1.value_ptr.* = 77; | 1734 | gop1.value_ptr.* = 77; |
| 2209 | try testing.expect(map.getEntry(5).?.value_ptr.* == 77); | 1735 | try testing.expect(map.getEntry(5).?.value_ptr.* == 77); |
| 2210 | 1736 | ||
| 2211 | const gop2 = try map.getOrPut(99); | 1737 | const gop2 = try map.getOrPut(gpa, 99); |
| 2212 | try testing.expect(gop2.found_existing == false); | 1738 | try testing.expect(gop2.found_existing == false); |
| 2213 | try testing.expect(gop2.index == 5); | 1739 | try testing.expect(gop2.index == 5); |
| 2214 | gop2.value_ptr.* = 42; | 1740 | gop2.value_ptr.* = 42; |
| 2215 | try testing.expect(map.getEntry(99).?.value_ptr.* == 42); | 1741 | try testing.expect(map.getEntry(99).?.value_ptr.* == 42); |
| 2216 | 1742 | ||
| 2217 | const gop3 = try map.getOrPutValue(5, 5); | 1743 | const gop3 = try map.getOrPutValue(gpa, 5, 5); |
| 2218 | try testing.expect(gop3.value_ptr.* == 77); | 1744 | try testing.expect(gop3.value_ptr.* == 77); |
| 2219 | 1745 | ||
| 2220 | const gop4 = try map.getOrPutValue(100, 41); | 1746 | const gop4 = try map.getOrPutValue(gpa, 100, 41); |
| 2221 | try testing.expect(gop4.value_ptr.* == 41); | 1747 | try testing.expect(gop4.value_ptr.* == 41); |
| 2222 | 1748 | ||
| 2223 | try testing.expect(map.contains(2)); | 1749 | try testing.expect(map.contains(2)); |
| ... | @@ -2234,7 +1760,7 @@ test "basic hash map usage" { | ... | @@ -2234,7 +1760,7 @@ test "basic hash map usage" { |
| 2234 | 1760 | ||
| 2235 | // Since we've used `swapRemove` above, the index of this entry should remain unchanged. | 1761 | // Since we've used `swapRemove` above, the index of this entry should remain unchanged. |
| 2236 | try testing.expect(map.getIndex(100).? == 1); | 1762 | try testing.expect(map.getIndex(100).? == 1); |
| 2237 | const gop5 = try map.getOrPut(5); | 1763 | const gop5 = try map.getOrPut(gpa, 5); |
| 2238 | try testing.expect(gop5.found_existing == true); | 1764 | try testing.expect(gop5.found_existing == true); |
| 2239 | try testing.expect(gop5.value_ptr.* == 77); | 1765 | try testing.expect(gop5.value_ptr.* == 77); |
| 2240 | try testing.expect(gop5.index == 4); | 1766 | try testing.expect(gop5.index == 4); |
| ... | @@ -2247,7 +1773,7 @@ test "basic hash map usage" { | ... | @@ -2247,7 +1773,7 @@ test "basic hash map usage" { |
| 2247 | try testing.expect(map.orderedRemove(100) == false); | 1773 | try testing.expect(map.orderedRemove(100) == false); |
| 2248 | try testing.expect(map.getEntry(100) == null); | 1774 | try testing.expect(map.getEntry(100) == null); |
| 2249 | try testing.expect(map.get(100) == null); | 1775 | try testing.expect(map.get(100) == null); |
| 2250 | const gop6 = try map.getOrPut(5); | 1776 | const gop6 = try map.getOrPut(gpa, 5); |
| 2251 | try testing.expect(gop6.found_existing == true); | 1777 | try testing.expect(gop6.found_existing == true); |
| 2252 | try testing.expect(gop6.value_ptr.* == 77); | 1778 | try testing.expect(gop6.value_ptr.* == 77); |
| 2253 | try testing.expect(gop6.index == 3); | 1779 | try testing.expect(gop6.index == 3); |
| ... | @@ -2256,15 +1782,17 @@ test "basic hash map usage" { | ... | @@ -2256,15 +1782,17 @@ test "basic hash map usage" { |
| 2256 | } | 1782 | } |
| 2257 | 1783 | ||
| 2258 | test "iterator hash map" { | 1784 | test "iterator hash map" { |
| 2259 | var reset_map = AutoArrayHashMap(i32, i32).init(std.testing.allocator); | 1785 | const gpa = testing.allocator; |
| 2260 | defer reset_map.deinit(); | 1786 | |
| 1787 | var reset_map: Auto(i32, i32) = .empty; | ||
| 1788 | defer reset_map.deinit(gpa); | ||
| 2261 | 1789 | ||
| 2262 | // test ensureTotalCapacity with a 0 parameter | 1790 | // test ensureTotalCapacity with a 0 parameter |
| 2263 | try reset_map.ensureTotalCapacity(0); | 1791 | try reset_map.ensureTotalCapacity(gpa, 0); |
| 2264 | 1792 | ||
| 2265 | try reset_map.putNoClobber(0, 11); | 1793 | try reset_map.putNoClobber(gpa, 0, 11); |
| 2266 | try reset_map.putNoClobber(1, 22); | 1794 | try reset_map.putNoClobber(gpa, 1, 22); |
| 2267 | try reset_map.putNoClobber(2, 33); | 1795 | try reset_map.putNoClobber(gpa, 2, 33); |
| 2268 | 1796 | ||
| 2269 | const keys = [_]i32{ | 1797 | const keys = [_]i32{ |
| 2270 | 0, 2, 1, | 1798 | 0, 2, 1, |
| ... | @@ -2312,10 +1840,12 @@ test "iterator hash map" { | ... | @@ -2312,10 +1840,12 @@ test "iterator hash map" { |
| 2312 | } | 1840 | } |
| 2313 | 1841 | ||
| 2314 | test "ensure capacity" { | 1842 | test "ensure capacity" { |
| 2315 | var map = AutoArrayHashMap(i32, i32).init(std.testing.allocator); | 1843 | const gpa = testing.allocator; |
| 2316 | defer map.deinit(); | ||
| 2317 | 1844 | ||
| 2318 | try map.ensureTotalCapacity(20); | 1845 | var map: Auto(i32, i32) = .empty; |
| 1846 | defer map.deinit(gpa); | ||
| 1847 | |||
| 1848 | try map.ensureTotalCapacity(gpa, 20); | ||
| 2319 | const initial_capacity = map.capacity(); | 1849 | const initial_capacity = map.capacity(); |
| 2320 | try testing.expect(initial_capacity >= 20); | 1850 | try testing.expect(initial_capacity >= 20); |
| 2321 | var i: i32 = 0; | 1851 | var i: i32 = 0; |
| ... | @@ -2329,23 +1859,25 @@ test "ensure capacity" { | ... | @@ -2329,23 +1859,25 @@ test "ensure capacity" { |
| 2329 | test "ensure capacity leak" { | 1859 | test "ensure capacity leak" { |
| 2330 | try testing.checkAllAllocationFailures(std.testing.allocator, struct { | 1860 | try testing.checkAllAllocationFailures(std.testing.allocator, struct { |
| 2331 | pub fn f(allocator: Allocator) !void { | 1861 | pub fn f(allocator: Allocator) !void { |
| 2332 | var map = AutoArrayHashMap(i32, i32).init(allocator); | 1862 | var map: Auto(i32, i32) = .empty; |
| 2333 | defer map.deinit(); | 1863 | defer map.deinit(allocator); |
| 2334 | 1864 | ||
| 2335 | var i: i32 = 0; | 1865 | var i: i32 = 0; |
| 2336 | // put more than `linear_scan_max` in so index_header gets allocated. | 1866 | // put more than `linear_scan_max` in so index_header gets allocated. |
| 2337 | while (i <= 20) : (i += 1) try map.put(i, i); | 1867 | while (i <= 20) : (i += 1) try map.put(allocator, i, i); |
| 2338 | } | 1868 | } |
| 2339 | }.f, .{}); | 1869 | }.f, .{}); |
| 2340 | } | 1870 | } |
| 2341 | 1871 | ||
| 2342 | test "big map" { | 1872 | test "big map" { |
| 2343 | var map = AutoArrayHashMap(i32, i32).init(std.testing.allocator); | 1873 | const gpa = testing.allocator; |
| 2344 | defer map.deinit(); | 1874 | |
| 1875 | var map: Auto(i32, i32) = .empty; | ||
| 1876 | defer map.deinit(gpa); | ||
| 2345 | 1877 | ||
| 2346 | var i: i32 = 0; | 1878 | var i: i32 = 0; |
| 2347 | while (i < 8) : (i += 1) { | 1879 | while (i < 8) : (i += 1) { |
| 2348 | try map.put(i, i + 10); | 1880 | try map.put(gpa, i, i + 10); |
| 2349 | } | 1881 | } |
| 2350 | 1882 | ||
| 2351 | i = 0; | 1883 | i = 0; |
| ... | @@ -2358,7 +1890,7 @@ test "big map" { | ... | @@ -2358,7 +1890,7 @@ test "big map" { |
| 2358 | 1890 | ||
| 2359 | i = 4; | 1891 | i = 4; |
| 2360 | while (i < 12) : (i += 1) { | 1892 | while (i < 12) : (i += 1) { |
| 2361 | try map.put(i, i + 12); | 1893 | try map.put(gpa, i, i + 12); |
| 2362 | } | 1894 | } |
| 2363 | 1895 | ||
| 2364 | i = 0; | 1896 | i = 0; |
| ... | @@ -2393,17 +1925,19 @@ test "big map" { | ... | @@ -2393,17 +1925,19 @@ test "big map" { |
| 2393 | } | 1925 | } |
| 2394 | 1926 | ||
| 2395 | test "clone" { | 1927 | test "clone" { |
| 2396 | var original = AutoArrayHashMap(i32, i32).init(std.testing.allocator); | 1928 | const gpa = testing.allocator; |
| 2397 | defer original.deinit(); | 1929 | |
| 1930 | var original: Auto(i32, i32) = .empty; | ||
| 1931 | defer original.deinit(gpa); | ||
| 2398 | 1932 | ||
| 2399 | // put more than `linear_scan_max` so we can test that the index header is properly cloned | 1933 | // put more than `linear_scan_max` so we can test that the index header is properly cloned |
| 2400 | var i: u8 = 0; | 1934 | var i: u8 = 0; |
| 2401 | while (i < 10) : (i += 1) { | 1935 | while (i < 10) : (i += 1) { |
| 2402 | try original.putNoClobber(i, i * 10); | 1936 | try original.putNoClobber(gpa, i, i * 10); |
| 2403 | } | 1937 | } |
| 2404 | 1938 | ||
| 2405 | var copy = try original.clone(); | 1939 | var copy = try original.clone(gpa); |
| 2406 | defer copy.deinit(); | 1940 | defer copy.deinit(gpa); |
| 2407 | 1941 | ||
| 2408 | i = 0; | 1942 | i = 0; |
| 2409 | while (i < 10) : (i += 1) { | 1943 | while (i < 10) : (i += 1) { |
| ... | @@ -2419,16 +1953,18 @@ test "clone" { | ... | @@ -2419,16 +1953,18 @@ test "clone" { |
| 2419 | } | 1953 | } |
| 2420 | 1954 | ||
| 2421 | test "shrink" { | 1955 | test "shrink" { |
| 2422 | var map = AutoArrayHashMap(i32, i32).init(std.testing.allocator); | 1956 | const gpa = testing.allocator; |
| 2423 | defer map.deinit(); | 1957 | |
| 1958 | var map: Auto(i32, i32) = .empty; | ||
| 1959 | defer map.deinit(gpa); | ||
| 2424 | 1960 | ||
| 2425 | // This test is more interesting if we insert enough entries to allocate the index header. | 1961 | // This test is more interesting if we insert enough entries to allocate the index header. |
| 2426 | const num_entries = 200; | 1962 | const num_entries = 200; |
| 2427 | var i: i32 = 0; | 1963 | var i: i32 = 0; |
| 2428 | while (i < num_entries) : (i += 1) | 1964 | while (i < num_entries) : (i += 1) |
| 2429 | try testing.expect((try map.fetchPut(i, i * 10)) == null); | 1965 | try testing.expect((try map.fetchPut(gpa, i, i * 10)) == null); |
| 2430 | 1966 | ||
| 2431 | try testing.expect(map.unmanaged.index_header != null); | 1967 | try testing.expect(map.index_header != null); |
| 2432 | try testing.expect(map.count() == num_entries); | 1968 | try testing.expect(map.count() == num_entries); |
| 2433 | 1969 | ||
| 2434 | // Test `shrinkRetainingCapacity`. | 1970 | // Test `shrinkRetainingCapacity`. |
| ... | @@ -2437,7 +1973,7 @@ test "shrink" { | ... | @@ -2437,7 +1973,7 @@ test "shrink" { |
| 2437 | try testing.expect(map.capacity() >= num_entries); | 1973 | try testing.expect(map.capacity() >= num_entries); |
| 2438 | i = 0; | 1974 | i = 0; |
| 2439 | while (i < num_entries) : (i += 1) { | 1975 | while (i < num_entries) : (i += 1) { |
| 2440 | const gop = try map.getOrPut(i); | 1976 | const gop = try map.getOrPut(gpa, i); |
| 2441 | if (i < 17) { | 1977 | if (i < 17) { |
| 2442 | try testing.expect(gop.found_existing == true); | 1978 | try testing.expect(gop.found_existing == true); |
| 2443 | try testing.expect(gop.value_ptr.* == i * 10); | 1979 | try testing.expect(gop.value_ptr.* == i * 10); |
| ... | @@ -2445,12 +1981,12 @@ test "shrink" { | ... | @@ -2445,12 +1981,12 @@ test "shrink" { |
| 2445 | } | 1981 | } |
| 2446 | 1982 | ||
| 2447 | // Test `shrinkAndFree`. | 1983 | // Test `shrinkAndFree`. |
| 2448 | map.shrinkAndFree(15); | 1984 | map.shrinkAndFree(gpa, 15); |
| 2449 | try testing.expect(map.count() == 15); | 1985 | try testing.expect(map.count() == 15); |
| 2450 | try testing.expect(map.capacity() == 15); | 1986 | try testing.expect(map.capacity() == 15); |
| 2451 | i = 0; | 1987 | i = 0; |
| 2452 | while (i < num_entries) : (i += 1) { | 1988 | while (i < num_entries) : (i += 1) { |
| 2453 | const gop = try map.getOrPut(i); | 1989 | const gop = try map.getOrPut(gpa, i); |
| 2454 | if (i < 15) { | 1990 | if (i < 15) { |
| 2455 | try testing.expect(gop.found_existing == true); | 1991 | try testing.expect(gop.found_existing == true); |
| 2456 | try testing.expect(gop.value_ptr.* == i * 10); | 1992 | try testing.expect(gop.value_ptr.* == i * 10); |
| ... | @@ -2459,15 +1995,17 @@ test "shrink" { | ... | @@ -2459,15 +1995,17 @@ test "shrink" { |
| 2459 | } | 1995 | } |
| 2460 | 1996 | ||
| 2461 | test "pop()" { | 1997 | test "pop()" { |
| 2462 | var map = AutoArrayHashMap(i32, i32).init(std.testing.allocator); | 1998 | const gpa = testing.allocator; |
| 2463 | defer map.deinit(); | 1999 | |
| 2000 | var map: Auto(i32, i32) = .empty; | ||
| 2001 | defer map.deinit(gpa); | ||
| 2464 | 2002 | ||
| 2465 | // Insert just enough entries so that the map expands. Afterwards, | 2003 | // Insert just enough entries so that the map expands. Afterwards, |
| 2466 | // pop all entries out of the map. | 2004 | // pop all entries out of the map. |
| 2467 | 2005 | ||
| 2468 | var i: i32 = 0; | 2006 | var i: i32 = 0; |
| 2469 | while (i < 9) : (i += 1) { | 2007 | while (i < 9) : (i += 1) { |
| 2470 | try testing.expect((try map.fetchPut(i, i)) == null); | 2008 | try testing.expect((try map.fetchPut(gpa, i, i)) == null); |
| 2471 | } | 2009 | } |
| 2472 | 2010 | ||
| 2473 | while (map.pop()) |pop| { | 2011 | while (map.pop()) |pop| { |
| ... | @@ -2479,31 +2017,33 @@ test "pop()" { | ... | @@ -2479,31 +2017,33 @@ test "pop()" { |
| 2479 | } | 2017 | } |
| 2480 | 2018 | ||
| 2481 | test "reIndex" { | 2019 | test "reIndex" { |
| 2482 | var map = ArrayHashMap(i32, i32, AutoContext(i32), true).init(std.testing.allocator); | 2020 | const gpa = testing.allocator; |
| 2483 | defer map.deinit(); | 2021 | |
| 2022 | var map: Custom(i32, i32, AutoContext(i32), true) = .empty; | ||
| 2023 | defer map.deinit(gpa); | ||
| 2484 | 2024 | ||
| 2485 | // Populate via the API. | 2025 | // Populate via the API. |
| 2486 | const num_indexed_entries = 200; | 2026 | const num_indexed_entries = 200; |
| 2487 | var i: i32 = 0; | 2027 | var i: i32 = 0; |
| 2488 | while (i < num_indexed_entries) : (i += 1) | 2028 | while (i < num_indexed_entries) : (i += 1) |
| 2489 | try testing.expect((try map.fetchPut(i, i * 10)) == null); | 2029 | try testing.expect((try map.fetchPut(gpa, i, i * 10)) == null); |
| 2490 | 2030 | ||
| 2491 | // Make sure we allocated an index header. | 2031 | // Make sure we allocated an index header. |
| 2492 | try testing.expect(map.unmanaged.index_header != null); | 2032 | try testing.expect(map.index_header != null); |
| 2493 | 2033 | ||
| 2494 | // Now write to the arrays directly. | 2034 | // Now write to the arrays directly. |
| 2495 | const num_unindexed_entries = 20; | 2035 | const num_unindexed_entries = 20; |
| 2496 | try map.unmanaged.entries.resize(std.testing.allocator, num_indexed_entries + num_unindexed_entries); | 2036 | try map.entries.resize(std.testing.allocator, num_indexed_entries + num_unindexed_entries); |
| 2497 | for (map.keys()[num_indexed_entries..], map.values()[num_indexed_entries..], num_indexed_entries..) |*key, *value, j| { | 2037 | for (map.keys()[num_indexed_entries..], map.values()[num_indexed_entries..], num_indexed_entries..) |*key, *value, j| { |
| 2498 | key.* = @intCast(j); | 2038 | key.* = @intCast(j); |
| 2499 | value.* = @intCast(j * 10); | 2039 | value.* = @intCast(j * 10); |
| 2500 | } | 2040 | } |
| 2501 | 2041 | ||
| 2502 | // After reindexing, we should see everything. | 2042 | // After reindexing, we should see everything. |
| 2503 | try map.reIndex(); | 2043 | try map.reIndex(gpa); |
| 2504 | i = 0; | 2044 | i = 0; |
| 2505 | while (i < num_indexed_entries + num_unindexed_entries) : (i += 1) { | 2045 | while (i < num_indexed_entries + num_unindexed_entries) : (i += 1) { |
| 2506 | const gop = try map.getOrPut(i); | 2046 | const gop = try map.getOrPut(gpa, i); |
| 2507 | try testing.expect(gop.found_existing == true); | 2047 | try testing.expect(gop.found_existing == true); |
| 2508 | try testing.expect(gop.value_ptr.* == i * 10); | 2048 | try testing.expect(gop.value_ptr.* == i * 10); |
| 2509 | try testing.expect(gop.index == i); | 2049 | try testing.expect(gop.index == i); |
| ... | @@ -2511,23 +2051,20 @@ test "reIndex" { | ... | @@ -2511,23 +2051,20 @@ test "reIndex" { |
| 2511 | } | 2051 | } |
| 2512 | 2052 | ||
| 2513 | test "auto store_hash" { | 2053 | test "auto store_hash" { |
| 2514 | const HasCheapEql = AutoArrayHashMap(i32, i32); | 2054 | const HasCheapEql = Auto(i32, i32); |
| 2515 | const HasExpensiveEql = AutoArrayHashMap([32]i32, i32); | 2055 | const HasExpensiveEql = Auto([32]i32, i32); |
| 2516 | try testing.expect(@FieldType(HasCheapEql.Data, "hash") == void); | 2056 | try testing.expect(@FieldType(HasCheapEql.Data, "hash") == void); |
| 2517 | try testing.expect(@FieldType(HasExpensiveEql.Data, "hash") != void); | 2057 | try testing.expect(@FieldType(HasExpensiveEql.Data, "hash") != void); |
| 2518 | |||
| 2519 | const HasCheapEqlUn = AutoArrayHashMapUnmanaged(i32, i32); | ||
| 2520 | const HasExpensiveEqlUn = AutoArrayHashMapUnmanaged([32]i32, i32); | ||
| 2521 | try testing.expect(@FieldType(HasCheapEqlUn.Data, "hash") == void); | ||
| 2522 | try testing.expect(@FieldType(HasExpensiveEqlUn.Data, "hash") != void); | ||
| 2523 | } | 2058 | } |
| 2524 | 2059 | ||
| 2525 | test "sort" { | 2060 | test "sort" { |
| 2526 | var map = AutoArrayHashMap(i32, i32).init(std.testing.allocator); | 2061 | const gpa = testing.allocator; |
| 2527 | defer map.deinit(); | 2062 | |
| 2063 | var map: Auto(i32, i32) = .empty; | ||
| 2064 | defer map.deinit(gpa); | ||
| 2528 | 2065 | ||
| 2529 | for ([_]i32{ 8, 3, 12, 10, 2, 4, 9, 5, 6, 13, 14, 15, 16, 1, 11, 17, 7 }) |x| { | 2066 | for ([_]i32{ 8, 3, 12, 10, 2, 4, 9, 5, 6, 13, 14, 15, 16, 1, 11, 17, 7 }) |x| { |
| 2530 | try map.put(x, x * 3); | 2067 | try map.put(gpa, x, x * 3); |
| 2531 | } | 2068 | } |
| 2532 | 2069 | ||
| 2533 | const C = struct { | 2070 | const C = struct { |
| ... | @@ -2549,15 +2086,17 @@ test "sort" { | ... | @@ -2549,15 +2086,17 @@ test "sort" { |
| 2549 | } | 2086 | } |
| 2550 | 2087 | ||
| 2551 | test "0 sized key" { | 2088 | test "0 sized key" { |
| 2552 | var map = AutoArrayHashMap(u0, i32).init(std.testing.allocator); | 2089 | const gpa = testing.allocator; |
| 2553 | defer map.deinit(); | 2090 | |
| 2091 | var map: Auto(u0, i32) = .empty; | ||
| 2092 | defer map.deinit(gpa); | ||
| 2554 | 2093 | ||
| 2555 | try testing.expectEqual(map.get(0), null); | 2094 | try testing.expectEqual(map.get(0), null); |
| 2556 | 2095 | ||
| 2557 | try map.put(0, 5); | 2096 | try map.put(gpa, 0, 5); |
| 2558 | try testing.expectEqual(map.get(0), 5); | 2097 | try testing.expectEqual(map.get(0), 5); |
| 2559 | 2098 | ||
| 2560 | try map.put(0, 10); | 2099 | try map.put(gpa, 0, 10); |
| 2561 | try testing.expectEqual(map.get(0), 10); | 2100 | try testing.expectEqual(map.get(0), 10); |
| 2562 | 2101 | ||
| 2563 | try testing.expectEqual(map.swapRemove(0), true); | 2102 | try testing.expectEqual(map.swapRemove(0), true); |
| ... | @@ -2565,12 +2104,14 @@ test "0 sized key" { | ... | @@ -2565,12 +2104,14 @@ test "0 sized key" { |
| 2565 | } | 2104 | } |
| 2566 | 2105 | ||
| 2567 | test "0 sized key and 0 sized value" { | 2106 | test "0 sized key and 0 sized value" { |
| 2568 | var map = AutoArrayHashMap(u0, u0).init(std.testing.allocator); | 2107 | const gpa = testing.allocator; |
| 2569 | defer map.deinit(); | 2108 | |
| 2109 | var map: Auto(u0, u0) = .empty; | ||
| 2110 | defer map.deinit(gpa); | ||
| 2570 | 2111 | ||
| 2571 | try testing.expectEqual(map.get(0), null); | 2112 | try testing.expectEqual(map.get(0), null); |
| 2572 | 2113 | ||
| 2573 | try map.put(0, 0); | 2114 | try map.put(gpa, 0, 0); |
| 2574 | try testing.expectEqual(map.get(0), 0); | 2115 | try testing.expectEqual(map.get(0), 0); |
| 2575 | 2116 | ||
| 2576 | try testing.expectEqual(map.swapRemove(0), true); | 2117 | try testing.expectEqual(map.swapRemove(0), true); |
| ... | @@ -2580,7 +2121,7 @@ test "0 sized key and 0 sized value" { | ... | @@ -2580,7 +2121,7 @@ test "0 sized key and 0 sized value" { |
| 2580 | test "setKey storehash true" { | 2121 | test "setKey storehash true" { |
| 2581 | const gpa = std.testing.allocator; | 2122 | const gpa = std.testing.allocator; |
| 2582 | 2123 | ||
| 2583 | var map: ArrayHashMapUnmanaged(i32, i32, AutoContext(i32), true) = .empty; | 2124 | var map: ArrayHashMap(i32, i32, AutoContext(i32), true) = .empty; |
| 2584 | defer map.deinit(gpa); | 2125 | defer map.deinit(gpa); |
| 2585 | 2126 | ||
| 2586 | try map.put(gpa, 12, 34); | 2127 | try map.put(gpa, 12, 34); |
| ... | @@ -2596,7 +2137,7 @@ test "setKey storehash true" { | ... | @@ -2596,7 +2137,7 @@ test "setKey storehash true" { |
| 2596 | test "setKey storehash false" { | 2137 | test "setKey storehash false" { |
| 2597 | const gpa = std.testing.allocator; | 2138 | const gpa = std.testing.allocator; |
| 2598 | 2139 | ||
| 2599 | var map: ArrayHashMapUnmanaged(i32, i32, AutoContext(i32), false) = .empty; | 2140 | var map: ArrayHashMap(i32, i32, AutoContext(i32), false) = .empty; |
| 2600 | defer map.deinit(gpa); | 2141 | defer map.deinit(gpa); |
| 2601 | 2142 | ||
| 2602 | try map.put(gpa, 12, 34); | 2143 | try map.put(gpa, 12, 34); |
| ... | @@ -2691,7 +2232,7 @@ pub fn getAutoHashStratFn(comptime K: type, comptime Context: type, comptime str | ... | @@ -2691,7 +2232,7 @@ pub fn getAutoHashStratFn(comptime K: type, comptime Context: type, comptime str |
| 2691 | test "orderedRemoveAtMany" { | 2232 | test "orderedRemoveAtMany" { |
| 2692 | const gpa = testing.allocator; | 2233 | const gpa = testing.allocator; |
| 2693 | 2234 | ||
| 2694 | var map: AutoArrayHashMapUnmanaged(usize, void) = .empty; | 2235 | var map: Auto(usize, void) = .empty; |
| 2695 | defer map.deinit(gpa); | 2236 | defer map.deinit(gpa); |
| 2696 | 2237 | ||
| 2697 | for (0..10) |n| { | 2238 | for (0..10) |n| { |
lib/std/json/Stringify.zig+3-3| ... | @@ -770,9 +770,9 @@ fn testBasicWriteStream(w: *Stringify) !void { | ... | @@ -770,9 +770,9 @@ fn testBasicWriteStream(w: *Stringify) !void { |
| 770 | } | 770 | } |
| 771 | 771 | ||
| 772 | fn getJsonObject(allocator: std.mem.Allocator) !std.json.Value { | 772 | fn getJsonObject(allocator: std.mem.Allocator) !std.json.Value { |
| 773 | var v: std.json.Value = .{ .object = std.json.ObjectMap.init(allocator) }; | 773 | var v: std.json.Value = .{ .object = .empty }; |
| 774 | try v.object.put("one", std.json.Value{ .integer = @as(i64, @intCast(1)) }); | 774 | try v.object.put(allocator, "one", std.json.Value{ .integer = @as(i64, @intCast(1)) }); |
| 775 | try v.object.put("two", std.json.Value{ .float = 2.0 }); | 775 | try v.object.put(allocator, "two", std.json.Value{ .float = 2.0 }); |
| 776 | return v; | 776 | return v; |
| 777 | } | 777 | } |
| 778 | 778 |
lib/std/json/dynamic.zig+4-4| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const debug = std.debug; | 2 | const debug = std.debug; |
| 3 | const ArenaAllocator = std.heap.ArenaAllocator; | 3 | const ArenaAllocator = std.heap.ArenaAllocator; |
| 4 | const StringArrayHashMap = std.StringArrayHashMap; | 4 | const StringArrayHashMap = std.array_hash_map.String; |
| 5 | const Allocator = std.mem.Allocator; | 5 | const Allocator = std.mem.Allocator; |
| 6 | const json = std.json; | 6 | const json = std.json; |
| 7 | 7 | ||
| ... | @@ -103,10 +103,10 @@ pub const Value = union(enum) { | ... | @@ -103,10 +103,10 @@ pub const Value = union(enum) { |
| 103 | 103 | ||
| 104 | .object_begin => { | 104 | .object_begin => { |
| 105 | switch (try source.nextAllocMax(allocator, .alloc_always, options.max_value_len.?)) { | 105 | switch (try source.nextAllocMax(allocator, .alloc_always, options.max_value_len.?)) { |
| 106 | .object_end => return try handleCompleteValue(&stack, allocator, source, Value{ .object = ObjectMap.init(allocator) }, options) orelse continue, | 106 | .object_end => return try handleCompleteValue(&stack, allocator, source, Value{ .object = .empty }, options) orelse continue, |
| 107 | .allocated_string => |key| { | 107 | .allocated_string => |key| { |
| 108 | try stack.appendSlice(&[_]Value{ | 108 | try stack.appendSlice(&[_]Value{ |
| 109 | Value{ .object = ObjectMap.init(allocator) }, | 109 | Value{ .object = .empty }, |
| 110 | Value{ .string = key }, | 110 | Value{ .string = key }, |
| 111 | }); | 111 | }); |
| 112 | }, | 112 | }, |
| ... | @@ -145,7 +145,7 @@ fn handleCompleteValue(stack: *Array, allocator: Allocator, source: anytype, val | ... | @@ -145,7 +145,7 @@ fn handleCompleteValue(stack: *Array, allocator: Allocator, source: anytype, val |
| 145 | // stack: [..., .object] | 145 | // stack: [..., .object] |
| 146 | var object = &stack.items[stack.items.len - 1].object; | 146 | var object = &stack.items[stack.items.len - 1].object; |
| 147 | 147 | ||
| 148 | const gop = try object.getOrPut(key); | 148 | const gop = try object.getOrPut(allocator, key); |
| 149 | if (gop.found_existing) { | 149 | if (gop.found_existing) { |
| 150 | switch (options.duplicate_field_behavior) { | 150 | switch (options.duplicate_field_behavior) { |
| 151 | .use_first => {}, | 151 | .use_first => {}, |
lib/std/json/dynamic_test.zig+4-3| ... | @@ -220,14 +220,15 @@ test "Value with duplicate fields" { | ... | @@ -220,14 +220,15 @@ test "Value with duplicate fields" { |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | test "Value.jsonStringify" { | 222 | test "Value.jsonStringify" { |
| 223 | const gpa = testing.allocator; | ||
| 223 | var vals = [_]Value{ | 224 | var vals = [_]Value{ |
| 224 | .{ .integer = 1 }, | 225 | .{ .integer = 1 }, |
| 225 | .{ .integer = 2 }, | 226 | .{ .integer = 2 }, |
| 226 | .{ .number_string = "3" }, | 227 | .{ .number_string = "3" }, |
| 227 | }; | 228 | }; |
| 228 | var obj = ObjectMap.init(testing.allocator); | 229 | var obj: ObjectMap = .empty; |
| 229 | defer obj.deinit(); | 230 | defer obj.deinit(gpa); |
| 230 | try obj.putNoClobber("a", .{ .string = "b" }); | 231 | try obj.putNoClobber(gpa, "a", .{ .string = "b" }); |
| 231 | const array = [_]Value{ | 232 | const array = [_]Value{ |
| 232 | .null, | 233 | .null, |
| 233 | .{ .bool = true }, | 234 | .{ .bool = true }, |
lib/std/std.zig+7-6| ... | @@ -1,7 +1,3 @@ | ... | @@ -1,7 +1,3 @@ |
| 1 | pub const ArrayHashMap = array_hash_map.ArrayHashMap; | ||
| 2 | pub const ArrayHashMapUnmanaged = array_hash_map.ArrayHashMapUnmanaged; | ||
| 3 | pub const AutoArrayHashMap = array_hash_map.AutoArrayHashMap; | ||
| 4 | pub const AutoArrayHashMapUnmanaged = array_hash_map.AutoArrayHashMapUnmanaged; | ||
| 5 | pub const AutoHashMap = hash_map.AutoHashMap; | 1 | pub const AutoHashMap = hash_map.AutoHashMap; |
| 6 | pub const AutoHashMapUnmanaged = hash_map.AutoHashMapUnmanaged; | 2 | pub const AutoHashMapUnmanaged = hash_map.AutoHashMapUnmanaged; |
| 7 | pub const BitStack = @import("BitStack.zig"); | 3 | pub const BitStack = @import("BitStack.zig"); |
| ... | @@ -31,14 +27,19 @@ pub const SinglyLinkedList = @import("SinglyLinkedList.zig"); | ... | @@ -31,14 +27,19 @@ pub const SinglyLinkedList = @import("SinglyLinkedList.zig"); |
| 31 | pub const StaticBitSet = bit_set.StaticBitSet; | 27 | pub const StaticBitSet = bit_set.StaticBitSet; |
| 32 | pub const StringHashMap = hash_map.StringHashMap; | 28 | pub const StringHashMap = hash_map.StringHashMap; |
| 33 | pub const StringHashMapUnmanaged = hash_map.StringHashMapUnmanaged; | 29 | pub const StringHashMapUnmanaged = hash_map.StringHashMapUnmanaged; |
| 34 | pub const StringArrayHashMap = array_hash_map.StringArrayHashMap; | ||
| 35 | pub const StringArrayHashMapUnmanaged = array_hash_map.StringArrayHashMapUnmanaged; | ||
| 36 | pub const Target = @import("Target.zig"); | 30 | pub const Target = @import("Target.zig"); |
| 37 | pub const Thread = @import("Thread.zig"); | 31 | pub const Thread = @import("Thread.zig"); |
| 38 | pub const Treap = @import("treap.zig").Treap; | 32 | pub const Treap = @import("treap.zig").Treap; |
| 39 | pub const Tz = tz.Tz; | 33 | pub const Tz = tz.Tz; |
| 40 | pub const Uri = @import("Uri.zig"); | 34 | pub const Uri = @import("Uri.zig"); |
| 41 | 35 | ||
| 36 | /// Deprecated; use `array_hash_map.Custom`. | ||
| 37 | pub const ArrayHashMapUnmanaged = array_hash_map.Custom; | ||
| 38 | /// Deprecated; use `array_hash_map.Auto`. | ||
| 39 | pub const AutoArrayHashMapUnmanaged = array_hash_map.Auto; | ||
| 40 | /// Deprecated; use `array_hash_map.String`. | ||
| 41 | pub const StringArrayHashMapUnmanaged = array_hash_map.String; | ||
| 42 | |||
| 42 | /// A contiguous, growable list of items in memory. This is a wrapper around a | 43 | /// A contiguous, growable list of items in memory. This is a wrapper around a |
| 43 | /// slice of `T` values. | 44 | /// slice of `T` values. |
| 44 | /// | 45 | /// |
lib/std/zig/AstGen.zig+3-3| ... | @@ -1779,8 +1779,8 @@ fn structInitExpr( | ... | @@ -1779,8 +1779,8 @@ fn structInitExpr( |
| 1779 | var sfba = std.heap.stackFallback(256, astgen.arena); | 1779 | var sfba = std.heap.stackFallback(256, astgen.arena); |
| 1780 | const sfba_allocator = sfba.get(); | 1780 | const sfba_allocator = sfba.get(); |
| 1781 | 1781 | ||
| 1782 | var duplicate_names = std.AutoArrayHashMap(Zir.NullTerminatedString, ArrayList(Ast.TokenIndex)).init(sfba_allocator); | 1782 | var duplicate_names: std.array_hash_map.Auto(Zir.NullTerminatedString, ArrayList(Ast.TokenIndex)) = .empty; |
| 1783 | try duplicate_names.ensureTotalCapacity(@intCast(struct_init.ast.fields.len)); | 1783 | try duplicate_names.ensureTotalCapacity(sfba_allocator, @intCast(struct_init.ast.fields.len)); |
| 1784 | 1784 | ||
| 1785 | // When there aren't errors, use this to avoid a second iteration. | 1785 | // When there aren't errors, use this to avoid a second iteration. |
| 1786 | var any_duplicate = false; | 1786 | var any_duplicate = false; |
| ... | @@ -1789,7 +1789,7 @@ fn structInitExpr( | ... | @@ -1789,7 +1789,7 @@ fn structInitExpr( |
| 1789 | const name_token = tree.firstToken(field) - 2; | 1789 | const name_token = tree.firstToken(field) - 2; |
| 1790 | const name_index = try astgen.identAsString(name_token); | 1790 | const name_index = try astgen.identAsString(name_token); |
| 1791 | 1791 | ||
| 1792 | const gop = try duplicate_names.getOrPut(name_index); | 1792 | const gop = try duplicate_names.getOrPut(sfba_allocator, name_index); |
| 1793 | 1793 | ||
| 1794 | if (gop.found_existing) { | 1794 | if (gop.found_existing) { |
| 1795 | try gop.value_ptr.append(sfba_allocator, name_token); | 1795 | try gop.value_ptr.append(sfba_allocator, name_token); |
src/InternPool.zig+3-3| ... | @@ -10552,7 +10552,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo | ... | @@ -10552,7 +10552,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo |
| 10552 | count: usize = 0, | 10552 | count: usize = 0, |
| 10553 | bytes: usize = 0, | 10553 | bytes: usize = 0, |
| 10554 | }; | 10554 | }; |
| 10555 | var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena); | 10555 | var counts: std.array_hash_map.Auto(Tag, TagStats) = .empty; |
| 10556 | for (ip.locals) |*local| { | 10556 | for (ip.locals) |*local| { |
| 10557 | // Early check for length 0, because `view()` is invalid if capacity is 0 | 10557 | // Early check for length 0, because `view()` is invalid if capacity is 0 |
| 10558 | if (local.mutate.items.len == 0) continue; | 10558 | if (local.mutate.items.len == 0) continue; |
| ... | @@ -10563,7 +10563,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo | ... | @@ -10563,7 +10563,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo |
| 10563 | items.items(.tag)[0..local.mutate.items.len], | 10563 | items.items(.tag)[0..local.mutate.items.len], |
| 10564 | items.items(.data)[0..local.mutate.items.len], | 10564 | items.items(.data)[0..local.mutate.items.len], |
| 10565 | ) |tag, data| { | 10565 | ) |tag, data| { |
| 10566 | const gop = try counts.getOrPut(tag); | 10566 | const gop = try counts.getOrPut(arena, tag); |
| 10567 | if (!gop.found_existing) gop.value_ptr.* = .{}; | 10567 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| 10568 | gop.value_ptr.count += 1; | 10568 | gop.value_ptr.count += 1; |
| 10569 | gop.value_ptr.bytes += 1 + 4 + @as(usize, switch (tag) { | 10569 | gop.value_ptr.bytes += 1 + 4 + @as(usize, switch (tag) { |
| ... | @@ -10799,7 +10799,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo | ... | @@ -10799,7 +10799,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo |
| 10799 | } | 10799 | } |
| 10800 | } | 10800 | } |
| 10801 | const SortContext = struct { | 10801 | const SortContext = struct { |
| 10802 | map: *std.AutoArrayHashMap(Tag, TagStats), | 10802 | map: *std.array_hash_map.Auto(Tag, TagStats), |
| 10803 | pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool { | 10803 | pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool { |
| 10804 | const values = ctx.map.values(); | 10804 | const values = ctx.map.values(); |
| 10805 | return values[a_index].bytes > values[b_index].bytes; | 10805 | return values[a_index].bytes > values[b_index].bytes; |
src/libs/glibc.zig+3-3| ... | @@ -795,7 +795,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -795,7 +795,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 795 | // | 795 | // |
| 796 | // If we don't handle this, we end up writing the default `lgammal` symbol for version 2.33 | 796 | // If we don't handle this, we end up writing the default `lgammal` symbol for version 2.33 |
| 797 | // twice, which causes a "duplicate symbol" assembler error. | 797 | // twice, which causes a "duplicate symbol" assembler error. |
| 798 | var versions_written = std.AutoArrayHashMap(Version, void).init(arena); | 798 | var versions_written: std.array_hash_map.Auto(Version, void) = .empty; |
| 799 | 799 | ||
| 800 | var inc_reader: Io.Reader = .fixed(metadata.inclusions); | 800 | var inc_reader: Io.Reader = .fixed(metadata.inclusions); |
| 801 | 801 | ||
| ... | @@ -859,7 +859,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -859,7 +859,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 859 | } | 859 | } |
| 860 | 860 | ||
| 861 | versions_written.clearRetainingCapacity(); | 861 | versions_written.clearRetainingCapacity(); |
| 862 | try versions_written.ensureTotalCapacity(versions_len); | 862 | try versions_written.ensureTotalCapacity(arena, versions_len); |
| 863 | 863 | ||
| 864 | { | 864 | { |
| 865 | var ver_buf_i: u8 = 0; | 865 | var ver_buf_i: u8 = 0; |
| ... | @@ -1035,7 +1035,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -1035,7 +1035,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 1035 | } | 1035 | } |
| 1036 | 1036 | ||
| 1037 | versions_written.clearRetainingCapacity(); | 1037 | versions_written.clearRetainingCapacity(); |
| 1038 | try versions_written.ensureTotalCapacity(versions_len); | 1038 | try versions_written.ensureTotalCapacity(arena, versions_len); |
| 1039 | 1039 | ||
| 1040 | { | 1040 | { |
| 1041 | var ver_buf_i: u8 = 0; | 1041 | var ver_buf_i: u8 = 0; |
src/libs/mingw/implib.zig+3-3| ... | @@ -36,14 +36,14 @@ pub fn writeCoffArchive( | ... | @@ -36,14 +36,14 @@ pub fn writeCoffArchive( |
| 36 | var long_names: StringTable = .{}; | 36 | var long_names: StringTable = .{}; |
| 37 | defer long_names.deinit(allocator); | 37 | defer long_names.deinit(allocator); |
| 38 | 38 | ||
| 39 | var symbol_to_member_index = std.StringArrayHashMap(usize).init(allocator); | 39 | var symbol_to_member_index: std.array_hash_map.String(usize) = .empty; |
| 40 | defer symbol_to_member_index.deinit(); | 40 | defer symbol_to_member_index.deinit(allocator); |
| 41 | var string_table_len: usize = 0; | 41 | var string_table_len: usize = 0; |
| 42 | var num_symbols: usize = 0; | 42 | var num_symbols: usize = 0; |
| 43 | 43 | ||
| 44 | for (members.list.items, 0..) |member, i| { | 44 | for (members.list.items, 0..) |member, i| { |
| 45 | for (member.symbol_names_for_import_lib) |symbol_name| { | 45 | for (member.symbol_names_for_import_lib) |symbol_name| { |
| 46 | const gop_result = try symbol_to_member_index.getOrPut(symbol_name); | 46 | const gop_result = try symbol_to_member_index.getOrPut(allocator, symbol_name); |
| 47 | // When building the symbol map, ignore duplicate symbol names. | 47 | // When building the symbol map, ignore duplicate symbol names. |
| 48 | // This can happen in cases like (using .def file syntax): | 48 | // This can happen in cases like (using .def file syntax): |
| 49 | // _foo | 49 | // _foo |
src/libs/musl.zig+6-6| ... | @@ -90,10 +90,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -90,10 +90,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 90 | // Even a .s file can substitute for a .c file. | 90 | // Even a .s file can substitute for a .c file. |
| 91 | const target = comp.getTarget(); | 91 | const target = comp.getTarget(); |
| 92 | const arch_name = std.zig.target.muslArchName(target.cpu.arch, target.abi); | 92 | const arch_name = std.zig.target.muslArchName(target.cpu.arch, target.abi); |
| 93 | var source_table = std.StringArrayHashMap(Ext).init(comp.gpa); | 93 | var source_table: std.array_hash_map.String(Ext) = .empty; |
| 94 | defer source_table.deinit(); | 94 | defer source_table.deinit(gpa); |
| 95 | 95 | ||
| 96 | try source_table.ensureTotalCapacity(compat_time32_files.len + src_files.len); | 96 | try source_table.ensureTotalCapacity(gpa, compat_time32_files.len + src_files.len); |
| 97 | 97 | ||
| 98 | for (src_files) |src_file| { | 98 | for (src_files) |src_file| { |
| 99 | try addSrcFile(arena, &source_table, src_file); | 99 | try addSrcFile(arena, &source_table, src_file); |
| ... | @@ -107,10 +107,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -107,10 +107,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | var c_source_files = std.array_list.Managed(Compilation.CSourceFile).init(comp.gpa); | 110 | var c_source_files = std.array_list.Managed(Compilation.CSourceFile).init(gpa); |
| 111 | defer c_source_files.deinit(); | 111 | defer c_source_files.deinit(); |
| 112 | 112 | ||
| 113 | var override_path = std.array_list.Managed(u8).init(comp.gpa); | 113 | var override_path = std.array_list.Managed(u8).init(gpa); |
| 114 | defer override_path.deinit(); | 114 | defer override_path.deinit(); |
| 115 | 115 | ||
| 116 | const s = path.sep_str; | 116 | const s = path.sep_str; |
| ... | @@ -349,7 +349,7 @@ const Ext = enum { | ... | @@ -349,7 +349,7 @@ const Ext = enum { |
| 349 | o3, | 349 | o3, |
| 350 | }; | 350 | }; |
| 351 | 351 | ||
| 352 | fn addSrcFile(arena: Allocator, source_table: *std.StringArrayHashMap(Ext), file_path: []const u8) !void { | 352 | fn addSrcFile(arena: Allocator, source_table: *std.array_hash_map.String(Ext), file_path: []const u8) !void { |
| 353 | const ext: Ext = ext: { | 353 | const ext: Ext = ext: { |
| 354 | if (mem.endsWith(u8, file_path, ".c")) { | 354 | if (mem.endsWith(u8, file_path, ".c")) { |
| 355 | if (mem.startsWith(u8, file_path, "musl/src/string/") or | 355 | if (mem.startsWith(u8, file_path, "musl/src/string/") or |
src/link/Elf.zig+8-8| ... | @@ -881,10 +881,10 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { | ... | @@ -881,10 +881,10 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 881 | self.rela_plt.clearRetainingCapacity(); | 881 | self.rela_plt.clearRetainingCapacity(); |
| 882 | 882 | ||
| 883 | if (self.zigObjectPtr()) |zo| { | 883 | if (self.zigObjectPtr()) |zo| { |
| 884 | var undefs: std.AutoArrayHashMap(SymbolResolver.Index, std.array_list.Managed(Ref)) = .init(gpa); | 884 | var undefs: std.array_hash_map.Auto(SymbolResolver.Index, std.array_list.Managed(Ref)) = .empty; |
| 885 | defer { | 885 | defer { |
| 886 | for (undefs.values()) |*refs| refs.deinit(); | 886 | for (undefs.values()) |*refs| refs.deinit(); |
| 887 | undefs.deinit(); | 887 | undefs.deinit(gpa); |
| 888 | } | 888 | } |
| 889 | 889 | ||
| 890 | var has_reloc_errors = false; | 890 | var has_reloc_errors = false; |
| ... | @@ -1332,10 +1332,10 @@ fn scanRelocs(self: *Elf) !void { | ... | @@ -1332,10 +1332,10 @@ fn scanRelocs(self: *Elf) !void { |
| 1332 | const gpa = self.base.comp.gpa; | 1332 | const gpa = self.base.comp.gpa; |
| 1333 | const shared_objects = self.shared_objects.values(); | 1333 | const shared_objects = self.shared_objects.values(); |
| 1334 | 1334 | ||
| 1335 | var undefs: std.AutoArrayHashMap(SymbolResolver.Index, std.array_list.Managed(Ref)) = .init(gpa); | 1335 | var undefs: std.array_hash_map.Auto(SymbolResolver.Index, std.array_list.Managed(Ref)) = .empty; |
| 1336 | defer { | 1336 | defer { |
| 1337 | for (undefs.values()) |*refs| refs.deinit(); | 1337 | for (undefs.values()) |*refs| refs.deinit(); |
| 1338 | undefs.deinit(); | 1338 | undefs.deinit(gpa); |
| 1339 | } | 1339 | } |
| 1340 | 1340 | ||
| 1341 | var has_reloc_errors = false; | 1341 | var has_reloc_errors = false; |
| ... | @@ -1748,12 +1748,12 @@ pub fn deleteExport( | ... | @@ -1748,12 +1748,12 @@ pub fn deleteExport( |
| 1748 | fn checkDuplicates(self: *Elf) !void { | 1748 | fn checkDuplicates(self: *Elf) !void { |
| 1749 | const gpa = self.base.comp.gpa; | 1749 | const gpa = self.base.comp.gpa; |
| 1750 | 1750 | ||
| 1751 | var dupes = std.AutoArrayHashMap(SymbolResolver.Index, std.ArrayList(File.Index)).init(gpa); | 1751 | var dupes: std.array_hash_map.Auto(SymbolResolver.Index, std.ArrayList(File.Index)) = .empty; |
| 1752 | defer { | 1752 | defer { |
| 1753 | for (dupes.values()) |*list| { | 1753 | for (dupes.values()) |*list| { |
| 1754 | list.deinit(gpa); | 1754 | list.deinit(gpa); |
| 1755 | } | 1755 | } |
| 1756 | dupes.deinit(); | 1756 | dupes.deinit(gpa); |
| 1757 | } | 1757 | } |
| 1758 | 1758 | ||
| 1759 | if (self.zigObjectPtr()) |zig_object| { | 1759 | if (self.zigObjectPtr()) |zig_object| { |
| ... | @@ -2992,10 +2992,10 @@ fn allocateSpecialPhdrs(self: *Elf) void { | ... | @@ -2992,10 +2992,10 @@ fn allocateSpecialPhdrs(self: *Elf) void { |
| 2992 | fn writeAtoms(self: *Elf) !void { | 2992 | fn writeAtoms(self: *Elf) !void { |
| 2993 | const gpa = self.base.comp.gpa; | 2993 | const gpa = self.base.comp.gpa; |
| 2994 | 2994 | ||
| 2995 | var undefs: std.AutoArrayHashMap(SymbolResolver.Index, std.array_list.Managed(Ref)) = .init(gpa); | 2995 | var undefs: std.array_hash_map.Auto(SymbolResolver.Index, std.array_list.Managed(Ref)) = .empty; |
| 2996 | defer { | 2996 | defer { |
| 2997 | for (undefs.values()) |*refs| refs.deinit(); | 2997 | for (undefs.values()) |*refs| refs.deinit(); |
| 2998 | undefs.deinit(); | 2998 | undefs.deinit(gpa); |
| 2999 | } | 2999 | } |
| 3000 | 3000 | ||
| 3001 | var buffer: std.Io.Writer.Allocating = .init(gpa); | 3001 | var buffer: std.Io.Writer.Allocating = .init(gpa); |
src/link/Elf/Atom.zig+1-1| ... | @@ -605,7 +605,7 @@ fn reportUndefined( | ... | @@ -605,7 +605,7 @@ fn reportUndefined( |
| 605 | .object => |x| x.symbols_resolver.items[rel.r_sym() - x.first_global.?], | 605 | .object => |x| x.symbols_resolver.items[rel.r_sym() - x.first_global.?], |
| 606 | inline else => |x| x.symbols_resolver.items[rel.r_sym()], | 606 | inline else => |x| x.symbols_resolver.items[rel.r_sym()], |
| 607 | }; | 607 | }; |
| 608 | const gop = try undefs.getOrPut(idx); | 608 | const gop = try undefs.getOrPut(gpa, idx); |
| 609 | if (!gop.found_existing) { | 609 | if (!gop.found_existing) { |
| 610 | gop.value_ptr.* = std.array_list.Managed(Elf.Ref).init(gpa); | 610 | gop.value_ptr.* = std.array_list.Managed(Elf.Ref).init(gpa); |
| 611 | } | 611 | } |
src/link/Elf/Object.zig+4-2| ... | @@ -753,6 +753,8 @@ pub fn markImportsExports(self: *Object, elf_file: *Elf) void { | ... | @@ -753,6 +753,8 @@ pub fn markImportsExports(self: *Object, elf_file: *Elf) void { |
| 753 | } | 753 | } |
| 754 | 754 | ||
| 755 | pub fn checkDuplicates(self: *Object, dupes: anytype, elf_file: *Elf) error{OutOfMemory}!void { | 755 | pub fn checkDuplicates(self: *Object, dupes: anytype, elf_file: *Elf) error{OutOfMemory}!void { |
| 756 | const gpa = elf_file.base.comp.gpa; | ||
| 757 | |||
| 756 | const first_global = self.first_global orelse return; | 758 | const first_global = self.first_global orelse return; |
| 757 | for (0..self.globals().len) |i| { | 759 | for (0..self.globals().len) |i| { |
| 758 | const esym_idx = first_global + i; | 760 | const esym_idx = first_global + i; |
| ... | @@ -772,11 +774,11 @@ pub fn checkDuplicates(self: *Object, dupes: anytype, elf_file: *Elf) error{OutO | ... | @@ -772,11 +774,11 @@ pub fn checkDuplicates(self: *Object, dupes: anytype, elf_file: *Elf) error{OutO |
| 772 | if (!atom_ptr.alive) continue; | 774 | if (!atom_ptr.alive) continue; |
| 773 | } | 775 | } |
| 774 | 776 | ||
| 775 | const gop = try dupes.getOrPut(self.symbols_resolver.items[i]); | 777 | const gop = try dupes.getOrPut(gpa, self.symbols_resolver.items[i]); |
| 776 | if (!gop.found_existing) { | 778 | if (!gop.found_existing) { |
| 777 | gop.value_ptr.* = .empty; | 779 | gop.value_ptr.* = .empty; |
| 778 | } | 780 | } |
| 779 | try gop.value_ptr.append(elf_file.base.comp.gpa, self.index); | 781 | try gop.value_ptr.append(gpa, self.index); |
| 780 | } | 782 | } |
| 781 | } | 783 | } |
| 782 | 784 |
src/link/Elf/ZigObject.zig+3-1| ... | @@ -710,6 +710,8 @@ pub fn markImportsExports(self: *ZigObject, elf_file: *Elf) void { | ... | @@ -710,6 +710,8 @@ pub fn markImportsExports(self: *ZigObject, elf_file: *Elf) void { |
| 710 | } | 710 | } |
| 711 | 711 | ||
| 712 | pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{OutOfMemory}!void { | 712 | pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{OutOfMemory}!void { |
| 713 | const gpa = elf_file.base.comp.gpa; | ||
| 714 | |||
| 713 | for (self.global_symbols.items, 0..) |index, i| { | 715 | for (self.global_symbols.items, 0..) |index, i| { |
| 714 | const esym = self.symtab.items(.elf_sym)[index]; | 716 | const esym = self.symtab.items(.elf_sym)[index]; |
| 715 | const shndx = self.symtab.items(.shndx)[index]; | 717 | const shndx = self.symtab.items(.shndx)[index]; |
| ... | @@ -727,7 +729,7 @@ pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{O | ... | @@ -727,7 +729,7 @@ pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{O |
| 727 | if (!atom_ptr.alive) continue; | 729 | if (!atom_ptr.alive) continue; |
| 728 | } | 730 | } |
| 729 | 731 | ||
| 730 | const gop = try dupes.getOrPut(self.symbols_resolver.items[i]); | 732 | const gop = try dupes.getOrPut(gpa, self.symbols_resolver.items[i]); |
| 731 | if (!gop.found_existing) { | 733 | if (!gop.found_existing) { |
| 732 | gop.value_ptr.* = .empty; | 734 | gop.value_ptr.* = .empty; |
| 733 | } | 735 | } |
src/link/MachO/InternalObject.zig+6-6| ... | @@ -164,8 +164,8 @@ pub fn resolveBoundarySymbols(self: *InternalObject, macho_file: *MachO) !void { | ... | @@ -164,8 +164,8 @@ pub fn resolveBoundarySymbols(self: *InternalObject, macho_file: *MachO) !void { |
| 164 | defer tracy.end(); | 164 | defer tracy.end(); |
| 165 | 165 | ||
| 166 | const gpa = macho_file.base.comp.gpa; | 166 | const gpa = macho_file.base.comp.gpa; |
| 167 | var boundary_symbols = std.StringArrayHashMap(MachO.Ref).init(gpa); | 167 | var boundary_symbols: std.array_hash_map.String(MachO.Ref) = .empty; |
| 168 | defer boundary_symbols.deinit(); | 168 | defer boundary_symbols.deinit(gpa); |
| 169 | 169 | ||
| 170 | for (macho_file.objects.items) |index| { | 170 | for (macho_file.objects.items) |index| { |
| 171 | const object = macho_file.getFile(index).?.object; | 171 | const object = macho_file.getFile(index).?.object; |
| ... | @@ -180,7 +180,7 @@ pub fn resolveBoundarySymbols(self: *InternalObject, macho_file: *MachO) !void { | ... | @@ -180,7 +180,7 @@ pub fn resolveBoundarySymbols(self: *InternalObject, macho_file: *MachO) !void { |
| 180 | mem.startsWith(u8, name, "section$start$") or | 180 | mem.startsWith(u8, name, "section$start$") or |
| 181 | mem.startsWith(u8, name, "section$end$")) | 181 | mem.startsWith(u8, name, "section$end$")) |
| 182 | { | 182 | { |
| 183 | const gop = try boundary_symbols.getOrPut(name); | 183 | const gop = try boundary_symbols.getOrPut(gpa, name); |
| 184 | if (!gop.found_existing) { | 184 | if (!gop.found_existing) { |
| 185 | gop.value_ptr.* = .{ .index = @intCast(i), .file = index }; | 185 | gop.value_ptr.* = .{ .index = @intCast(i), .file = index }; |
| 186 | } | 186 | } |
| ... | @@ -344,8 +344,8 @@ pub fn resolveObjcMsgSendSymbols(self: *InternalObject, macho_file: *MachO) !voi | ... | @@ -344,8 +344,8 @@ pub fn resolveObjcMsgSendSymbols(self: *InternalObject, macho_file: *MachO) !voi |
| 344 | 344 | ||
| 345 | const gpa = macho_file.base.comp.gpa; | 345 | const gpa = macho_file.base.comp.gpa; |
| 346 | 346 | ||
| 347 | var objc_msgsend_syms = std.StringArrayHashMap(MachO.Ref).init(gpa); | 347 | var objc_msgsend_syms: std.array_hash_map.String(MachO.Ref) = .empty; |
| 348 | defer objc_msgsend_syms.deinit(); | 348 | defer objc_msgsend_syms.deinit(gpa); |
| 349 | 349 | ||
| 350 | for (macho_file.objects.items) |index| { | 350 | for (macho_file.objects.items) |index| { |
| 351 | const object = macho_file.getFile(index).?.object; | 351 | const object = macho_file.getFile(index).?.object; |
| ... | @@ -360,7 +360,7 @@ pub fn resolveObjcMsgSendSymbols(self: *InternalObject, macho_file: *MachO) !voi | ... | @@ -360,7 +360,7 @@ pub fn resolveObjcMsgSendSymbols(self: *InternalObject, macho_file: *MachO) !voi |
| 360 | 360 | ||
| 361 | const name = sym.getName(macho_file); | 361 | const name = sym.getName(macho_file); |
| 362 | if (mem.startsWith(u8, name, "_objc_msgSend$")) { | 362 | if (mem.startsWith(u8, name, "_objc_msgSend$")) { |
| 363 | const gop = try objc_msgsend_syms.getOrPut(name); | 363 | const gop = try objc_msgsend_syms.getOrPut(gpa, name); |
| 364 | if (!gop.found_existing) { | 364 | if (!gop.found_existing) { |
| 365 | gop.value_ptr.* = .{ .index = @intCast(i), .file = index }; | 365 | gop.value_ptr.* = .{ .index = @intCast(i), .file = index }; |
| 366 | } | 366 | } |
src/link/MachO/Object.zig+5-5| ... | @@ -1292,8 +1292,8 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target. | ... | @@ -1292,8 +1292,8 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target. |
| 1292 | 1292 | ||
| 1293 | const Superposition = struct { atom: Atom.Index, size: u64, cu: ?UnwindInfo.Record.Index = null, fde: ?Fde.Index = null }; | 1293 | const Superposition = struct { atom: Atom.Index, size: u64, cu: ?UnwindInfo.Record.Index = null, fde: ?Fde.Index = null }; |
| 1294 | 1294 | ||
| 1295 | var superposition = std.AutoArrayHashMap(u64, Superposition).init(allocator); | 1295 | var superposition: std.array_hash_map.Auto(u64, Superposition) = .empty; |
| 1296 | defer superposition.deinit(); | 1296 | defer superposition.deinit(allocator); |
| 1297 | 1297 | ||
| 1298 | const slice = self.symtab.slice(); | 1298 | const slice = self.symtab.slice(); |
| 1299 | for (slice.items(.nlist), slice.items(.atom), slice.items(.size)) |nlist, atom, size| { | 1299 | for (slice.items(.nlist), slice.items(.atom), slice.items(.size)) |nlist, atom, size| { |
| ... | @@ -1301,7 +1301,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target. | ... | @@ -1301,7 +1301,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target. |
| 1301 | if (nlist.n_type.bits.type != .sect) continue; | 1301 | if (nlist.n_type.bits.type != .sect) continue; |
| 1302 | const sect = self.sections.items(.header)[nlist.n_sect - 1]; | 1302 | const sect = self.sections.items(.header)[nlist.n_sect - 1]; |
| 1303 | if (sect.isCode() and sect.size > 0) { | 1303 | if (sect.isCode() and sect.size > 0) { |
| 1304 | try superposition.ensureUnusedCapacity(1); | 1304 | try superposition.ensureUnusedCapacity(allocator, 1); |
| 1305 | const gop = superposition.getOrPutAssumeCapacity(nlist.n_value); | 1305 | const gop = superposition.getOrPutAssumeCapacity(nlist.n_value); |
| 1306 | if (gop.found_existing) { | 1306 | if (gop.found_existing) { |
| 1307 | assert(gop.value_ptr.atom == atom and gop.value_ptr.size == size); | 1307 | assert(gop.value_ptr.atom == atom and gop.value_ptr.size == size); |
| ... | @@ -1315,7 +1315,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target. | ... | @@ -1315,7 +1315,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target. |
| 1315 | const atom = rec.getAtom(macho_file); | 1315 | const atom = rec.getAtom(macho_file); |
| 1316 | const addr = atom.getInputAddress(macho_file) + rec.atom_offset; | 1316 | const addr = atom.getInputAddress(macho_file) + rec.atom_offset; |
| 1317 | 1317 | ||
| 1318 | try superposition.ensureUnusedCapacity(1); | 1318 | try superposition.ensureUnusedCapacity(allocator, 1); |
| 1319 | const gop = superposition.getOrPutAssumeCapacity(addr); | 1319 | const gop = superposition.getOrPutAssumeCapacity(addr); |
| 1320 | if (!gop.found_existing) { | 1320 | if (!gop.found_existing) { |
| 1321 | gop.value_ptr.* = .{ .atom = rec.atom, .size = rec.length }; | 1321 | gop.value_ptr.* = .{ .atom = rec.atom, .size = rec.length }; |
| ... | @@ -1331,7 +1331,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target. | ... | @@ -1331,7 +1331,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target. |
| 1331 | const atom = fde.getAtom(macho_file); | 1331 | const atom = fde.getAtom(macho_file); |
| 1332 | const addr = atom.getInputAddress(macho_file) + fde.atom_offset; | 1332 | const addr = atom.getInputAddress(macho_file) + fde.atom_offset; |
| 1333 | 1333 | ||
| 1334 | try superposition.ensureUnusedCapacity(1); | 1334 | try superposition.ensureUnusedCapacity(allocator, 1); |
| 1335 | const gop = superposition.getOrPutAssumeCapacity(addr); | 1335 | const gop = superposition.getOrPutAssumeCapacity(addr); |
| 1336 | if (!gop.found_existing) { | 1336 | if (!gop.found_existing) { |
| 1337 | gop.value_ptr.* = .{ .atom = fde.atom, .size = fde.pc_range }; | 1337 | gop.value_ptr.* = .{ .atom = fde.atom, .size = fde.pc_range }; |
src/link/MachO/UnwindInfo.zig+4-4| ... | @@ -173,18 +173,18 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { | ... | @@ -173,18 +173,18 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { |
| 173 | } | 173 | } |
| 174 | }; | 174 | }; |
| 175 | 175 | ||
| 176 | var common_encodings_counts = std.ArrayHashMap( | 176 | var common_encodings_counts: std.array_hash_map.Custom( |
| 177 | Encoding, | 177 | Encoding, |
| 178 | CommonEncWithCount, | 178 | CommonEncWithCount, |
| 179 | Context, | 179 | Context, |
| 180 | false, | 180 | false, |
| 181 | ).init(gpa); | 181 | ) = .empty; |
| 182 | defer common_encodings_counts.deinit(); | 182 | defer common_encodings_counts.deinit(gpa); |
| 183 | 183 | ||
| 184 | for (info.records.items) |ref| { | 184 | for (info.records.items) |ref| { |
| 185 | const rec = ref.getUnwindRecord(macho_file); | 185 | const rec = ref.getUnwindRecord(macho_file); |
| 186 | if (rec.enc.isDwarf(macho_file)) continue; | 186 | if (rec.enc.isDwarf(macho_file)) continue; |
| 187 | const gop = try common_encodings_counts.getOrPut(rec.enc); | 187 | const gop = try common_encodings_counts.getOrPut(gpa, rec.enc); |
| 188 | if (!gop.found_existing) { | 188 | if (!gop.found_existing) { |
| 189 | gop.value_ptr.* = .{ | 189 | gop.value_ptr.* = .{ |
| 190 | .enc = rec.enc, | 190 | .enc = rec.enc, |
src/link/SpirV/lower_invocation_globals.zig+28-27| ... | @@ -67,17 +67,17 @@ const ModuleInfo = struct { | ... | @@ -67,17 +67,17 @@ const ModuleInfo = struct { |
| 67 | parser: *BinaryModule.Parser, | 67 | parser: *BinaryModule.Parser, |
| 68 | binary: BinaryModule, | 68 | binary: BinaryModule, |
| 69 | ) BinaryModule.ParseError!ModuleInfo { | 69 | ) BinaryModule.ParseError!ModuleInfo { |
| 70 | var entry_points = std.AutoArrayHashMap(ResultId, void).init(arena); | 70 | var entry_points: std.array_hash_map.Auto(ResultId, void) = .empty; |
| 71 | var functions = std.AutoArrayHashMap(ResultId, Fn).init(arena); | 71 | var functions: std.array_hash_map.Auto(ResultId, Fn) = .empty; |
| 72 | var fn_types = std.AutoHashMap(ResultId, struct { | 72 | var fn_types = std.AutoHashMap(ResultId, struct { |
| 73 | return_type: ResultId, | 73 | return_type: ResultId, |
| 74 | param_types: []const ResultId, | 74 | param_types: []const ResultId, |
| 75 | }).init(arena); | 75 | }).init(arena); |
| 76 | var calls = std.AutoArrayHashMap(ResultId, void).init(arena); | 76 | var calls: std.array_hash_map.Auto(ResultId, void) = .empty; |
| 77 | var callee_store = std.array_list.Managed(ResultId).init(arena); | 77 | var callee_store = std.array_list.Managed(ResultId).init(arena); |
| 78 | var function_invocation_globals = std.AutoArrayHashMap(ResultId, void).init(arena); | 78 | var function_invocation_globals: std.array_hash_map.Auto(ResultId, void) = .empty; |
| 79 | var result_id_offsets = std.array_list.Managed(u16).init(arena); | 79 | var result_id_offsets = std.array_list.Managed(u16).init(arena); |
| 80 | var invocation_globals = std.AutoArrayHashMap(ResultId, InvocationGlobal).init(arena); | 80 | var invocation_globals: std.array_hash_map.Auto(ResultId, InvocationGlobal) = .empty; |
| 81 | 81 | ||
| 82 | var maybe_current_function: ?ResultId = null; | 82 | var maybe_current_function: ?ResultId = null; |
| 83 | var fn_ty_id: ResultId = undefined; | 83 | var fn_ty_id: ResultId = undefined; |
| ... | @@ -90,7 +90,7 @@ const ModuleInfo = struct { | ... | @@ -90,7 +90,7 @@ const ModuleInfo = struct { |
| 90 | switch (inst.opcode) { | 90 | switch (inst.opcode) { |
| 91 | .OpEntryPoint => { | 91 | .OpEntryPoint => { |
| 92 | const entry_point: ResultId = @enumFromInt(inst.operands[1]); | 92 | const entry_point: ResultId = @enumFromInt(inst.operands[1]); |
| 93 | const entry = try entry_points.getOrPut(entry_point); | 93 | const entry = try entry_points.getOrPut(arena, entry_point); |
| 94 | if (entry.found_existing) { | 94 | if (entry.found_existing) { |
| 95 | log.err("Entry point type {f} has duplicate definition", .{entry_point}); | 95 | log.err("Entry point type {f} has duplicate definition", .{entry_point}); |
| 96 | return error.DuplicateId; | 96 | return error.DuplicateId; |
| ... | @@ -126,7 +126,7 @@ const ModuleInfo = struct { | ... | @@ -126,7 +126,7 @@ const ModuleInfo = struct { |
| 126 | else | 126 | else |
| 127 | .none; | 127 | .none; |
| 128 | 128 | ||
| 129 | try invocation_globals.put(result_id, .{ | 129 | try invocation_globals.put(arena, result_id, .{ |
| 130 | .dependencies = .{}, | 130 | .dependencies = .{}, |
| 131 | .ty = global_type, | 131 | .ty = global_type, |
| 132 | .initializer = initializer, | 132 | .initializer = initializer, |
| ... | @@ -145,14 +145,14 @@ const ModuleInfo = struct { | ... | @@ -145,14 +145,14 @@ const ModuleInfo = struct { |
| 145 | }, | 145 | }, |
| 146 | .OpFunctionCall => { | 146 | .OpFunctionCall => { |
| 147 | const callee: ResultId = @enumFromInt(inst.operands[2]); | 147 | const callee: ResultId = @enumFromInt(inst.operands[2]); |
| 148 | try calls.put(callee, {}); | 148 | try calls.put(arena, callee, {}); |
| 149 | }, | 149 | }, |
| 150 | .OpFunctionEnd => { | 150 | .OpFunctionEnd => { |
| 151 | const current_function = maybe_current_function orelse { | 151 | const current_function = maybe_current_function orelse { |
| 152 | log.err("encountered OpFunctionEnd without corresponding OpFunction", .{}); | 152 | log.err("encountered OpFunctionEnd without corresponding OpFunction", .{}); |
| 153 | return error.InvalidPhysicalFormat; | 153 | return error.InvalidPhysicalFormat; |
| 154 | }; | 154 | }; |
| 155 | const entry = try functions.getOrPut(current_function); | 155 | const entry = try functions.getOrPut(arena, current_function); |
| 156 | if (entry.found_existing) { | 156 | if (entry.found_existing) { |
| 157 | log.err("Function {f} has duplicate definition", .{current_function}); | 157 | log.err("Function {f} has duplicate definition", .{current_function}); |
| 158 | return error.DuplicateId; | 158 | return error.DuplicateId; |
| ... | @@ -170,7 +170,7 @@ const ModuleInfo = struct { | ... | @@ -170,7 +170,7 @@ const ModuleInfo = struct { |
| 170 | .first_callee = first_callee, | 170 | .first_callee = first_callee, |
| 171 | .return_type = fn_type.return_type, | 171 | .return_type = fn_type.return_type, |
| 172 | .param_types = fn_type.param_types, | 172 | .param_types = fn_type.param_types, |
| 173 | .invocation_globals = try function_invocation_globals.unmanaged.clone(arena), | 173 | .invocation_globals = try function_invocation_globals.clone(arena), |
| 174 | }; | 174 | }; |
| 175 | maybe_current_function = null; | 175 | maybe_current_function = null; |
| 176 | calls.clearRetainingCapacity(); | 176 | calls.clearRetainingCapacity(); |
| ... | @@ -181,7 +181,7 @@ const ModuleInfo = struct { | ... | @@ -181,7 +181,7 @@ const ModuleInfo = struct { |
| 181 | for (result_id_offsets.items) |off| { | 181 | for (result_id_offsets.items) |off| { |
| 182 | const result_id: ResultId = @enumFromInt(inst.operands[off]); | 182 | const result_id: ResultId = @enumFromInt(inst.operands[off]); |
| 183 | if (invocation_globals.contains(result_id)) { | 183 | if (invocation_globals.contains(result_id)) { |
| 184 | try function_invocation_globals.put(result_id, {}); | 184 | try function_invocation_globals.put(arena, result_id, {}); |
| 185 | } | 185 | } |
| 186 | } | 186 | } |
| 187 | } | 187 | } |
| ... | @@ -191,11 +191,11 @@ const ModuleInfo = struct { | ... | @@ -191,11 +191,11 @@ const ModuleInfo = struct { |
| 191 | return error.InvalidPhysicalFormat; | 191 | return error.InvalidPhysicalFormat; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | return ModuleInfo{ | 194 | return .{ |
| 195 | .functions = functions.unmanaged, | 195 | .functions = functions, |
| 196 | .entry_points = entry_points.unmanaged, | 196 | .entry_points = entry_points, |
| 197 | .callee_store = callee_store.items, | 197 | .callee_store = callee_store.items, |
| 198 | .invocation_globals = invocation_globals.unmanaged, | 198 | .invocation_globals = invocation_globals, |
| 199 | }; | 199 | }; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| ... | @@ -583,7 +583,8 @@ const ModuleBuilder = struct { | ... | @@ -583,7 +583,8 @@ const ModuleBuilder = struct { |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | fn emitNewEntryPoints(self: *ModuleBuilder, info: ModuleInfo) !void { | 585 | fn emitNewEntryPoints(self: *ModuleBuilder, info: ModuleInfo) !void { |
| 586 | var all_function_invocation_globals = std.AutoArrayHashMap(ResultId, void).init(self.arena); | 586 | const arena = self.arena; |
| 587 | var all_function_invocation_globals: std.array_hash_map.Auto(ResultId, void) = .empty; | ||
| 587 | 588 | ||
| 588 | for (info.entry_points.keys(), 0..) |func, entry_point_index| { | 589 | for (info.entry_points.keys(), 0..) |func, entry_point_index| { |
| 589 | const fn_info = info.functions.get(func).?; | 590 | const fn_info = info.functions.get(func).?; |
| ... | @@ -593,7 +594,7 @@ const ModuleBuilder = struct { | ... | @@ -593,7 +594,7 @@ const ModuleBuilder = struct { |
| 593 | .param_types = fn_info.param_types, | 594 | .param_types = fn_info.param_types, |
| 594 | }).?; | 595 | }).?; |
| 595 | 596 | ||
| 596 | try self.section.emit(self.arena, .OpFunction, .{ | 597 | try self.section.emit(arena, .OpFunction, .{ |
| 597 | .id_result_type = fn_info.return_type, | 598 | .id_result_type = fn_info.return_type, |
| 598 | .id_result = ep_id, | 599 | .id_result = ep_id, |
| 599 | .function_control = .{}, // TODO: Copy the attributes from the original function maybe? | 600 | .function_control = .{}, // TODO: Copy the attributes from the original function maybe? |
| ... | @@ -604,13 +605,13 @@ const ModuleBuilder = struct { | ... | @@ -604,13 +605,13 @@ const ModuleBuilder = struct { |
| 604 | const params_id_base: u32 = @intFromEnum(self.allocIds(@intCast(fn_info.param_types.len))); | 605 | const params_id_base: u32 = @intFromEnum(self.allocIds(@intCast(fn_info.param_types.len))); |
| 605 | for (fn_info.param_types, 0..) |param_type, i| { | 606 | for (fn_info.param_types, 0..) |param_type, i| { |
| 606 | const id: ResultId = @enumFromInt(params_id_base + @as(u32, @intCast(i))); | 607 | const id: ResultId = @enumFromInt(params_id_base + @as(u32, @intCast(i))); |
| 607 | try self.section.emit(self.arena, .OpFunctionParameter, .{ | 608 | try self.section.emit(arena, .OpFunctionParameter, .{ |
| 608 | .id_result_type = param_type, | 609 | .id_result_type = param_type, |
| 609 | .id_result = id, | 610 | .id_result = id, |
| 610 | }); | 611 | }); |
| 611 | } | 612 | } |
| 612 | 613 | ||
| 613 | try self.section.emit(self.arena, .OpLabel, .{ | 614 | try self.section.emit(arena, .OpLabel, .{ |
| 614 | .id_result = self.allocId(), | 615 | .id_result = self.allocId(), |
| 615 | }); | 616 | }); |
| 616 | 617 | ||
| ... | @@ -619,10 +620,10 @@ const ModuleBuilder = struct { | ... | @@ -619,10 +620,10 @@ const ModuleBuilder = struct { |
| 619 | // Just quickly construct that set here. | 620 | // Just quickly construct that set here. |
| 620 | all_function_invocation_globals.clearRetainingCapacity(); | 621 | all_function_invocation_globals.clearRetainingCapacity(); |
| 621 | for (fn_info.invocation_globals.keys()) |global| { | 622 | for (fn_info.invocation_globals.keys()) |global| { |
| 622 | try all_function_invocation_globals.put(global, {}); | 623 | try all_function_invocation_globals.put(arena, global, {}); |
| 623 | const global_info = info.invocation_globals.get(global).?; | 624 | const global_info = info.invocation_globals.get(global).?; |
| 624 | for (global_info.dependencies.keys()) |dependency| { | 625 | for (global_info.dependencies.keys()) |dependency| { |
| 625 | try all_function_invocation_globals.put(dependency, {}); | 626 | try all_function_invocation_globals.put(arena, dependency, {}); |
| 626 | } | 627 | } |
| 627 | } | 628 | } |
| 628 | 629 | ||
| ... | @@ -632,7 +633,7 @@ const ModuleBuilder = struct { | ... | @@ -632,7 +633,7 @@ const ModuleBuilder = struct { |
| 632 | const global_info = info.invocation_globals.get(global).?; | 633 | const global_info = info.invocation_globals.get(global).?; |
| 633 | 634 | ||
| 634 | const id: ResultId = @enumFromInt(global_id_base + @as(u32, @intCast(i))); | 635 | const id: ResultId = @enumFromInt(global_id_base + @as(u32, @intCast(i))); |
| 635 | try self.section.emit(self.arena, .OpVariable, .{ | 636 | try self.section.emit(arena, .OpVariable, .{ |
| 636 | .id_result_type = global_info.ty, | 637 | .id_result_type = global_info.ty, |
| 637 | .id_result = id, | 638 | .id_result = id, |
| 638 | .storage_class = .function, | 639 | .storage_class = .function, |
| ... | @@ -649,7 +650,7 @@ const ModuleBuilder = struct { | ... | @@ -649,7 +650,7 @@ const ModuleBuilder = struct { |
| 649 | assert(initializer_info.param_types.len == 0); | 650 | assert(initializer_info.param_types.len == 0); |
| 650 | 651 | ||
| 651 | try self.callWithGlobalsAndLinearParams( | 652 | try self.callWithGlobalsAndLinearParams( |
| 652 | all_function_invocation_globals, | 653 | &all_function_invocation_globals, |
| 653 | global_info.initializer, | 654 | global_info.initializer, |
| 654 | initializer_info, | 655 | initializer_info, |
| 655 | global_id_base, | 656 | global_id_base, |
| ... | @@ -659,21 +660,21 @@ const ModuleBuilder = struct { | ... | @@ -659,21 +660,21 @@ const ModuleBuilder = struct { |
| 659 | 660 | ||
| 660 | // Call the main kernel entry | 661 | // Call the main kernel entry |
| 661 | try self.callWithGlobalsAndLinearParams( | 662 | try self.callWithGlobalsAndLinearParams( |
| 662 | all_function_invocation_globals, | 663 | &all_function_invocation_globals, |
| 663 | func, | 664 | func, |
| 664 | fn_info, | 665 | fn_info, |
| 665 | global_id_base, | 666 | global_id_base, |
| 666 | params_id_base, | 667 | params_id_base, |
| 667 | ); | 668 | ); |
| 668 | 669 | ||
| 669 | try self.section.emit(self.arena, .OpReturn, {}); | 670 | try self.section.emit(arena, .OpReturn, {}); |
| 670 | try self.section.emit(self.arena, .OpFunctionEnd, {}); | 671 | try self.section.emit(arena, .OpFunctionEnd, {}); |
| 671 | } | 672 | } |
| 672 | } | 673 | } |
| 673 | 674 | ||
| 674 | fn callWithGlobalsAndLinearParams( | 675 | fn callWithGlobalsAndLinearParams( |
| 675 | self: *ModuleBuilder, | 676 | self: *ModuleBuilder, |
| 676 | all_globals: std.AutoArrayHashMap(ResultId, void), | 677 | all_globals: *const std.array_hash_map.Auto(ResultId, void), |
| 677 | func: ResultId, | 678 | func: ResultId, |
| 678 | callee_info: ModuleInfo.Fn, | 679 | callee_info: ModuleInfo.Fn, |
| 679 | global_id_base: u32, | 680 | global_id_base: u32, |
src/link/Wasm.zig+3-3| ... | @@ -3088,11 +3088,11 @@ fn parseArchive(wasm: *Wasm, obj: link.Input.Object) !void { | ... | @@ -3088,11 +3088,11 @@ fn parseArchive(wasm: *Wasm, obj: link.Input.Object) !void { |
| 3088 | // In this case we must force link all embedded object files within the archive | 3088 | // In this case we must force link all embedded object files within the archive |
| 3089 | // We loop over all symbols, and then group them by offset as the offset | 3089 | // We loop over all symbols, and then group them by offset as the offset |
| 3090 | // notates where the object file starts. | 3090 | // notates where the object file starts. |
| 3091 | var offsets = std.AutoArrayHashMap(u32, void).init(gpa); | 3091 | var offsets: std.array_hash_map.Auto(u32, void) = .empty; |
| 3092 | defer offsets.deinit(); | 3092 | defer offsets.deinit(gpa); |
| 3093 | for (archive.toc.values()) |symbol_offsets| { | 3093 | for (archive.toc.values()) |symbol_offsets| { |
| 3094 | for (symbol_offsets.items) |sym_offset| { | 3094 | for (symbol_offsets.items) |sym_offset| { |
| 3095 | try offsets.put(sym_offset, {}); | 3095 | try offsets.put(gpa, sym_offset, {}); |
| 3096 | } | 3096 | } |
| 3097 | } | 3097 | } |
| 3098 | 3098 |
tools/gen_spirv_spec.zig+11-11| ... | @@ -44,7 +44,7 @@ const StringPairContext = struct { | ... | @@ -44,7 +44,7 @@ const StringPairContext = struct { |
| 44 | } | 44 | } |
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | const OperandKindMap = std.ArrayHashMap(StringPair, OperandKind, StringPairContext, true); | 47 | const OperandKindMap = std.array_hash_map.Custom(StringPair, OperandKind, StringPairContext, true); |
| 48 | 48 | ||
| 49 | /// Khronos made it so that these names are not defined explicitly, so | 49 | /// Khronos made it so that these names are not defined explicitly, so |
| 50 | /// we need to hardcode it (like they did). | 50 | /// we need to hardcode it (like they did). |
| ... | @@ -295,9 +295,9 @@ fn render( | ... | @@ -295,9 +295,9 @@ fn render( |
| 295 | ); | 295 | ); |
| 296 | 296 | ||
| 297 | // Merge the operand kinds from all extensions together. | 297 | // Merge the operand kinds from all extensions together. |
| 298 | var all_operand_kinds = OperandKindMap.init(arena); | 298 | var all_operand_kinds: OperandKindMap = .empty; |
| 299 | for (registry.operand_kinds) |kind| { | 299 | for (registry.operand_kinds) |kind| { |
| 300 | try all_operand_kinds.putNoClobber(.{ "core", kind.kind }, kind); | 300 | try all_operand_kinds.putNoClobber(arena, .{ "core", kind.kind }, kind); |
| 301 | } | 301 | } |
| 302 | for (extensions) |ext| { | 302 | for (extensions) |ext| { |
| 303 | // Note: extensions may define the same operand kind, with different | 303 | // Note: extensions may define the same operand kind, with different |
| ... | @@ -305,11 +305,11 @@ fn render( | ... | @@ -305,11 +305,11 @@ fn render( |
| 305 | // using the name of the extension. This is similar to what | 305 | // using the name of the extension. This is similar to what |
| 306 | // the official headers do. | 306 | // the official headers do. |
| 307 | 307 | ||
| 308 | try all_operand_kinds.ensureUnusedCapacity(ext.spec.operand_kinds.len); | 308 | try all_operand_kinds.ensureUnusedCapacity(arena, ext.spec.operand_kinds.len); |
| 309 | for (ext.spec.operand_kinds) |kind| { | 309 | for (ext.spec.operand_kinds) |kind| { |
| 310 | var new_kind = kind; | 310 | var new_kind = kind; |
| 311 | new_kind.kind = try std.mem.join(arena, ".", &.{ ext.name, kind.kind }); | 311 | new_kind.kind = try std.mem.join(arena, ".", &.{ ext.name, kind.kind }); |
| 312 | try all_operand_kinds.putNoClobber(.{ ext.name, kind.kind }, new_kind); | 312 | try all_operand_kinds.putNoClobber(arena, .{ ext.name, kind.kind }, new_kind); |
| 313 | } | 313 | } |
| 314 | } | 314 | } |
| 315 | 315 | ||
| ... | @@ -411,11 +411,11 @@ fn renderInstructionsCase( | ... | @@ -411,11 +411,11 @@ fn renderInstructionsCase( |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | fn renderClass(arena: Allocator, writer: *std.Io.Writer, instructions: []const Instruction) !void { | 413 | fn renderClass(arena: Allocator, writer: *std.Io.Writer, instructions: []const Instruction) !void { |
| 414 | var class_map = std.StringArrayHashMap(void).init(arena); | 414 | var class_map: std.array_hash_map.String(void) = .empty; |
| 415 | 415 | ||
| 416 | for (instructions) |inst| { | 416 | for (instructions) |inst| { |
| 417 | if (std.mem.eql(u8, inst.class.?, "@exclude")) continue; | 417 | if (std.mem.eql(u8, inst.class.?, "@exclude")) continue; |
| 418 | try class_map.put(inst.class.?, {}); | 418 | try class_map.put(arena, inst.class.?, {}); |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | try writer.writeAll("pub const Class = enum {\n"); | 421 | try writer.writeAll("pub const Class = enum {\n"); |
| ... | @@ -538,8 +538,8 @@ fn renderOpcodes( | ... | @@ -538,8 +538,8 @@ fn renderOpcodes( |
| 538 | instructions: []const Instruction, | 538 | instructions: []const Instruction, |
| 539 | extended_structs: ExtendedStructSet, | 539 | extended_structs: ExtendedStructSet, |
| 540 | ) !void { | 540 | ) !void { |
| 541 | var inst_map = std.AutoArrayHashMap(u32, usize).init(arena); | 541 | var inst_map: std.array_hash_map.Auto(u32, usize) = .empty; |
| 542 | try inst_map.ensureTotalCapacity(instructions.len); | 542 | try inst_map.ensureTotalCapacity(arena, instructions.len); |
| 543 | 543 | ||
| 544 | var aliases = std.array_list.Managed(struct { inst: usize, alias: usize }).init(arena); | 544 | var aliases = std.array_list.Managed(struct { inst: usize, alias: usize }).init(arena); |
| 545 | try aliases.ensureTotalCapacity(instructions.len); | 545 | try aliases.ensureTotalCapacity(instructions.len); |
| ... | @@ -653,8 +653,8 @@ fn renderValueEnum( | ... | @@ -653,8 +653,8 @@ fn renderValueEnum( |
| 653 | ) !void { | 653 | ) !void { |
| 654 | const enumerants = enumeration.enumerants orelse return error.InvalidRegistry; | 654 | const enumerants = enumeration.enumerants orelse return error.InvalidRegistry; |
| 655 | 655 | ||
| 656 | var enum_map = std.AutoArrayHashMap(u32, usize).init(arena); | 656 | var enum_map: std.array_hash_map.Auto(u32, usize) = .empty; |
| 657 | try enum_map.ensureTotalCapacity(enumerants.len); | 657 | try enum_map.ensureTotalCapacity(arena, enumerants.len); |
| 658 | 658 | ||
| 659 | var aliases = std.array_list.Managed(struct { enumerant: usize, alias: usize }).init(arena); | 659 | var aliases = std.array_list.Managed(struct { enumerant: usize, alias: usize }).init(arena); |
| 660 | try aliases.ensureTotalCapacity(enumerants.len); | 660 | try aliases.ensureTotalCapacity(enumerants.len); |
tools/gen_stubs.zig+10-14| ... | @@ -274,8 +274,8 @@ const MultiSym = struct { | ... | @@ -274,8 +274,8 @@ const MultiSym = struct { |
| 274 | 274 | ||
| 275 | const Parse = struct { | 275 | const Parse = struct { |
| 276 | arena: mem.Allocator, | 276 | arena: mem.Allocator, |
| 277 | sym_table: *std.StringArrayHashMap(MultiSym), | 277 | sym_table: *std.array_hash_map.String(MultiSym), |
| 278 | sections: *std.StringArrayHashMap(void), | 278 | sections: *std.array_hash_map.String(void), |
| 279 | elf_bytes: []align(@alignOf(elf.Elf64_Ehdr)) u8, | 279 | elf_bytes: []align(@alignOf(elf.Elf64_Ehdr)) u8, |
| 280 | header: elf.Header, | 280 | header: elf.Header, |
| 281 | arch: Arch, | 281 | arch: Arch, |
| ... | @@ -289,13 +289,11 @@ pub fn main(init: std.process.Init) !void { | ... | @@ -289,13 +289,11 @@ pub fn main(init: std.process.Init) !void { |
| 289 | 289 | ||
| 290 | var build_all_dir = try Io.Dir.cwd().openDir(io, build_all_path, .{}); | 290 | var build_all_dir = try Io.Dir.cwd().openDir(io, build_all_path, .{}); |
| 291 | 291 | ||
| 292 | var sym_table = std.StringArrayHashMap(MultiSym).init(arena); | 292 | var sym_table: std.array_hash_map.String(MultiSym) = .empty; |
| 293 | var sections = std.StringArrayHashMap(void).init(arena); | 293 | var sections: std.array_hash_map.String(void) = .empty; |
| 294 | 294 | ||
| 295 | for (arches) |arch| { | 295 | for (arches) |arch| { |
| 296 | const libc_so_path = try std.fmt.allocPrint(arena, "{s}/lib/libc.so", .{ | 296 | const libc_so_path = try std.fmt.allocPrint(arena, "{t}/lib/libc.so", .{arch}); |
| 297 | @tagName(arch), | ||
| 298 | }); | ||
| 299 | 297 | ||
| 300 | // Read the ELF header. | 298 | // Read the ELF header. |
| 301 | const elf_bytes = build_all_dir.readFileAllocOptions( | 299 | const elf_bytes = build_all_dir.readFileAllocOptions( |
| ... | @@ -306,9 +304,7 @@ pub fn main(init: std.process.Init) !void { | ... | @@ -306,9 +304,7 @@ pub fn main(init: std.process.Init) !void { |
| 306 | .of(elf.Elf64_Ehdr), | 304 | .of(elf.Elf64_Ehdr), |
| 307 | null, | 305 | null, |
| 308 | ) catch |err| { | 306 | ) catch |err| { |
| 309 | std.debug.panic("unable to read '{s}/{s}': {s}", .{ | 307 | std.debug.panic("unable to read '{s}/{s}': {t}", .{ build_all_path, libc_so_path, err }); |
| 310 | build_all_path, libc_so_path, @errorName(err), | ||
| 311 | }); | ||
| 312 | }; | 308 | }; |
| 313 | var stream: std.Io.Reader = .fixed(elf_bytes); | 309 | var stream: std.Io.Reader = .fixed(elf_bytes); |
| 314 | const header = try elf.Header.read(&stream); | 310 | const header = try elf.Header.read(&stream); |
| ... | @@ -359,8 +355,8 @@ pub fn main(init: std.process.Init) !void { | ... | @@ -359,8 +355,8 @@ pub fn main(init: std.process.Init) !void { |
| 359 | 355 | ||
| 360 | // Sort the symbols for deterministic output and cleaner vcs diffs. | 356 | // Sort the symbols for deterministic output and cleaner vcs diffs. |
| 361 | const SymTableSort = struct { | 357 | const SymTableSort = struct { |
| 362 | sections: *const std.StringArrayHashMap(void), | 358 | sections: *const std.array_hash_map.String(void), |
| 363 | sym_table: *const std.StringArrayHashMap(MultiSym), | 359 | sym_table: *const std.array_hash_map.String(MultiSym), |
| 364 | 360 | ||
| 365 | /// Sort first by section name, then by symbol name | 361 | /// Sort first by section name, then by symbol name |
| 366 | pub fn lessThan(ctx: @This(), index_a: usize, index_b: usize) bool { | 362 | pub fn lessThan(ctx: @This(), index_a: usize, index_b: usize) bool { |
| ... | @@ -580,7 +576,7 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: std.builtin.End | ... | @@ -580,7 +576,7 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: std.builtin.End |
| 580 | if (mem.eql(u8, sh_name, ".dynsym")) { | 576 | if (mem.eql(u8, sh_name, ".dynsym")) { |
| 581 | dynsym_index = @as(u16, @intCast(i)); | 577 | dynsym_index = @as(u16, @intCast(i)); |
| 582 | } | 578 | } |
| 583 | const gop = try parse.sections.getOrPut(sh_name); | 579 | const gop = try parse.sections.getOrPut(arena, sh_name); |
| 584 | section_index_map[i] = @as(u16, @intCast(gop.index)); | 580 | section_index_map[i] = @as(u16, @intCast(gop.index)); |
| 585 | } | 581 | } |
| 586 | if (dynsym_index == 0) @panic("did not find the .dynsym section"); | 582 | if (dynsym_index == 0) @panic("did not find the .dynsym section"); |
| ... | @@ -653,7 +649,7 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: std.builtin.End | ... | @@ -653,7 +649,7 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: std.builtin.End |
| 653 | }, | 649 | }, |
| 654 | } | 650 | } |
| 655 | 651 | ||
| 656 | const gop = try parse.sym_table.getOrPut(name); | 652 | const gop = try parse.sym_table.getOrPut(arena, name); |
| 657 | if (gop.found_existing) { | 653 | if (gop.found_existing) { |
| 658 | if (gop.value_ptr.section != section_index_map[this_section]) { | 654 | if (gop.value_ptr.section != section_index_map[this_section]) { |
| 659 | const sh_name = mem.sliceTo(shstrtab[s(shdrs[this_section].sh_name)..], 0); | 655 | const sh_name = mem.sliceTo(shstrtab[s(shdrs[this_section].sh_name)..], 0); |
tools/process_headers.zig+4-4| ... | @@ -130,7 +130,7 @@ const Contents = struct { | ... | @@ -130,7 +130,7 @@ const Contents = struct { |
| 130 | }; | 130 | }; |
| 131 | 131 | ||
| 132 | const HashToContents = std.StringHashMap(Contents); | 132 | const HashToContents = std.StringHashMap(Contents); |
| 133 | const TargetToHash = std.StringArrayHashMap([]const u8); | 133 | const TargetToHash = std.array_hash_map.String([]const u8); |
| 134 | const PathTable = std.StringHashMap(*TargetToHash); | 134 | const PathTable = std.StringHashMap(*TargetToHash); |
| 135 | 135 | ||
| 136 | const LibCVendor = enum { | 136 | const LibCVendor = enum { |
| ... | @@ -317,7 +317,7 @@ pub fn main(init: std.process.Init) !void { | ... | @@ -317,7 +317,7 @@ pub fn main(init: std.process.Init) !void { |
| 317 | const path_gop = try path_table.getOrPut(rel_path); | 317 | const path_gop = try path_table.getOrPut(rel_path); |
| 318 | const target_to_hash = if (path_gop.found_existing) path_gop.value_ptr.* else blk: { | 318 | const target_to_hash = if (path_gop.found_existing) path_gop.value_ptr.* else blk: { |
| 319 | const ptr = try arena.create(TargetToHash); | 319 | const ptr = try arena.create(TargetToHash); |
| 320 | ptr.* = TargetToHash.init(arena); | 320 | ptr.* = .empty; |
| 321 | path_gop.value_ptr.* = ptr; | 321 | path_gop.value_ptr.* = ptr; |
| 322 | break :blk ptr; | 322 | break :blk ptr; |
| 323 | }; | 323 | }; |
| ... | @@ -327,14 +327,14 @@ pub fn main(init: std.process.Init) !void { | ... | @@ -327,14 +327,14 @@ pub fn main(init: std.process.Init) !void { |
| 327 | // such cases, we manually patch the affected header after processing, so it's fine that | 327 | // such cases, we manually patch the affected header after processing, so it's fine that |
| 328 | // only one header wins here. | 328 | // only one header wins here. |
| 329 | if (libc_target.dest != null) { | 329 | if (libc_target.dest != null) { |
| 330 | const hash_gop = try target_to_hash.getOrPut(dest_target); | 330 | const hash_gop = try target_to_hash.getOrPut(arena, dest_target); |
| 331 | if (hash_gop.found_existing) std.debug.print("overwrote: {s} {s} {s}\n", .{ | 331 | if (hash_gop.found_existing) std.debug.print("overwrote: {s} {s} {s}\n", .{ |
| 332 | libc_dir, | 332 | libc_dir, |
| 333 | rel_path, | 333 | rel_path, |
| 334 | dest_target, | 334 | dest_target, |
| 335 | }) else hash_gop.value_ptr.* = hash; | 335 | }) else hash_gop.value_ptr.* = hash; |
| 336 | } else { | 336 | } else { |
| 337 | try target_to_hash.putNoClobber(dest_target, hash); | 337 | try target_to_hash.putNoClobber(arena, dest_target, hash); |
| 338 | } | 338 | } |
| 339 | }, | 339 | }, |
| 340 | else => std.debug.print("warning: weird file: {s}\n", .{full_path}), | 340 | else => std.debug.print("warning: weird file: {s}\n", .{full_path}), |
tools/update-linux-headers.zig+3-3| ... | @@ -138,7 +138,7 @@ const Contents = struct { | ... | @@ -138,7 +138,7 @@ const Contents = struct { |
| 138 | }; | 138 | }; |
| 139 | 139 | ||
| 140 | const HashToContents = std.StringHashMap(Contents); | 140 | const HashToContents = std.StringHashMap(Contents); |
| 141 | const TargetToHash = std.ArrayHashMap(DestTarget, []const u8, DestTarget.HashContext, true); | 141 | const TargetToHash = std.array_hash_map.Custom(DestTarget, []const u8, DestTarget.HashContext, true); |
| 142 | const PathTable = std.StringHashMap(*TargetToHash); | 142 | const PathTable = std.StringHashMap(*TargetToHash); |
| 143 | 143 | ||
| 144 | pub fn main(init: std.process.Init) !void { | 144 | pub fn main(init: std.process.Init) !void { |
| ... | @@ -239,11 +239,11 @@ pub fn main(init: std.process.Init) !void { | ... | @@ -239,11 +239,11 @@ pub fn main(init: std.process.Init) !void { |
| 239 | const path_gop = try path_table.getOrPut(rel_path); | 239 | const path_gop = try path_table.getOrPut(rel_path); |
| 240 | const target_to_hash = if (path_gop.found_existing) path_gop.value_ptr.* else blk: { | 240 | const target_to_hash = if (path_gop.found_existing) path_gop.value_ptr.* else blk: { |
| 241 | const ptr = try arena.create(TargetToHash); | 241 | const ptr = try arena.create(TargetToHash); |
| 242 | ptr.* = TargetToHash.init(arena); | 242 | ptr.* = .empty; |
| 243 | path_gop.value_ptr.* = ptr; | 243 | path_gop.value_ptr.* = ptr; |
| 244 | break :blk ptr; | 244 | break :blk ptr; |
| 245 | }; | 245 | }; |
| 246 | try target_to_hash.putNoClobber(dest_target, hash); | 246 | try target_to_hash.putNoClobber(arena, dest_target, hash); |
| 247 | }, | 247 | }, |
| 248 | else => std.debug.print("warning: weird file: {s}\n", .{full_path}), | 248 | else => std.debug.print("warning: weird file: {s}\n", .{full_path}), |
| 249 | } | 249 | } |