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