authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-27 20:57:58-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:34-07:00
log0d48cbb822551c07ac987c9c2e20d3251ee3a09c
treea41ed8a676845dd4cf43810a425bae9fee2ee63b
parent378b790ee20fa64c549d114204dafc19d1e33362

std.process.Environ.Map: add putAll and clearRetainingCapacity


1 files changed, 27 insertions(+), 3 deletions(-)

lib/std/process/Environ.zig+27-3
...@@ -96,6 +96,7 @@ pub const WindowsBlock = struct {...@@ -96,6 +96,7 @@ pub const WindowsBlock = struct {
96 }96 }
97};97};
9898
99/// Each key and each value are allocated independently and owned by this data structure.
99pub const Map = struct {100pub const Map = struct {
100 array_hash_map: ArrayHashMap,101 array_hash_map: ArrayHashMap,
101 allocator: Allocator,102 allocator: Allocator,
...@@ -340,9 +341,6 @@ pub const Map = struct {...@@ -340,9 +341,6 @@ pub const Map = struct {
340 /// Returns a full copy of `em` allocated with `gpa`, which is not necessarily341 /// Returns a full copy of `em` allocated with `gpa`, which is not necessarily
341 /// the same allocator used to allocate `em`.342 /// the same allocator used to allocate `em`.
342 pub fn clone(m: *const Map, gpa: Allocator) Allocator.Error!Map {343 pub fn clone(m: *const Map, gpa: Allocator) Allocator.Error!Map {
343 // Since we need to dupe the keys and values, the only way for error handling to not be a
344 // nightmare is to add keys to an empty map one-by-one. This could be avoided if this
345 // abstraction were a bit less... OOP-esque.
346 var new: Map = .init(gpa);344 var new: Map = .init(gpa);
347 errdefer new.deinit();345 errdefer new.deinit();
348 try new.array_hash_map.ensureUnusedCapacity(gpa, m.array_hash_map.count());346 try new.array_hash_map.ensureUnusedCapacity(gpa, m.array_hash_map.count());
...@@ -352,6 +350,32 @@ pub const Map = struct {...@@ -352,6 +350,32 @@ pub const Map = struct {
352 return new;350 return new;
353 }351 }
354352
353 /// Adds all the key-value pairs from `other` into this `m`.
354 pub fn putAll(m: *Map, other: *const Map) Allocator.Error!void {
355 const gpa = m.allocator;
356 try m.array_hash_map.ensureUnusedCapacity(gpa, other.array_hash_map.count());
357 const start = m.count();
358 errdefer while (m.array_hash_map.count() > start) {
359 const kv = m.array_hash_map.pop().?;
360 gpa.free(kv.key);
361 gpa.free(kv.value);
362 };
363 for (other.array_hash_map.keys(), other.array_hash_map.values()) |key, value| {
364 try m.put(key, value);
365 }
366 }
367
368 /// Set the length to zero, freeing all key and value memory, not freeing
369 /// the allocation for the entries.
370 pub fn clearRetainingCapacity(m: *Map) void {
371 const gpa = m.allocator;
372 for (m.array_hash_map.keys(), m.array_hash_map.values()) |k, v| {
373 gpa.free(k);
374 gpa.free(v);
375 }
376 m.array_hash_map.clearRetainingCapacity();
377 }
378
355 /// Creates a null-delimited environment variable block in the format379 /// Creates a null-delimited environment variable block in the format
356 /// expected by POSIX, from a hash map plus options.380 /// expected by POSIX, from a hash map plus options.
357 pub fn createPosixBlock(381 pub fn createPosixBlock(