authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-09 01:04:13-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-09 05:47:13-04:00
log151c06cce40f33649fa96937d53926a7769491b9
tree3d4ff833e135bebaebffdc1d4d687d9ba88fbeed
parent66084b6c3f78349a7730c02614125185df8b6672

std.mem.sliceAsBytes: support arrays of zero-bit types

This makes `std.ArrayListUnmanaged(void)` usable.

1 files changed, 14 insertions(+), 7 deletions(-)

lib/std/mem.zig+14-7
...@@ -4138,23 +4138,24 @@ test "bytesAsSlice preserves pointer attributes" {...@@ -4138,23 +4138,24 @@ test "bytesAsSlice preserves pointer attributes" {
4138 try testing.expectEqual(in.alignment, out.alignment);4138 try testing.expectEqual(in.alignment, out.alignment);
4139}4139}
41404140
4141fn SliceAsBytesReturnType(comptime sliceType: type) type {4141fn SliceAsBytesReturnType(comptime Slice: type) type {
4142 if (!trait.isSlice(sliceType) and !trait.isPtrTo(.Array)(sliceType)) {4142 if (!trait.isSlice(Slice) and !trait.isPtrTo(.Array)(Slice)) {
4143 @compileError("expected []T or *[_]T, passed " ++ @typeName(sliceType));4143 @compileError("expected []T or *[_]T, passed " ++ @typeName(Slice));
4144 }4144 }
41454145
4146 return CopyPtrAttrs(sliceType, .Slice, u8);4146 return CopyPtrAttrs(Slice, .Slice, u8);
4147}4147}
41484148
4149/// Given a slice, returns a slice of the underlying bytes, preserving pointer attributes.4149/// Given a slice, returns a slice of the underlying bytes, preserving pointer attributes.
4150pub fn sliceAsBytes(slice: anytype) SliceAsBytesReturnType(@TypeOf(slice)) {4150pub fn sliceAsBytes(slice: anytype) SliceAsBytesReturnType(@TypeOf(slice)) {
4151 const Slice = @TypeOf(slice);4151 const Slice = @TypeOf(slice);
41524152
4153 // a slice of zero-bit values always occupies zero bytes
4154 if (@sizeOf(meta.Elem(Slice)) == 0) return &[0]u8{};
4155
4153 // let's not give an undefined pointer to @ptrCast4156 // let's not give an undefined pointer to @ptrCast
4154 // it may be equal to zero and fail a null check4157 // it may be equal to zero and fail a null check
4155 if (slice.len == 0 and comptime meta.sentinel(Slice) == null) {4158 if (slice.len == 0 and comptime meta.sentinel(Slice) == null) return &[0]u8{};
4156 return &[0]u8{};
4157 }
41584159
4159 const cast_target = CopyPtrAttrs(Slice, .Many, u8);4160 const cast_target = CopyPtrAttrs(Slice, .Many, u8);
41604161
...@@ -4177,6 +4178,12 @@ test "sliceAsBytes with sentinel slice" {...@@ -4177,6 +4178,12 @@ test "sliceAsBytes with sentinel slice" {
4177 try testing.expect(bytes.len == 0);4178 try testing.expect(bytes.len == 0);
4178}4179}
41794180
4181test "sliceAsBytes with zero-bit element type" {
4182 const lots_of_nothing = [1]void{{}} ** 10_000;
4183 const bytes = sliceAsBytes(&lots_of_nothing);
4184 try testing.expect(bytes.len == 0);
4185}
4186
4180test "sliceAsBytes packed struct at runtime and comptime" {4187test "sliceAsBytes packed struct at runtime and comptime" {
4181 const Foo = packed struct {4188 const Foo = packed struct {
4182 a: u4,4189 a: u4,