Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions lib/std/array_hash_map.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2215,6 +2215,35 @@ test "auto store_hash" {
try testing.expect(meta.fieldInfo(HasExpensiveEqlUn.Data, .hash).field_type != void);
}

test "0 sized key" {
var map = AutoArrayHashMap(u0, i32).init(std.testing.allocator);
defer map.deinit();

try testing.expectEqual(map.get(0), null);

try map.put(0, 5);
try testing.expectEqual(map.get(0), 5);

try map.put(0, 10);
try testing.expectEqual(map.get(0), 10);

try testing.expectEqual(map.swapRemove(0), true);
try testing.expectEqual(map.get(0), null);
}

test "0 sized key and 0 sized value" {
var map = AutoArrayHashMap(u0, u0).init(std.testing.allocator);
defer map.deinit();

try testing.expectEqual(map.get(0), null);

try map.put(0, 0);
try testing.expectEqual(map.get(0), 0);

try testing.expectEqual(map.swapRemove(0), true);
try testing.expectEqual(map.get(0), null);
}

pub fn getHashPtrAddrFn(comptime K: type, comptime Context: type) (fn (Context, K) u32) {
return struct {
fn hash(ctx: Context, key: K) u32 {
Expand Down
63 changes: 57 additions & 6 deletions lib/std/multi_array_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ const testing = std.testing;
/// `.items(.<field_name>)` to obtain a slice of field values.
pub fn MultiArrayList(comptime S: type) type {
return struct {
bytes: [*]align(@alignOf(S)) u8 = undefined,
const alignS = if (@alignOf(S) == 0) 1 else @alignOf(S);

bytes: [*]align(alignS) u8 = undefined,
len: usize = 0,
capacity: usize = 0,

Expand Down Expand Up @@ -50,8 +52,8 @@ pub fn MultiArrayList(comptime S: type) type {
return .{};
}
const unaligned_ptr = self.ptrs[sizes.fields[0]];
const aligned_ptr = @alignCast(@alignOf(S), unaligned_ptr);
const casted_ptr = @ptrCast([*]align(@alignOf(S)) u8, aligned_ptr);
const aligned_ptr = @alignCast(alignS, unaligned_ptr);
const casted_ptr = @ptrCast([*]align(alignS) u8, aligned_ptr);
return .{
.bytes = casted_ptr,
.len = self.len,
Expand Down Expand Up @@ -261,7 +263,7 @@ pub fn MultiArrayList(comptime S: type) type {

const other_bytes = gpa.allocAdvanced(
u8,
@alignOf(S),
alignS,
capacityInBytes(new_len),
.exact,
) catch {
Expand Down Expand Up @@ -339,7 +341,7 @@ pub fn MultiArrayList(comptime S: type) type {
assert(new_capacity >= self.len);
const new_bytes = try gpa.allocAdvanced(
u8,
@alignOf(S),
alignS,
capacityInBytes(new_capacity),
.exact,
);
Expand Down Expand Up @@ -398,7 +400,7 @@ pub fn MultiArrayList(comptime S: type) type {
return @reduce(.Add, capacity_vector * sizes_vector);
}

fn allocatedBytes(self: Self) []align(@alignOf(S)) u8 {
fn allocatedBytes(self: Self) []align(alignS) u8 {
return self.bytes[0..capacityInBytes(self.capacity)];
}

Expand Down Expand Up @@ -621,3 +623,52 @@ test "insert elements" {
try testing.expectEqualSlices(u8, &[_]u8{ 1, 2 }, list.items(.a));
try testing.expectEqualSlices(u32, &[_]u32{ 2, 3 }, list.items(.b));
}

test "0 sized struct field" {
const ally = testing.allocator;

const Foo = struct {
a: u0,
b: f32,
};

var list = MultiArrayList(Foo){};
defer list.deinit(ally);

try testing.expectEqualSlices(u0, &[_]u0{}, list.items(.a));
try testing.expectEqualSlices(f32, &[_]f32{}, list.items(.b));

try list.append(ally, .{ .a = 0, .b = 42.0 });
try testing.expectEqualSlices(u0, &[_]u0{0}, list.items(.a));
try testing.expectEqualSlices(f32, &[_]f32{42.0}, list.items(.b));

try list.insert(ally, 0, .{ .a = 0, .b = -1.0 });
try testing.expectEqualSlices(u0, &[_]u0{ 0, 0 }, list.items(.a));
try testing.expectEqualSlices(f32, &[_]f32{ -1.0, 42.0 }, list.items(.b));

list.swapRemove(list.len - 1);
try testing.expectEqualSlices(u0, &[_]u0{0}, list.items(.a));
try testing.expectEqualSlices(f32, &[_]f32{-1.0}, list.items(.b));
}

test "0 sized struct" {
const ally = testing.allocator;

const Foo = struct {
a: u0,
};

var list = MultiArrayList(Foo){};
defer list.deinit(ally);

try testing.expectEqualSlices(u0, &[_]u0{}, list.items(.a));

try list.append(ally, .{ .a = 0 });
try testing.expectEqualSlices(u0, &[_]u0{0}, list.items(.a));

try list.insert(ally, 0, .{ .a = 0 });
try testing.expectEqualSlices(u0, &[_]u0{ 0, 0 }, list.items(.a));

list.swapRemove(list.len - 1);
try testing.expectEqualSlices(u0, &[_]u0{0}, list.items(.a));
}