Commit 8ea0a00f40
Changed files (3)
src-self-hosted
lib/std/mem.zig
@@ -1829,21 +1829,19 @@ fn SliceAsBytesReturnType(comptime sliceType: type) type {
}
pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {
- const actualSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(slice))) slice[0..] else slice;
- const actualSliceTypeInfo = @typeInfo(@TypeOf(actualSlice)).Pointer;
+ const Slice = @TypeOf(slice);
// let's not give an undefined pointer to @ptrCast
// it may be equal to zero and fail a null check
- if (actualSlice.len == 0 and actualSliceTypeInfo.sentinel == null) {
+ if (slice.len == 0 and comptime meta.sentinel(Slice) == null) {
return &[0]u8{};
}
- const sliceType = @TypeOf(actualSlice);
- const alignment = comptime meta.alignment(sliceType);
+ const alignment = comptime meta.alignment(Slice);
- const castTarget = if (comptime trait.isConstPtr(sliceType)) [*]align(alignment) const u8 else [*]align(alignment) u8;
+ const cast_target = if (comptime trait.isConstPtr(Slice)) [*]align(alignment) const u8 else [*]align(alignment) u8;
- return @ptrCast(castTarget, actualSlice.ptr)[0 .. actualSlice.len * @sizeOf(comptime meta.Child(sliceType))];
+ return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Child(Slice))];
}
test "sliceAsBytes" {
lib/std/meta.zig
@@ -115,30 +115,37 @@ test "std.meta.Child" {
testing.expect(Child(?u8) == u8);
}
-/// Given a type with a sentinel e.g. `[:0]u8`, returns the sentinel
-pub fn Sentinel(comptime T: type) Child(T) {
- // comptime asserts that ptr has a sentinel
+/// Given a type which can have a sentinel e.g. `[:0]u8`, returns the sentinel value,
+/// or `null` if there is not one.
+/// Types which cannot possibly have a sentinel will be a compile error.
+pub fn sentinel(comptime T: type) ?Child(T) {
switch (@typeInfo(T)) {
- .Array => |arrayInfo| {
- return comptime arrayInfo.sentinel.?;
- },
- .Pointer => |ptrInfo| {
- switch (ptrInfo.size) {
- .Many, .Slice => {
- return comptime ptrInfo.sentinel.?;
+ .Array => |info| return info.sentinel,
+ .Pointer => |info| {
+ switch (info.size) {
+ .Many, .Slice => return info.sentinel,
+ .One => switch (info.child) {
+ .Array => |array_info| return array_info.sentinel,
+ else => {},
},
else => {},
}
},
else => {},
}
- @compileError("not a sentinel type, found '" ++ @typeName(T) ++ "'");
+ @compileError("type '" ++ @typeName(T) ++ "' cannot possibly have a sentinel");
}
-test "std.meta.Sentinel" {
- testing.expectEqual(@as(u8, 0), Sentinel([:0]u8));
- testing.expectEqual(@as(u8, 0), Sentinel([*:0]u8));
- testing.expectEqual(@as(u8, 0), Sentinel([5:0]u8));
+test "std.meta.sentinel" {
+ testing.expectEqual(@as(u8, 0), sentinel([:0]u8).?);
+ testing.expectEqual(@as(u8, 0), sentinel([*:0]u8).?);
+ testing.expectEqual(@as(u8, 0), sentinel([5:0]u8).?);
+ testing.expectEqual(@as(u8, 0), sentinel(*const [5:0]u8).?);
+
+ testing.expect(sentinel([]u8) == null);
+ testing.expect(sentinel([*]u8) == null);
+ testing.expect(sentinel([5]u8) == null);
+ testing.expect(sentinel(*const [5]u8) == null);
}
pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout {
src-self-hosted/translate_c.zig
@@ -1744,20 +1744,18 @@ fn writeEscapedString(buf: []u8, s: []const u8) void {
// Returns either a string literal or a slice of `buf`.
fn escapeChar(c: u8, char_buf: *[4]u8) []const u8 {
return switch (c) {
- '\"' => "\\\""[0..],
- '\'' => "\\'"[0..],
- '\\' => "\\\\"[0..],
- '\n' => "\\n"[0..],
- '\r' => "\\r"[0..],
- '\t' => "\\t"[0..],
- else => {
- // Handle the remaining escapes Zig doesn't support by turning them
- // into their respective hex representation
- if (std.ascii.isCntrl(c))
- return std.fmt.bufPrint(char_buf[0..], "\\x{x:0<2}", .{c}) catch unreachable
- else
- return std.fmt.bufPrint(char_buf[0..], "{c}", .{c}) catch unreachable;
- },
+ '\"' => "\\\"",
+ '\'' => "\\'",
+ '\\' => "\\\\",
+ '\n' => "\\n",
+ '\r' => "\\r",
+ '\t' => "\\t",
+ // Handle the remaining escapes Zig doesn't support by turning them
+ // into their respective hex representation
+ else => if (std.ascii.isCntrl(c))
+ std.fmt.bufPrint(char_buf, "\\x{x:0<2}", .{c}) catch unreachable
+ else
+ std.fmt.bufPrint(char_buf, "{c}", .{c}) catch unreachable,
};
}