authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-17 18:54:09-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-19 09:53:54-04:00
log8ea0a00f406bb04c08a8fa4471c3a3895f82b24a
treedb67660d2496e6b501ebb67bec9c2d4907e3fa51
parent8d0ac6dc4d32daea3561e7de8eeee9ce34d2c5cb
signaturelock-open Commit is signed but in an unrecognized format.

improve std lib code for the new semantics


3 files changed, 39 insertions(+), 36 deletions(-)

lib/std/mem.zig+5-7
......@@ -1829,21 +1829,19 @@ fn SliceAsBytesReturnType(comptime sliceType: type) type {
18291829}
18301830
18311831pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {
1832 const actualSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(slice))) slice[0..] else slice;
1833 const actualSliceTypeInfo = @typeInfo(@TypeOf(actualSlice)).Pointer;
1832 const Slice = @TypeOf(slice);
18341833
18351834 // let's not give an undefined pointer to @ptrCast
18361835 // it may be equal to zero and fail a null check
1837 if (actualSlice.len == 0 and actualSliceTypeInfo.sentinel == null) {
1836 if (slice.len == 0 and comptime meta.sentinel(Slice) == null) {
18381837 return &[0]u8{};
18391838 }
18401839
1841 const sliceType = @TypeOf(actualSlice);
1842 const alignment = comptime meta.alignment(sliceType);
1840 const alignment = comptime meta.alignment(Slice);
18431841
1844 const castTarget = if (comptime trait.isConstPtr(sliceType)) [*]align(alignment) const u8 else [*]align(alignment) u8;
1842 const cast_target = if (comptime trait.isConstPtr(Slice)) [*]align(alignment) const u8 else [*]align(alignment) u8;
18451843
1846 return @ptrCast(castTarget, actualSlice.ptr)[0 .. actualSlice.len * @sizeOf(comptime meta.Child(sliceType))];
1844 return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Child(Slice))];
18471845}
18481846
18491847test "sliceAsBytes" {
lib/std/meta.zig+22-15
......@@ -115,30 +115,37 @@ test "std.meta.Child" {
115115 testing.expect(Child(?u8) == u8);
116116}
117117
118/// Given a type with a sentinel e.g. `[:0]u8`, returns the sentinel
119pub fn Sentinel(comptime T: type) Child(T) {
120 // comptime asserts that ptr has a sentinel
118/// Given a type which can have a sentinel e.g. `[:0]u8`, returns the sentinel value,
119/// or `null` if there is not one.
120/// Types which cannot possibly have a sentinel will be a compile error.
121pub fn sentinel(comptime T: type) ?Child(T) {
121122 switch (@typeInfo(T)) {
122 .Array => |arrayInfo| {
123 return comptime arrayInfo.sentinel.?;
124 },
125 .Pointer => |ptrInfo| {
126 switch (ptrInfo.size) {
127 .Many, .Slice => {
128 return comptime ptrInfo.sentinel.?;
123 .Array => |info| return info.sentinel,
124 .Pointer => |info| {
125 switch (info.size) {
126 .Many, .Slice => return info.sentinel,
127 .One => switch (info.child) {
128 .Array => |array_info| return array_info.sentinel,
129 else => {},
129130 },
130131 else => {},
131132 }
132133 },
133134 else => {},
134135 }
135 @compileError("not a sentinel type, found '" ++ @typeName(T) ++ "'");
136 @compileError("type '" ++ @typeName(T) ++ "' cannot possibly have a sentinel");
136137}
137138
138test "std.meta.Sentinel" {
139 testing.expectEqual(@as(u8, 0), Sentinel([:0]u8));
140 testing.expectEqual(@as(u8, 0), Sentinel([*:0]u8));
141 testing.expectEqual(@as(u8, 0), Sentinel([5:0]u8));
139test "std.meta.sentinel" {
140 testing.expectEqual(@as(u8, 0), sentinel([:0]u8).?);
141 testing.expectEqual(@as(u8, 0), sentinel([*:0]u8).?);
142 testing.expectEqual(@as(u8, 0), sentinel([5:0]u8).?);
143 testing.expectEqual(@as(u8, 0), sentinel(*const [5:0]u8).?);
144
145 testing.expect(sentinel([]u8) == null);
146 testing.expect(sentinel([*]u8) == null);
147 testing.expect(sentinel([5]u8) == null);
148 testing.expect(sentinel(*const [5]u8) == null);
142149}
143150
144151pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout {
src-self-hosted/translate_c.zig+12-14
......@@ -1744,20 +1744,18 @@ fn writeEscapedString(buf: []u8, s: []const u8) void {
17441744// Returns either a string literal or a slice of `buf`.
17451745fn escapeChar(c: u8, char_buf: *[4]u8) []const u8 {
17461746 return switch (c) {
1747 '\"' => "\\\""[0..],
1748 '\'' => "\\'"[0..],
1749 '\\' => "\\\\"[0..],
1750 '\n' => "\\n"[0..],
1751 '\r' => "\\r"[0..],
1752 '\t' => "\\t"[0..],
1753 else => {
1754 // Handle the remaining escapes Zig doesn't support by turning them
1755 // into their respective hex representation
1756 if (std.ascii.isCntrl(c))
1757 return std.fmt.bufPrint(char_buf[0..], "\\x{x:0<2}", .{c}) catch unreachable
1758 else
1759 return std.fmt.bufPrint(char_buf[0..], "{c}", .{c}) catch unreachable;
1760 },
1747 '\"' => "\\\"",
1748 '\'' => "\\'",
1749 '\\' => "\\\\",
1750 '\n' => "\\n",
1751 '\r' => "\\r",
1752 '\t' => "\\t",
1753 // Handle the remaining escapes Zig doesn't support by turning them
1754 // into their respective hex representation
1755 else => if (std.ascii.isCntrl(c))
1756 std.fmt.bufPrint(char_buf, "\\x{x:0<2}", .{c}) catch unreachable
1757 else
1758 std.fmt.bufPrint(char_buf, "{c}", .{c}) catch unreachable,
17611759 };
17621760}
17631761