aboutsummaryrefslogtreecommitdiff
path: root/lib/std/meta.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-03-18 19:29:24 -0400
committerAndrew Kelley <andrew@ziglang.org>2020-03-19 09:53:55 -0400
commitb5dba702fff35c2d9aa86c9d5dd93a4a38d3b75b (patch)
treebb25768327c4170f7a88246942b097594c8229cc /lib/std/meta.zig
parent2164b511cce235ec4a49de99452e4900835bfba8 (diff)
downloadzig-b5dba702fff35c2d9aa86c9d5dd93a4a38d3b75b.tar.gz
zig-b5dba702fff35c2d9aa86c9d5dd93a4a38d3b75b.zip
fixes to std.meta
behavior tests are passing now
Diffstat (limited to 'lib/std/meta.zig')
-rw-r--r--lib/std/meta.zig34
1 files changed, 31 insertions, 3 deletions
diff --git a/lib/std/meta.zig b/lib/std/meta.zig
index e8b9f16895..7343cfc51a 100644
--- a/lib/std/meta.zig
+++ b/lib/std/meta.zig
@@ -104,7 +104,7 @@ pub fn Child(comptime T: type) type {
.Array => |info| info.child,
.Pointer => |info| info.child,
.Optional => |info| info.child,
- else => @compileError("Expected pointer, optional, or array type, " ++ "found '" ++ @typeName(T) ++ "'"),
+ else => @compileError("Expected pointer, optional, or array type, found '" ++ @typeName(T) ++ "'"),
};
}
@@ -115,16 +115,39 @@ test "std.meta.Child" {
testing.expect(Child(?u8) == u8);
}
+/// Given a "memory span" type, returns the "element type".
+pub fn Elem(comptime T: type) type {
+ switch (@typeInfo(T)) {
+ .Array => |info| return info.child,
+ .Pointer => |info| switch (info.size) {
+ .One => switch (@typeInfo(info.child)) {
+ .Array => |array_info| return array_info.child,
+ else => {},
+ },
+ .Many, .C, .Slice => return info.child,
+ },
+ else => {},
+ }
+ @compileError("Expected pointer, slice, or array, found '" ++ @typeName(T) ++ "'");
+}
+
+test "std.meta.Elem" {
+ testing.expect(Elem([1]u8) == u8);
+ testing.expect(Elem([*]u8) == u8);
+ testing.expect(Elem([]u8) == u8);
+ testing.expect(Elem(*[10]u8) == u8);
+}
+
/// 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) {
+pub fn sentinel(comptime T: type) ?Elem(T) {
switch (@typeInfo(T)) {
.Array => |info| return info.sentinel,
.Pointer => |info| {
switch (info.size) {
.Many, .Slice => return info.sentinel,
- .One => switch (info.child) {
+ .One => switch (@typeInfo(info.child)) {
.Array => |array_info| return array_info.sentinel,
else => {},
},
@@ -137,6 +160,11 @@ pub fn sentinel(comptime T: type) ?Child(T) {
}
test "std.meta.sentinel" {
+ testSentinel();
+ comptime testSentinel();
+}
+
+fn testSentinel() void {
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).?);