| author | |
| committer | |
| log | 0b0de22fd1b0391f0cf1c7d821afc6522041c699 |
| tree | f00dfb75125a1efa6cd3c6c5b5632e289c440f82 |
| parent | b99c6d56da3d2db995c268fb07f48548ea6d1148 |
| signature | Commit is signed but in an unrecognized format. |
std: add std.meta.Sentinel to get sentinel of a type6 files changed, 58 insertions(+), 15 deletions(-)
lib/std/cstr.zig+1-1| ... | ... | @@ -28,7 +28,7 @@ test "cstr fns" { |
| 28 | 28 | |
| 29 | 29 | fn testCStrFnsImpl() void { |
| 30 | 30 | testing.expect(cmp("aoeu", "aoez") == -1); |
| 31 | testing.expect(mem.len(u8, "123456789") == 9); | |
| 31 | testing.expect(mem.len(u8, "123456789".*) == 9); | |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | /// Returns a mutable, null-terminated slice with the same length as `slice`. |
lib/std/fmt.zig+6-2| ... | ... | @@ -441,10 +441,14 @@ pub fn formatType( |
| 441 | 441 | else => return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) }), |
| 442 | 442 | }, |
| 443 | 443 | .Many, .C => { |
| 444 | if (ptr_info.sentinel) |sentinel| { | |
| 445 | const slice = mem.pointerToSlice([:sentinel]const ptr_info.child, value); | |
| 446 | return formatType(slice, fmt, options, context, Errors, output, max_depth); | |
| 447 | } | |
| 444 | 448 | if (ptr_info.child == u8) { |
| 445 | 449 | if (fmt.len > 0 and fmt[0] == 's') { |
| 446 | const len = mem.len(u8, value); | |
| 447 | return formatText(value[0..len], fmt, options, context, Errors, output); | |
| 450 | const slice = mem.pointerToSlice([:0]const u8, @as([*:0]const u8, value)); | |
| 451 | return formatText(slice, fmt, options, context, Errors, output); | |
| 448 | 452 | } |
| 449 | 453 | } |
| 450 | 454 | return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) }); |
lib/std/mem.zig+17-4| ... | ... | @@ -470,18 +470,31 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { |
| 470 | 470 | return true; |
| 471 | 471 | } |
| 472 | 472 | |
| 473 | pub fn len(comptime T: type, ptr: [*:0]const T) usize { | |
| 473 | pub fn len(comptime T: type, ptr: var) usize { | |
| 474 | const sentinel: T = comptime meta.Sentinel(@TypeOf(ptr)); | |
| 474 | 475 | var count: usize = 0; |
| 475 | while (ptr[count] != 0) : (count += 1) {} | |
| 476 | while (ptr[count] != sentinel) : (count += 1) {} | |
| 476 | 477 | return count; |
| 477 | 478 | } |
| 478 | 479 | |
| 480 | /// Given a sentintel-terminated pointer-to-many, find the sentintel and return a slice. | |
| 481 | pub fn pointerToSlice(comptime T: type, ptr: blk: { | |
| 482 | var info = @typeInfo(T).Pointer; | |
| 483 | info.size = .Many; | |
| 484 | break :blk @Type(std.builtin.TypeInfo{ .Pointer = info }); | |
| 485 | }) T { | |
| 486 | const sentinel = comptime meta.Sentinel(T); | |
| 487 | return ptr[0..len(meta.Child(T), ptr) :sentinel]; | |
| 488 | } | |
| 489 | ||
| 490 | /// Deprecated; use pointerToSlice instead | |
| 479 | 491 | pub fn toSliceConst(comptime T: type, ptr: [*:0]const T) [:0]const T { |
| 480 | return ptr[0..len(T, ptr) :0]; | |
| 492 | return pointerToSlice([:0]const T, ptr); | |
| 481 | 493 | } |
| 482 | 494 | |
| 495 | /// Deprecated; use pointerToSlice instead | |
| 483 | 496 | pub fn toSlice(comptime T: type, ptr: [*:0]T) [:0]T { |
| 484 | return ptr[0..len(T, ptr) :0]; | |
| 497 | return pointerToSlice([:0]T, ptr); | |
| 485 | 498 | } |
| 486 | 499 | |
| 487 | 500 | /// Returns true if all elements in a slice are equal to the scalar value provided |
lib/std/meta.zig+26| ... | ... | @@ -115,6 +115,32 @@ test "std.meta.Child" { |
| 115 | 115 | testing.expect(Child(?u8) == u8); |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | /// Given a type with a sentinel e.g. `[:0]u8`, returns the sentinel | |
| 119 | pub fn Sentinel(comptime T: type) Child(T) { | |
| 120 | // comptime asserts that ptr has a sentinel | |
| 121 | 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.?; | |
| 129 | }, | |
| 130 | else => {}, | |
| 131 | } | |
| 132 | }, | |
| 133 | else => {}, | |
| 134 | } | |
| 135 | @compileError("not a sentinel type, found '" ++ @typeName(T) ++ "'"); | |
| 136 | } | |
| 137 | ||
| 138 | test "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)); | |
| 142 | } | |
| 143 | ||
| 118 | 144 | pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout { |
| 119 | 145 | return switch (@typeInfo(T)) { |
| 120 | 146 | .Struct => |info| info.layout, |
src-self-hosted/main.zig+7-7| ... | ... | @@ -792,7 +792,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro |
| 792 | 792 | } |
| 793 | 793 | |
| 794 | 794 | fn cmdVersion(allocator: *Allocator, args: []const []const u8) !void { |
| 795 | try stdout.print("{}\n", .{std.mem.toSliceConst(u8, c.ZIG_VERSION_STRING)}); | |
| 795 | try stdout.print("{}\n", .{c.ZIG_VERSION_STRING}); | |
| 796 | 796 | } |
| 797 | 797 | |
| 798 | 798 | fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void { |
| ... | ... | @@ -863,12 +863,12 @@ fn cmdInternalBuildInfo(allocator: *Allocator, args: []const []const u8) !void { |
| 863 | 863 | \\ZIG_DIA_GUIDS_LIB {} |
| 864 | 864 | \\ |
| 865 | 865 | , .{ |
| 866 | std.mem.toSliceConst(u8, c.ZIG_CMAKE_BINARY_DIR), | |
| 867 | std.mem.toSliceConst(u8, c.ZIG_CXX_COMPILER), | |
| 868 | std.mem.toSliceConst(u8, c.ZIG_LLD_INCLUDE_PATH), | |
| 869 | std.mem.toSliceConst(u8, c.ZIG_LLD_LIBRARIES), | |
| 870 | std.mem.toSliceConst(u8, c.ZIG_LLVM_CONFIG_EXE), | |
| 871 | std.mem.toSliceConst(u8, c.ZIG_DIA_GUIDS_LIB), | |
| 866 | c.ZIG_CMAKE_BINARY_DIR, | |
| 867 | c.ZIG_CXX_COMPILER, | |
| 868 | c.ZIG_LLD_INCLUDE_PATH, | |
| 869 | c.ZIG_LLD_LIBRARIES, | |
| 870 | c.ZIG_LLVM_CONFIG_EXE, | |
| 871 | c.ZIG_DIA_GUIDS_LIB, | |
| 872 | 872 | }); |
| 873 | 873 | } |
| 874 | 874 |
test/stage1/behavior/misc.zig+1-1| ... | ... | @@ -335,7 +335,7 @@ test "string concatenation" { |
| 335 | 335 | comptime expect(@TypeOf(a) == *const [12:0]u8); |
| 336 | 336 | comptime expect(@TypeOf(b) == *const [12:0]u8); |
| 337 | 337 | |
| 338 | const len = mem.len(u8, b); | |
| 338 | const len = b.len; | |
| 339 | 339 | const len_with_null = len + 1; |
| 340 | 340 | { |
| 341 | 341 | var i: u32 = 0; |