From 8ea0a00f406bb04c08a8fa4471c3a3895f82b24a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 17 Mar 2020 18:54:09 -0400 Subject: improve std lib code for the new semantics --- lib/std/meta.zig | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'lib/std/meta.zig') diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 65809abb5c..e8b9f16895 100644 --- a/lib/std/meta.zig +++ b/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 { -- cgit v1.2.3