| ... | @@ -7,13 +7,12 @@ const testing = std.testing; | ... | @@ -7,13 +7,12 @@ const testing = std.testing; |
| 7 | | 7 | |
| 8 | pub const trait = @import("meta/trait.zig"); | 8 | pub const trait = @import("meta/trait.zig"); |
| 9 | | 9 | |
| 10 | const TypeId = builtin.TypeId; | | |
| 11 | const TypeInfo = builtin.TypeInfo; | 10 | const TypeInfo = builtin.TypeInfo; |
| 12 | | 11 | |
| 13 | pub fn tagName(v: var) []const u8 { | 12 | pub fn tagName(v: var) []const u8 { |
| 14 | const T = @TypeOf(v); | 13 | const T = @TypeOf(v); |
| 15 | switch (@typeInfo(T)) { | 14 | switch (@typeInfo(T)) { |
| 16 | TypeId.ErrorSet => return @errorName(v), | 15 | .ErrorSet => return @errorName(v), |
| 17 | else => return @tagName(v), | 16 | else => return @tagName(v), |
| 18 | } | 17 | } |
| 19 | } | 18 | } |
| ... | @@ -55,7 +54,7 @@ test "std.meta.tagName" { | ... | @@ -55,7 +54,7 @@ test "std.meta.tagName" { |
| 55 | | 54 | |
| 56 | pub fn stringToEnum(comptime T: type, str: []const u8) ?T { | 55 | pub fn stringToEnum(comptime T: type, str: []const u8) ?T { |
| 57 | inline for (@typeInfo(T).Enum.fields) |enumField| { | 56 | inline for (@typeInfo(T).Enum.fields) |enumField| { |
| 58 | if (std.mem.eql(u8, str, enumField.name)) { | 57 | if (mem.eql(u8, str, enumField.name)) { |
| 59 | return @field(T, enumField.name); | 58 | return @field(T, enumField.name); |
| 60 | } | 59 | } |
| 61 | } | 60 | } |
| ... | @@ -74,9 +73,9 @@ test "std.meta.stringToEnum" { | ... | @@ -74,9 +73,9 @@ test "std.meta.stringToEnum" { |
| 74 | | 73 | |
| 75 | pub fn bitCount(comptime T: type) comptime_int { | 74 | pub fn bitCount(comptime T: type) comptime_int { |
| 76 | return switch (@typeInfo(T)) { | 75 | return switch (@typeInfo(T)) { |
| 77 | TypeId.Bool => 1, | 76 | .Bool => 1, |
| 78 | TypeId.Int => |info| info.bits, | 77 | .Int => |info| info.bits, |
| 79 | TypeId.Float => |info| info.bits, | 78 | .Float => |info| info.bits, |
| 80 | else => @compileError("Expected bool, int or float type, found '" ++ @typeName(T) ++ "'"), | 79 | else => @compileError("Expected bool, int or float type, found '" ++ @typeName(T) ++ "'"), |
| 81 | }; | 80 | }; |
| 82 | } | 81 | } |
| ... | @@ -88,7 +87,7 @@ test "std.meta.bitCount" { | ... | @@ -88,7 +87,7 @@ test "std.meta.bitCount" { |
| 88 | | 87 | |
| 89 | pub fn alignment(comptime T: type) comptime_int { | 88 | pub fn alignment(comptime T: type) comptime_int { |
| 90 | //@alignOf works on non-pointer types | 89 | //@alignOf works on non-pointer types |
| 91 | const P = if (comptime trait.is(TypeId.Pointer)(T)) T else *T; | 90 | const P = if (comptime trait.is(.Pointer)(T)) T else *T; |
| 92 | return @typeInfo(P).Pointer.alignment; | 91 | return @typeInfo(P).Pointer.alignment; |
| 93 | } | 92 | } |
| 94 | | 93 | |
| ... | @@ -102,9 +101,9 @@ test "std.meta.alignment" { | ... | @@ -102,9 +101,9 @@ test "std.meta.alignment" { |
| 102 | | 101 | |
| 103 | pub fn Child(comptime T: type) type { | 102 | pub fn Child(comptime T: type) type { |
| 104 | return switch (@typeInfo(T)) { | 103 | return switch (@typeInfo(T)) { |
| 105 | TypeId.Array => |info| info.child, | 104 | .Array => |info| info.child, |
| 106 | TypeId.Pointer => |info| info.child, | 105 | .Pointer => |info| info.child, |
| 107 | TypeId.Optional => |info| info.child, | 106 | .Optional => |info| info.child, |
| 108 | else => @compileError("Expected pointer, optional, or array type, " ++ "found '" ++ @typeName(T) ++ "'"), | 107 | else => @compileError("Expected pointer, optional, or array type, " ++ "found '" ++ @typeName(T) ++ "'"), |
| 109 | }; | 108 | }; |
| 110 | } | 109 | } |
| ... | @@ -118,9 +117,9 @@ test "std.meta.Child" { | ... | @@ -118,9 +117,9 @@ test "std.meta.Child" { |
| 118 | | 117 | |
| 119 | pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout { | 118 | pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout { |
| 120 | return switch (@typeInfo(T)) { | 119 | return switch (@typeInfo(T)) { |
| 121 | TypeId.Struct => |info| info.layout, | 120 | .Struct => |info| info.layout, |
| 122 | TypeId.Enum => |info| info.layout, | 121 | .Enum => |info| info.layout, |
| 123 | TypeId.Union => |info| info.layout, | 122 | .Union => |info| info.layout, |
| 124 | else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"), | 123 | else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"), |
| 125 | }; | 124 | }; |
| 126 | } | 125 | } |
| ... | @@ -148,22 +147,22 @@ test "std.meta.containerLayout" { | ... | @@ -148,22 +147,22 @@ test "std.meta.containerLayout" { |
| 148 | a: u8, | 147 | a: u8, |
| 149 | }; | 148 | }; |
| 150 | | 149 | |
| 151 | testing.expect(containerLayout(E1) == TypeInfo.ContainerLayout.Auto); | 150 | testing.expect(containerLayout(E1) == .Auto); |
| 152 | testing.expect(containerLayout(E2) == TypeInfo.ContainerLayout.Packed); | 151 | testing.expect(containerLayout(E2) == .Packed); |
| 153 | testing.expect(containerLayout(E3) == TypeInfo.ContainerLayout.Extern); | 152 | testing.expect(containerLayout(E3) == .Extern); |
| 154 | testing.expect(containerLayout(S1) == TypeInfo.ContainerLayout.Auto); | 153 | testing.expect(containerLayout(S1) == .Auto); |
| 155 | testing.expect(containerLayout(S2) == TypeInfo.ContainerLayout.Packed); | 154 | testing.expect(containerLayout(S2) == .Packed); |
| 156 | testing.expect(containerLayout(S3) == TypeInfo.ContainerLayout.Extern); | 155 | testing.expect(containerLayout(S3) == .Extern); |
| 157 | testing.expect(containerLayout(U1) == TypeInfo.ContainerLayout.Auto); | 156 | testing.expect(containerLayout(U1) == .Auto); |
| 158 | testing.expect(containerLayout(U2) == TypeInfo.ContainerLayout.Packed); | 157 | testing.expect(containerLayout(U2) == .Packed); |
| 159 | testing.expect(containerLayout(U3) == TypeInfo.ContainerLayout.Extern); | 158 | testing.expect(containerLayout(U3) == .Extern); |
| 160 | } | 159 | } |
| 161 | | 160 | |
| 162 | pub fn declarations(comptime T: type) []TypeInfo.Declaration { | 161 | pub fn declarations(comptime T: type) []TypeInfo.Declaration { |
| 163 | return switch (@typeInfo(T)) { | 162 | return switch (@typeInfo(T)) { |
| 164 | TypeId.Struct => |info| info.decls, | 163 | .Struct => |info| info.decls, |
| 165 | TypeId.Enum => |info| info.decls, | 164 | .Enum => |info| info.decls, |
| 166 | TypeId.Union => |info| info.decls, | 165 | .Union => |info| info.decls, |
| 167 | else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"), | 166 | else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"), |
| 168 | }; | 167 | }; |
| 169 | } | 168 | } |
| ... | @@ -232,17 +231,17 @@ test "std.meta.declarationInfo" { | ... | @@ -232,17 +231,17 @@ test "std.meta.declarationInfo" { |
| 232 | } | 231 | } |
| 233 | | 232 | |
| 234 | pub fn fields(comptime T: type) switch (@typeInfo(T)) { | 233 | pub fn fields(comptime T: type) switch (@typeInfo(T)) { |
| 235 | TypeId.Struct => []TypeInfo.StructField, | 234 | .Struct => []TypeInfo.StructField, |
| 236 | TypeId.Union => []TypeInfo.UnionField, | 235 | .Union => []TypeInfo.UnionField, |
| 237 | TypeId.ErrorSet => []TypeInfo.Error, | 236 | .ErrorSet => []TypeInfo.Error, |
| 238 | TypeId.Enum => []TypeInfo.EnumField, | 237 | .Enum => []TypeInfo.EnumField, |
| 239 | else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), | 238 | else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), |
| 240 | } { | 239 | } { |
| 241 | return switch (@typeInfo(T)) { | 240 | return switch (@typeInfo(T)) { |
| 242 | TypeId.Struct => |info| info.fields, | 241 | .Struct => |info| info.fields, |
| 243 | TypeId.Union => |info| info.fields, | 242 | .Union => |info| info.fields, |
| 244 | TypeId.Enum => |info| info.fields, | 243 | .Enum => |info| info.fields, |
| 245 | TypeId.ErrorSet => |errors| errors.?, // must be non global error set | 244 | .ErrorSet => |errors| errors.?, // must be non global error set |
| 246 | else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), | 245 | else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), |
| 247 | }; | 246 | }; |
| 248 | } | 247 | } |
| ... | @@ -277,10 +276,10 @@ test "std.meta.fields" { | ... | @@ -277,10 +276,10 @@ test "std.meta.fields" { |
| 277 | } | 276 | } |
| 278 | | 277 | |
| 279 | pub fn fieldInfo(comptime T: type, comptime field_name: []const u8) switch (@typeInfo(T)) { | 278 | pub fn fieldInfo(comptime T: type, comptime field_name: []const u8) switch (@typeInfo(T)) { |
| 280 | TypeId.Struct => TypeInfo.StructField, | 279 | .Struct => TypeInfo.StructField, |
| 281 | TypeId.Union => TypeInfo.UnionField, | 280 | .Union => TypeInfo.UnionField, |
| 282 | TypeId.ErrorSet => TypeInfo.Error, | 281 | .ErrorSet => TypeInfo.Error, |
| 283 | TypeId.Enum => TypeInfo.EnumField, | 282 | .Enum => TypeInfo.EnumField, |
| 284 | else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), | 283 | else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), |
| 285 | } { | 284 | } { |
| 286 | inline for (comptime fields(T)) |field| { | 285 | inline for (comptime fields(T)) |field| { |
| ... | @@ -318,8 +317,8 @@ test "std.meta.fieldInfo" { | ... | @@ -318,8 +317,8 @@ test "std.meta.fieldInfo" { |
| 318 | | 317 | |
| 319 | pub fn TagType(comptime T: type) type { | 318 | pub fn TagType(comptime T: type) type { |
| 320 | return switch (@typeInfo(T)) { | 319 | return switch (@typeInfo(T)) { |
| 321 | TypeId.Enum => |info| info.tag_type, | 320 | .Enum => |info| info.tag_type, |
| 322 | TypeId.Union => |info| if (info.tag_type) |Tag| Tag else null, | 321 | .Union => |info| if (info.tag_type) |Tag| Tag else null, |
| 323 | else => @compileError("expected enum or union type, found '" ++ @typeName(T) ++ "'"), | 322 | else => @compileError("expected enum or union type, found '" ++ @typeName(T) ++ "'"), |
| 324 | }; | 323 | }; |
| 325 | } | 324 | } |
| ... | @@ -365,7 +364,7 @@ test "std.meta.activeTag" { | ... | @@ -365,7 +364,7 @@ test "std.meta.activeTag" { |
| 365 | ///Given a tagged union type, and an enum, return the type of the union | 364 | ///Given a tagged union type, and an enum, return the type of the union |
| 366 | /// field corresponding to the enum tag. | 365 | /// field corresponding to the enum tag. |
| 367 | pub fn TagPayloadType(comptime U: type, tag: @TagType(U)) type { | 366 | pub fn TagPayloadType(comptime U: type, tag: @TagType(U)) type { |
| 368 | testing.expect(trait.is(builtin.TypeId.Union)(U)); | 367 | testing.expect(trait.is(.Union)(U)); |
| 369 | | 368 | |
| 370 | const info = @typeInfo(U).Union; | 369 | const info = @typeInfo(U).Union; |
| 371 | | 370 | |
| ... | @@ -387,30 +386,26 @@ test "std.meta.TagPayloadType" { | ... | @@ -387,30 +386,26 @@ test "std.meta.TagPayloadType" { |
| 387 | testing.expect(MovedEvent == @TypeOf(e.Moved)); | 386 | testing.expect(MovedEvent == @TypeOf(e.Moved)); |
| 388 | } | 387 | } |
| 389 | | 388 | |
| 390 | ///Compares two of any type for equality. Containers are compared on a field-by-field basis, | 389 | /// Compares two of any type for equality. Containers are compared on a field-by-field basis, |
| 391 | /// where possible. Pointers are not followed. | 390 | /// where possible. Pointers are not followed. |
| 392 | pub fn eql(a: var, b: @TypeOf(a)) bool { | 391 | pub fn eql(a: var, b: @TypeOf(a)) bool { |
| 393 | const T = @TypeOf(a); | 392 | const T = @TypeOf(a); |
| 394 | | 393 | |
| 395 | switch (@typeId(T)) { | 394 | switch (@typeInfo(T)) { |
| 396 | builtin.TypeId.Struct => { | 395 | .Struct => |info| { |
| 397 | const info = @typeInfo(T).Struct; | | |
| 398 | | | |
| 399 | inline for (info.fields) |field_info| { | 396 | inline for (info.fields) |field_info| { |
| 400 | if (!eql(@field(a, field_info.name), @field(b, field_info.name))) return false; | 397 | if (!eql(@field(a, field_info.name), @field(b, field_info.name))) return false; |
| 401 | } | 398 | } |
| 402 | return true; | 399 | return true; |
| 403 | }, | 400 | }, |
| 404 | builtin.TypeId.ErrorUnion => { | 401 | .ErrorUnion => { |
| 405 | if (a) |a_p| { | 402 | if (a) |a_p| { |
| 406 | if (b) |b_p| return eql(a_p, b_p) else |_| return false; | 403 | if (b) |b_p| return eql(a_p, b_p) else |_| return false; |
| 407 | } else |a_e| { | 404 | } else |a_e| { |
| 408 | if (b) |_| return false else |b_e| return a_e == b_e; | 405 | if (b) |_| return false else |b_e| return a_e == b_e; |
| 409 | } | 406 | } |
| 410 | }, | 407 | }, |
| 411 | builtin.TypeId.Union => { | 408 | .Union => |info| { |
| 412 | const info = @typeInfo(T).Union; | | |
| 413 | | | |
| 414 | if (info.tag_type) |_| { | 409 | if (info.tag_type) |_| { |
| 415 | const tag_a = activeTag(a); | 410 | const tag_a = activeTag(a); |
| 416 | const tag_b = activeTag(b); | 411 | const tag_b = activeTag(b); |
| ... | @@ -427,31 +422,26 @@ pub fn eql(a: var, b: @TypeOf(a)) bool { | ... | @@ -427,31 +422,26 @@ pub fn eql(a: var, b: @TypeOf(a)) bool { |
| 427 | | 422 | |
| 428 | @compileError("cannot compare untagged union type " ++ @typeName(T)); | 423 | @compileError("cannot compare untagged union type " ++ @typeName(T)); |
| 429 | }, | 424 | }, |
| 430 | builtin.TypeId.Array => { | 425 | .Array => { |
| 431 | if (a.len != b.len) return false; | 426 | if (a.len != b.len) return false; |
| 432 | for (a) |e, i| | 427 | for (a) |e, i| |
| 433 | if (!eql(e, b[i])) return false; | 428 | if (!eql(e, b[i])) return false; |
| 434 | return true; | 429 | return true; |
| 435 | }, | 430 | }, |
| 436 | builtin.TypeId.Vector => { | 431 | .Vector => |info| { |
| 437 | const info = @typeInfo(T).Vector; | | |
| 438 | var i: usize = 0; | 432 | var i: usize = 0; |
| 439 | while (i < info.len) : (i += 1) { | 433 | while (i < info.len) : (i += 1) { |
| 440 | if (!eql(a[i], b[i])) return false; | 434 | if (!eql(a[i], b[i])) return false; |
| 441 | } | 435 | } |
| 442 | return true; | 436 | return true; |
| 443 | }, | 437 | }, |
| 444 | builtin.TypeId.Pointer => { | 438 | .Pointer => |info| { |
| 445 | const info = @typeInfo(T).Pointer; | 439 | return switch (info.size) { |
| 446 | switch (info.size) { | 440 | .One, .Many, .C, => a == b, |
| 447 | builtin.TypeInfo.Pointer.Size.One, | 441 | .Slice => a.ptr == b.ptr and a.len == b.len, |
| 448 | builtin.TypeInfo.Pointer.Size.Many, | 442 | }; |
| 449 | builtin.TypeInfo.Pointer.Size.C, | | |
| 450 | => return a == b, | | |
| 451 | builtin.TypeInfo.Pointer.Size.Slice => return a.ptr == b.ptr and a.len == b.len, | | |
| 452 | } | | |
| 453 | }, | 443 | }, |
| 454 | builtin.TypeId.Optional => { | 444 | .Optional => { |
| 455 | if (a == null and b == null) return true; | 445 | if (a == null and b == null) return true; |
| 456 | if (a == null or b == null) return false; | 446 | if (a == null or b == null) return false; |
| 457 | return eql(a.?, b.?); | 447 | return eql(a.?, b.?); |