aboutsummaryrefslogtreecommitdiff
path: root/lib/std/multi_array_list.zig
diff options
context:
space:
mode:
authorriverbl <94326797+riverbl@users.noreply.github.com>2022-01-24 15:31:27 +0000
committerGitHub <noreply@github.com>2022-01-24 17:31:27 +0200
commit1f10cf4edf2b645e63dedc42f5d7475914bf2311 (patch)
treefdc16957a46c7f8c81035e95e189e16845bea5bb /lib/std/multi_array_list.zig
parentc54a7ca4b25a0ffe080a80fb19986142c98b124e (diff)
downloadzig-1f10cf4edf2b645e63dedc42f5d7475914bf2311.tar.gz
zig-1f10cf4edf2b645e63dedc42f5d7475914bf2311.zip
MultiArrayList: Fix error when struct is 0 sized
Also fixes error with ArrayHashMap when both key and value are 0 sized
Diffstat (limited to 'lib/std/multi_array_list.zig')
-rw-r--r--lib/std/multi_array_list.zig63
1 files changed, 57 insertions, 6 deletions
diff --git a/lib/std/multi_array_list.zig b/lib/std/multi_array_list.zig
index 47d12884df..d5cbaaa88e 100644
--- a/lib/std/multi_array_list.zig
+++ b/lib/std/multi_array_list.zig
@@ -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,
@@ -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,
@@ -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 {
@@ -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,
);
@@ -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)];
}
@@ -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));
+}