authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-10-19 23:27:16+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-10-19 23:27:16+02:00
logdb3b768eabaf0ca7f83cccabfaa61eb0aa400c41
tree7cff9bfe7a108346e749a52920d9e69fe8320c9e
parent2a3fdd52ce7bd0cc577947e49bc8a3e69a34b6d0

Ran fmt on last PR


3 files changed, 232 insertions(+), 364 deletions(-)

std/mem.zig+61-73
...@@ -866,128 +866,123 @@ test "std.mem.endianSwap" {...@@ -866,128 +866,123 @@ test "std.mem.endianSwap" {
866 assert(endianSwap(u32, 0xDEADBEEF) == 0xEFBEADDE);866 assert(endianSwap(u32, 0xDEADBEEF) == 0xEFBEADDE);
867}867}
868868
869869fn AsBytesReturnType(comptime P: type) type {
870870 if (comptime !trait.isSingleItemPtr(P))
871fn AsBytesReturnType(comptime P: type) type871 @compileError("expected single item " ++ "pointer, passed " ++ @typeName(P));
872{
873 if(comptime !trait.isSingleItemPtr(P)) @compileError("expected single item "
874 ++ "pointer, passed " ++ @typeName(P));
875872
876 const size = usize(@sizeOf(meta.Child(P)));873 const size = usize(@sizeOf(meta.Child(P)));
877 const alignment = comptime meta.alignment(P);874 const alignment = comptime meta.alignment(P);
878 if(comptime trait.isConstPtr(P)) return *align(alignment) const [size]u8;875
876 if (comptime trait.isConstPtr(P))
877 return *align(alignment) const [size]u8;
879 return *align(alignment) [size]u8;878 return *align(alignment) [size]u8;
880}879}
881880
882///Given a pointer to a single item, returns a slice of the underlying bytes, preserving constness.881///Given a pointer to a single item, returns a slice of the underlying bytes, preserving constness.
883pub fn asBytes(ptr: var) AsBytesReturnType(@typeOf(ptr))882pub fn asBytes(ptr: var) AsBytesReturnType(@typeOf(ptr)) {
884{
885 const P = @typeOf(ptr);883 const P = @typeOf(ptr);
886 return @ptrCast(AsBytesReturnType(P), ptr);884 return @ptrCast(AsBytesReturnType(P), ptr);
887}885}
888886
889test "std.mem.asBytes"887test "std.mem.asBytes" {
890{
891 const deadbeef = u32(0xDEADBEEF);888 const deadbeef = u32(0xDEADBEEF);
892 const deadbeef_bytes = switch(builtin.endian)889 const deadbeef_bytes = switch (builtin.endian) {
893 {
894 builtin.Endian.Big => "\xDE\xAD\xBE\xEF",890 builtin.Endian.Big => "\xDE\xAD\xBE\xEF",
895 builtin.Endian.Little => "\xEF\xBE\xAD\xDE",891 builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
896 };892 };
897 893
898 debug.assert(std.mem.eql(u8, asBytes(&deadbeef), deadbeef_bytes));894 debug.assert(std.mem.eql(u8, asBytes(&deadbeef), deadbeef_bytes));
899 895
900 var codeface = u32(0xC0DEFACE);896 var codeface = u32(0xC0DEFACE);
901 for(asBytes(&codeface).*) |*b| b.* = 0;897 for (asBytes(&codeface).*) |*b|
898 b.* = 0;
902 debug.assert(codeface == 0);899 debug.assert(codeface == 0);
903 900
904 const S = packed struct.901 const S = packed struct.{
905 {
906 a: u8,902 a: u8,
907 b: u8,903 b: u8,
908 c: u8,904 c: u8,
909 d: u8,905 d: u8,
910 };906 };
911 907
912 const inst = S.{ .a = 0xBE, .b = 0xEF, .c = 0xDE, .d = 0xA1, };908 const inst = S.{
909 .a = 0xBE,
910 .b = 0xEF,
911 .c = 0xDE,
912 .d = 0xA1,
913 };
913 debug.assert(std.mem.eql(u8, asBytes(&inst), "\xBE\xEF\xDE\xA1"));914 debug.assert(std.mem.eql(u8, asBytes(&inst), "\xBE\xEF\xDE\xA1"));
914}915}
915916
916///Given any value, returns a copy of its bytes in an array.917///Given any value, returns a copy of its bytes in an array.
917pub fn toBytes(value: var) [@sizeOf(@typeOf(value))]u8918pub fn toBytes(value: var) [@sizeOf(@typeOf(value))]u8 {
918{
919 return asBytes(&value).*;919 return asBytes(&value).*;
920}920}
921921
922test "std.mem.toBytes"922test "std.mem.toBytes" {
923{
924 var my_bytes = toBytes(u32(0x12345678));923 var my_bytes = toBytes(u32(0x12345678));
925 switch(builtin.endian)924 switch (builtin.endian) {
926 {
927 builtin.Endian.Big => debug.assert(std.mem.eql(u8, my_bytes, "\x12\x34\x56\x78")),925 builtin.Endian.Big => debug.assert(std.mem.eql(u8, my_bytes, "\x12\x34\x56\x78")),
928 builtin.Endian.Little => debug.assert(std.mem.eql(u8, my_bytes, "\x78\x56\x34\x12")),926 builtin.Endian.Little => debug.assert(std.mem.eql(u8, my_bytes, "\x78\x56\x34\x12")),
929 }927 }
930 928
931 my_bytes[0] = '\x99';929 my_bytes[0] = '\x99';
932 switch(builtin.endian)930 switch (builtin.endian) {
933 {
934 builtin.Endian.Big => debug.assert(std.mem.eql(u8, my_bytes, "\x99\x34\x56\x78")),931 builtin.Endian.Big => debug.assert(std.mem.eql(u8, my_bytes, "\x99\x34\x56\x78")),
935 builtin.Endian.Little => debug.assert(std.mem.eql(u8, my_bytes, "\x99\x56\x34\x12")),932 builtin.Endian.Little => debug.assert(std.mem.eql(u8, my_bytes, "\x99\x56\x34\x12")),
936 }933 }
937}934}
938935
939936fn BytesAsValueReturnType(comptime T: type, comptime B: type) type {
940fn BytesAsValueReturnType(comptime T: type, comptime B: type) type
941{
942 const size = usize(@sizeOf(T));937 const size = usize(@sizeOf(T));
943938
944 if(comptime !trait.is(builtin.TypeId.Pointer)(B) or meta.Child(B) != [size]u8)939 if (comptime !trait.is(builtin.TypeId.Pointer)(B) or meta.Child(B) != [size]u8) {
945 {
946 @compileError("expected *[N]u8 " ++ ", passed " ++ @typeName(B));940 @compileError("expected *[N]u8 " ++ ", passed " ++ @typeName(B));
947 }941 }
948 942
949 const alignment = comptime meta.alignment(B);943 const alignment = comptime meta.alignment(B);
950 944
951 return if(comptime trait.isConstPtr(B)) *align(alignment) const T else *align(alignment) T;945 return if (comptime trait.isConstPtr(B)) *align(alignment) const T else *align(alignment) T;
952}946}
953947
954///Given a pointer to an array of bytes, returns a pointer to a value of the specified type948///Given a pointer to an array of bytes, returns a pointer to a value of the specified type
955/// backed by those bytes, preserving constness.949/// backed by those bytes, preserving constness.
956pub fn bytesAsValue(comptime T: type, bytes: var) BytesAsValueReturnType(T, @typeOf(bytes))950pub fn bytesAsValue(comptime T: type, bytes: var) BytesAsValueReturnType(T, @typeOf(bytes)) {
957{
958 return @ptrCast(BytesAsValueReturnType(T, @typeOf(bytes)), bytes);951 return @ptrCast(BytesAsValueReturnType(T, @typeOf(bytes)), bytes);
959}952}
960953
961test "std.mem.bytesAsValue"954test "std.mem.bytesAsValue" {
962{
963 const deadbeef = u32(0xDEADBEEF);955 const deadbeef = u32(0xDEADBEEF);
964 const deadbeef_bytes = switch(builtin.endian)956 const deadbeef_bytes = switch (builtin.endian) {
965 {
966 builtin.Endian.Big => "\xDE\xAD\xBE\xEF",957 builtin.Endian.Big => "\xDE\xAD\xBE\xEF",
967 builtin.Endian.Little => "\xEF\xBE\xAD\xDE",958 builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
968 };959 };
969 960
970 debug.assert(deadbeef == bytesAsValue(u32, &deadbeef_bytes).*);961 debug.assert(deadbeef == bytesAsValue(u32, &deadbeef_bytes).*);
971 962
972 var codeface_bytes = switch(builtin.endian)963 var codeface_bytes = switch (builtin.endian) {
973 {
974 builtin.Endian.Big => "\xC0\xDE\xFA\xCE",964 builtin.Endian.Big => "\xC0\xDE\xFA\xCE",
975 builtin.Endian.Little => "\xCE\xFA\xDE\xC0",965 builtin.Endian.Little => "\xCE\xFA\xDE\xC0",
976 };966 };
977 var codeface = bytesAsValue(u32, &codeface_bytes);967 var codeface = bytesAsValue(u32, &codeface_bytes);
978 debug.assert(codeface.* == 0xC0DEFACE);968 debug.assert(codeface.* == 0xC0DEFACE);
979 codeface.* = 0;969 codeface.* = 0;
980 for(codeface_bytes) |b| debug.assert(b == 0);970 for (codeface_bytes) |b|
981 971 debug.assert(b == 0);
982 const S = packed struct.972
983 {973 const S = packed struct.{
984 a: u8,974 a: u8,
985 b: u8,975 b: u8,
986 c: u8,976 c: u8,
987 d: u8,977 d: u8,
988 };978 };
989 979
990 const inst = S.{ .a = 0xBE, .b = 0xEF, .c = 0xDE, .d = 0xA1, };980 const inst = S.{
981 .a = 0xBE,
982 .b = 0xEF,
983 .c = 0xDE,
984 .d = 0xA1,
985 };
991 const inst_bytes = "\xBE\xEF\xDE\xA1";986 const inst_bytes = "\xBE\xEF\xDE\xA1";
992 const inst2 = bytesAsValue(S, &inst_bytes);987 const inst2 = bytesAsValue(S, &inst_bytes);
993 debug.assert(meta.eql(inst, inst2.*));988 debug.assert(meta.eql(inst, inst2.*));
...@@ -995,50 +990,43 @@ test "std.mem.bytesAsValue"...@@ -995,50 +990,43 @@ test "std.mem.bytesAsValue"
995990
996///Given a pointer to an array of bytes, returns a value of the specified type backed by a991///Given a pointer to an array of bytes, returns a value of the specified type backed by a
997/// copy of those bytes.992/// copy of those bytes.
998pub fn bytesToValue(comptime T: type, bytes: var) T993pub fn bytesToValue(comptime T: type, bytes: var) T {
999{
1000 return bytesAsValue(T, &bytes).*;994 return bytesAsValue(T, &bytes).*;
1001}995}
1002 test "std.mem.bytesToValue"996test "std.mem.bytesToValue" {
1003{997 const deadbeef_bytes = switch (builtin.endian) {
1004 const deadbeef_bytes = switch(builtin.endian)
1005 {
1006 builtin.Endian.Big => "\xDE\xAD\xBE\xEF",998 builtin.Endian.Big => "\xDE\xAD\xBE\xEF",
1007 builtin.Endian.Little => "\xEF\xBE\xAD\xDE",999 builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
1008 };1000 };
1009 1001
1010 const deadbeef = bytesToValue(u32, deadbeef_bytes);1002 const deadbeef = bytesToValue(u32, deadbeef_bytes);
1011 debug.assert(deadbeef == u32(0xDEADBEEF));1003 debug.assert(deadbeef == u32(0xDEADBEEF));
1012}1004}
10131005
10141006fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
1015fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type1007 if (trait.isConstPtr(T))
1016{1008 return *const [length]meta.Child(meta.Child(T));
1017 if(trait.isConstPtr(T)) return *const [length]meta.Child(meta.Child(T));
1018 return *[length]meta.Child(meta.Child(T));1009 return *[length]meta.Child(meta.Child(T));
1019}1010}
10201011
1021///Given a pointer to an array, returns a pointer to a portion of that array, preserving constness.1012///Given a pointer to an array, returns a pointer to a portion of that array, preserving constness.
1022pub fn subArrayPtr(ptr: var, comptime start: usize, comptime length: usize) 1013pub fn subArrayPtr(ptr: var, comptime start: usize, comptime length: usize) SubArrayPtrReturnType(@typeOf(ptr), length) {
1023 SubArrayPtrReturnType(@typeOf(ptr), length)
1024{
1025 debug.assert(start + length <= ptr.*.len);1014 debug.assert(start + length <= ptr.*.len);
1026 1015
1027 const ReturnType = SubArrayPtrReturnType(@typeOf(ptr), length);1016 const ReturnType = SubArrayPtrReturnType(@typeOf(ptr), length);
1028 const T = meta.Child(meta.Child(@typeOf(ptr)));1017 const T = meta.Child(meta.Child(@typeOf(ptr)));
1029 return @ptrCast(ReturnType, &ptr[start]);1018 return @ptrCast(ReturnType, &ptr[start]);
1030}1019}
10311020
1032test "std.mem.subArrayPtr"1021test "std.mem.subArrayPtr" {
1033{
1034 const a1 = "abcdef";1022 const a1 = "abcdef";
1035 const sub1 = subArrayPtr(&a1, 2, 3);1023 const sub1 = subArrayPtr(&a1, 2, 3);
1036 debug.assert(std.mem.eql(u8, sub1.*, "cde"));1024 debug.assert(std.mem.eql(u8, sub1.*, "cde"));
1037 1025
1038 var a2 = "abcdef";1026 var a2 = "abcdef";
1039 var sub2 = subArrayPtr(&a2, 2, 3);1027 var sub2 = subArrayPtr(&a2, 2, 3);
10401028
1041 debug.assert(std.mem.eql(u8, sub2, "cde"));1029 debug.assert(std.mem.eql(u8, sub2, "cde"));
1042 sub2[1] = 'X';1030 sub2[1] = 'X';
1043 debug.assert(std.mem.eql(u8, a2, "abcXef"));1031 debug.assert(std.mem.eql(u8, a2, "abcXef"));
1044}
\ No newline at end of file
1032}
std/meta/index.zig+71-111
...@@ -21,7 +21,7 @@ pub fn tagName(v: var) []const u8 {...@@ -21,7 +21,7 @@ pub fn tagName(v: var) []const u8 {
21 unreachable;21 unreachable;
22 },22 },
23 TypeId.Union => |info| {23 TypeId.Union => |info| {
24 const UnionTag = if(info.tag_type) |UT| UT else @compileError("union is untagged");24 const UnionTag = if (info.tag_type) |UT| UT else @compileError("union is untagged");
25 const Tag = @typeInfo(UnionTag).Enum.tag_type;25 const Tag = @typeInfo(UnionTag).Enum.tag_type;
26 inline for (info.fields) |field| {26 inline for (info.fields) |field| {
27 if (field.enum_field.?.value == @enumToInt(UnionTag(v)))27 if (field.enum_field.?.value == @enumToInt(UnionTag(v)))
...@@ -37,8 +37,7 @@ pub fn tagName(v: var) []const u8 {...@@ -37,8 +37,7 @@ pub fn tagName(v: var) []const u8 {
3737
38 unreachable;38 unreachable;
39 },39 },
40 else => @compileError("expected enum, error set or union type, found '" 40 else => @compileError("expected enum, error set or union type, found '" ++ @typeName(T) ++ "'"),
41 ++ @typeName(T) ++ "'"),
42 }41 }
43}42}
4443
...@@ -92,7 +91,7 @@ test "std.meta.bitCount" {...@@ -92,7 +91,7 @@ test "std.meta.bitCount" {
9291
93pub fn alignment(comptime T: type) u29 {92pub fn alignment(comptime T: type) u29 {
94 //@alignOf works on non-pointer types93 //@alignOf works on non-pointer types
95 const P = if(comptime trait.is(TypeId.Pointer)(T)) T else *T;94 const P = if (comptime trait.is(TypeId.Pointer)(T)) T else *T;
96 return @typeInfo(P).Pointer.alignment;95 return @typeInfo(P).Pointer.alignment;
97}96}
9897
...@@ -109,9 +108,8 @@ pub fn Child(comptime T: type) type {...@@ -109,9 +108,8 @@ pub fn Child(comptime T: type) type {
109 TypeId.Array => |info| info.child,108 TypeId.Array => |info| info.child,
110 TypeId.Pointer => |info| info.child,109 TypeId.Pointer => |info| info.child,
111 TypeId.Optional => |info| info.child,110 TypeId.Optional => |info| info.child,
112 TypeId.Promise => |info| if(info.child) |child| child else null,111 TypeId.Promise => |info| if (info.child) |child| child else null,
113 else => @compileError("Expected promise, pointer, optional, or array type, " 112 else => @compileError("Expected promise, pointer, optional, or array type, " ++ "found '" ++ @typeName(T) ++ "'"),
114 ++ "found '" ++ @typeName(T) ++ "'"),
115 };113 };
116}114}
117115
...@@ -128,8 +126,7 @@ pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout {...@@ -128,8 +126,7 @@ pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout {
128 TypeId.Struct => |info| info.layout,126 TypeId.Struct => |info| info.layout,
129 TypeId.Enum => |info| info.layout,127 TypeId.Enum => |info| info.layout,
130 TypeId.Union => |info| info.layout,128 TypeId.Union => |info| info.layout,
131 else => @compileError("Expected struct, enum or union type, found '" 129 else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"),
132 ++ @typeName(T) ++ "'"),
133 };130 };
134}131}
135132
...@@ -172,8 +169,7 @@ pub fn definitions(comptime T: type) []TypeInfo.Definition {...@@ -172,8 +169,7 @@ pub fn definitions(comptime T: type) []TypeInfo.Definition {
172 TypeId.Struct => |info| info.defs,169 TypeId.Struct => |info| info.defs,
173 TypeId.Enum => |info| info.defs,170 TypeId.Enum => |info| info.defs,
174 TypeId.Union => |info| info.defs,171 TypeId.Union => |info| info.defs,
175 else => @compileError("Expected struct, enum or union type, found '" 172 else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"),
176 ++ @typeName(T) ++ "'"),
177 };173 };
178}174}
179175
...@@ -245,16 +241,14 @@ pub fn fields(comptime T: type) switch (@typeInfo(T)) {...@@ -245,16 +241,14 @@ pub fn fields(comptime T: type) switch (@typeInfo(T)) {
245 TypeId.Union => []TypeInfo.UnionField,241 TypeId.Union => []TypeInfo.UnionField,
246 TypeId.ErrorSet => []TypeInfo.Error,242 TypeId.ErrorSet => []TypeInfo.Error,
247 TypeId.Enum => []TypeInfo.EnumField,243 TypeId.Enum => []TypeInfo.EnumField,
248 else => @compileError("Expected struct, union, error set or enum type, found '"244 else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"),
249 ++ @typeName(T) ++ "'"),
250} {245} {
251 return switch (@typeInfo(T)) {246 return switch (@typeInfo(T)) {
252 TypeId.Struct => |info| info.fields,247 TypeId.Struct => |info| info.fields,
253 TypeId.Union => |info| info.fields,248 TypeId.Union => |info| info.fields,
254 TypeId.Enum => |info| info.fields,249 TypeId.Enum => |info| info.fields,
255 TypeId.ErrorSet => |info| info.errors,250 TypeId.ErrorSet => |info| info.errors,
256 else => @compileError("Expected struct, union, error set or enum type, found '"251 else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"),
257 ++ @typeName(T) ++ "'"),
258 };252 };
259}253}
260254
...@@ -292,8 +286,7 @@ pub fn fieldInfo(comptime T: type, comptime field_name: []const u8) switch (@typ...@@ -292,8 +286,7 @@ pub fn fieldInfo(comptime T: type, comptime field_name: []const u8) switch (@typ
292 TypeId.Union => TypeInfo.UnionField,286 TypeId.Union => TypeInfo.UnionField,
293 TypeId.ErrorSet => TypeInfo.Error,287 TypeId.ErrorSet => TypeInfo.Error,
294 TypeId.Enum => TypeInfo.EnumField,288 TypeId.Enum => TypeInfo.EnumField,
295 else => @compileError("Expected struct, union, error set or enum type, found '" 289 else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"),
296 ++ @typeName(T) ++ "'"),
297} {290} {
298 inline for (comptime fields(T)) |field| {291 inline for (comptime fields(T)) |field| {
299 if (comptime mem.eql(u8, field.name, field_name))292 if (comptime mem.eql(u8, field.name, field_name))
...@@ -331,7 +324,7 @@ test "std.meta.fieldInfo" {...@@ -331,7 +324,7 @@ test "std.meta.fieldInfo" {
331pub fn TagType(comptime T: type) type {324pub fn TagType(comptime T: type) type {
332 return switch (@typeInfo(T)) {325 return switch (@typeInfo(T)) {
333 TypeId.Enum => |info| info.tag_type,326 TypeId.Enum => |info| info.tag_type,
334 TypeId.Union => |info| if(info.tag_type) |Tag| Tag else null,327 TypeId.Union => |info| if (info.tag_type) |Tag| Tag else null,
335 else => @compileError("expected enum or union type, found '" ++ @typeName(T) ++ "'"),328 else => @compileError("expected enum or union type, found '" ++ @typeName(T) ++ "'"),
336 };329 };
337}330}
...@@ -350,104 +343,80 @@ test "std.meta.TagType" {...@@ -350,104 +343,80 @@ test "std.meta.TagType" {
350 debug.assert(TagType(U) == E);343 debug.assert(TagType(U) == E);
351}344}
352345
353
354
355///Returns the active tag of a tagged union346///Returns the active tag of a tagged union
356pub fn activeTag(u: var) @TagType(@typeOf(u))347pub fn activeTag(u: var) @TagType(@typeOf(u)) {
357{
358 const T = @typeOf(u);348 const T = @typeOf(u);
359 return @TagType(T)(u);349 return @TagType(T)(u);
360}350}
361351
362test "std.meta.activeTag"352test "std.meta.activeTag" {
363{353 const UE = enum.{
364 const UE = enum.
365 {
366 Int,354 Int,
367 Float,355 Float,
368 };356 };
369 357
370 const U = union(UE).358 const U = union(UE).{
371 {
372 Int: u32,359 Int: u32,
373 Float: f32,360 Float: f32,
374 };361 };
375 362
376 var u = U.{ .Int = 32, };363 var u = U.{ .Int = 32 };
377 debug.assert(activeTag(u) == UE.Int);364 debug.assert(activeTag(u) == UE.Int);
378
379 u = U.{ .Float = 112.9876, };
380 debug.assert(activeTag(u) == UE.Float);
381365
366 u = U.{ .Float = 112.9876 };
367 debug.assert(activeTag(u) == UE.Float);
382}368}
383369
384///Compares two of any type for equality. Containers are compared on a field-by-field basis,370///Compares two of any type for equality. Containers are compared on a field-by-field basis,
385/// where possible. Pointers are not followed.371/// where possible. Pointers are not followed.
386pub fn eql(a: var, b: @typeOf(a)) bool372pub fn eql(a: var, b: @typeOf(a)) bool {
387{
388 const T = @typeOf(a);373 const T = @typeOf(a);
389 374
390 switch(@typeId(T))375 switch (@typeId(T)) {
391 {376 builtin.TypeId.Struct => {
392 builtin.TypeId.Struct =>
393 {
394 const info = @typeInfo(T).Struct;377 const info = @typeInfo(T).Struct;
395 378
396 inline for(info.fields) |field_info|379 inline for (info.fields) |field_info| {
397 {380 if (!eql(@field(a, field_info.name), @field(b, field_info.name))) return false;
398 if(!eql(@field(a, field_info.name),
399 @field(b, field_info.name))) return false;
400 }381 }
401 return true;382 return true;
402 },383 },
403 builtin.TypeId.ErrorUnion =>384 builtin.TypeId.ErrorUnion => {
404 {385 if (a) |a_p| {
405 if(a) |a_p|386 if (b) |b_p| return eql(a_p, b_p) else |_| return false;
406 {387 } else |a_e| {
407 if(b) |b_p| return eql(a_p, b_p) else |_| return false;388 if (b) |_| return false else |b_e| return a_e == b_e;
408 }
409 else |a_e|
410 {
411 if(b) |_| return false else |b_e| return a_e == b_e;
412 }389 }
413 },390 },
414 builtin.TypeId.Union => 391 builtin.TypeId.Union => {
415 {
416 const info = @typeInfo(T).Union;392 const info = @typeInfo(T).Union;
417 393
418 if(info.tag_type) |_|394 if (info.tag_type) |_| {
419 {
420 const tag_a = activeTag(a);395 const tag_a = activeTag(a);
421 const tag_b = activeTag(b);396 const tag_b = activeTag(b);
422 if(tag_a != tag_b) return false;397 if (tag_a != tag_b) return false;
423 398
424 inline for(info.fields) |field_info|399 inline for (info.fields) |field_info| {
425 {
426 const enum_field = field_info.enum_field.?;400 const enum_field = field_info.enum_field.?;
427 if(enum_field.value == @enumToInt(tag_a))401 if (enum_field.value == @enumToInt(tag_a)) {
428 {402 return eql(@field(a, enum_field.name), @field(b, enum_field.name));
429 return eql(@field(a, enum_field.name),
430 @field(b, enum_field.name));
431 }403 }
432 }404 }
433 return false;405 return false;
434 }406 }
435 407
436 @compileError("cannot compare untagged union type " ++ @typeName(T));408 @compileError("cannot compare untagged union type " ++ @typeName(T));
437 },409 },
438 builtin.TypeId.Array => 410 builtin.TypeId.Array => {
439 {411 if (a.len != b.len) return false;
440 if(a.len != b.len) return false;412 for (a) |e, i|
441 for(a) |e, i| if(!eql(e, b[i])) return false;413 if (!eql(e, b[i])) return false;
442 return true;414 return true;
443 },415 },
444 builtin.TypeId.Pointer => 416 builtin.TypeId.Pointer => {
445 {
446 const info = @typeInfo(T).Pointer;417 const info = @typeInfo(T).Pointer;
447 switch(info.size)418 switch (info.size) {
448 {419 builtin.TypeInfo.Pointer.Size.One, builtin.TypeInfo.Pointer.Size.Many => return a == b,
449 builtin.TypeInfo.Pointer.Size.One,
450 builtin.TypeInfo.Pointer.Size.Many => return a == b,
451 builtin.TypeInfo.Pointer.Size.Slice => return a.ptr == b.ptr and a.len == b.len,420 builtin.TypeInfo.Pointer.Size.Slice => return a.ptr == b.ptr and a.len == b.len,
452 }421 }
453 },422 },
...@@ -455,71 +424,62 @@ pub fn eql(a: var, b: @typeOf(a)) bool...@@ -455,71 +424,62 @@ pub fn eql(a: var, b: @typeOf(a)) bool
455 }424 }
456}425}
457426
458427test "std.meta.eql" {
459test "std.meta.eql"428 const S = struct.{
460{
461 const S = struct.
462 {
463 a: u32,429 a: u32,
464 b: f64,430 b: f64,
465 c: [5]u8,431 c: [5]u8,
466 };432 };
467 433
468 const U = union(enum).434 const U = union(enum).{
469 {
470 s: S,435 s: S,
471 f: f32,436 f: f32,
472 };437 };
473 438
474 const s_1 = S.439 const s_1 = S.{
475 {
476 .a = 134,440 .a = 134,
477 .b = 123.3,441 .b = 123.3,
478 .c = "12345",442 .c = "12345",
479 };443 };
480 444
481 const s_2 = S.445 const s_2 = S.{
482 {
483 .a = 1,446 .a = 1,
484 .b = 123.3,447 .b = 123.3,
485 .c = "54321",448 .c = "54321",
486 };449 };
487 450
488 const s_3 = S.451 const s_3 = S.{
489 {
490 .a = 134,452 .a = 134,
491 .b = 123.3,453 .b = 123.3,
492 .c = "12345",454 .c = "12345",
493 };455 };
494 456
495 const u_1 = U.{ .f = 24, };457 const u_1 = U.{ .f = 24 };
496 const u_2 = U.{ .s = s_1, };458 const u_2 = U.{ .s = s_1 };
497 const u_3 = U.{ .f = 24, };459 const u_3 = U.{ .f = 24 };
498 460
499 debug.assert(eql(s_1, s_3));461 debug.assert(eql(s_1, s_3));
500 debug.assert(eql(&s_1, &s_1));462 debug.assert(eql(&s_1, &s_1));
501 debug.assert(!eql(&s_1, &s_3));463 debug.assert(!eql(&s_1, &s_3));
502 debug.assert(eql(u_1, u_3));464 debug.assert(eql(u_1, u_3));
503 debug.assert(!eql(u_1, u_2));465 debug.assert(!eql(u_1, u_2));
504 466
505 var a1 = "abcdef";467 var a1 = "abcdef";
506 var a2 = "abcdef";468 var a2 = "abcdef";
507 var a3 = "ghijkl";469 var a3 = "ghijkl";
508 470
509 debug.assert(eql(a1, a2));471 debug.assert(eql(a1, a2));
510 debug.assert(!eql(a1, a3));472 debug.assert(!eql(a1, a3));
511 debug.assert(!eql(a1[0..], a2[0..]));473 debug.assert(!eql(a1[0..], a2[0..]));
512 474
513 const EU = struct.475 const EU = struct.{
514 {476 fn tst(err: bool) !u8 {
515 fn tst(err: bool) !u8477 if (err) return error.Error;
516 {
517 if(err) return error.Error;
518 return u8(5);478 return u8(5);
519 }479 }
520 };480 };
521 481
522 debug.assert(eql(EU.tst(true), EU.tst(true)));482 debug.assert(eql(EU.tst(true), EU.tst(true)));
523 debug.assert(eql(EU.tst(false), EU.tst(false)));483 debug.assert(eql(EU.tst(false), EU.tst(false)));
524 debug.assert(!eql(EU.tst(false), EU.tst(true)));484 debug.assert(!eql(EU.tst(false), EU.tst(true)));
525}
\ No newline at end of file
485}
std/meta/trait.zig+100-180
...@@ -8,101 +8,80 @@ const meta = @import("index.zig");...@@ -8,101 +8,80 @@ const meta = @import("index.zig");
88
9//This is necessary if we want to return generic functions directly because of how the9//This is necessary if we want to return generic functions directly because of how the
10// the type erasure works. see: #137510// the type erasure works. see: #1375
11fn traitFnWorkaround(comptime T: type) bool11fn traitFnWorkaround(comptime T: type) bool {
12{
13 return false;12 return false;
14}13}
1514
16pub const TraitFn = @typeOf(traitFnWorkaround);15pub const TraitFn = @typeOf(traitFnWorkaround);
17
18///16///
1917
20//////Trait generators18//////Trait generators
2119
22//Need TraitList because compiler can't do varargs at comptime yet20//Need TraitList because compiler can't do varargs at comptime yet
23pub const TraitList = []const TraitFn;21pub const TraitList = []const TraitFn;
24pub fn multiTrait(comptime traits: TraitList) TraitFn22pub fn multiTrait(comptime traits: TraitList) TraitFn {
25{23 const Closure = struct.{
26 const Closure = struct.24 pub fn trait(comptime T: type) bool {
27 {25 inline for (traits) |t|
28 pub fn trait(comptime T: type) bool26 if (!t(T)) return false;
29 {
30 inline for(traits) |t| if(!t(T)) return false;
31 return true;27 return true;
32 }28 }
33 };29 };
34 return Closure.trait;30 return Closure.trait;
35}31}
3632
37test "std.meta.trait.multiTrait"33test "std.meta.trait.multiTrait" {
38{34 const Vector2 = struct.{
39 const Vector2 = struct.
40 {
41 const MyType = @This();35 const MyType = @This();
42 36
43 x: u8,37 x: u8,
44 y: u8,38 y: u8,
45 39
46 pub fn add(self: MyType, other: MyType) MyType40 pub fn add(self: MyType, other: MyType) MyType {
47 {41 return MyType.{
48 return MyType.
49 {
50 .x = self.x + other.x,42 .x = self.x + other.x,
51 .y = self.y + other.y,43 .y = self.y + other.y,
52 };44 };
53 }45 }
54 };46 };
55 47
56 const isVector = multiTrait48 const isVector = multiTrait(TraitList.{
57 (49 hasFn("add"),
58 TraitList.50 hasField("x"),
59 {51 hasField("y"),
60 hasFn("add"),52 });
61 hasField("x"),
62 hasField("y"),
63 }
64 );
65 debug.assert(isVector(Vector2));53 debug.assert(isVector(Vector2));
66 debug.assert(!isVector(u8));54 debug.assert(!isVector(u8));
67}55}
6856
69///57///
7058pub fn hasDef(comptime name: []const u8) TraitFn {
71pub fn hasDef(comptime name: []const u8) TraitFn59 const Closure = struct.{
72{60 pub fn trait(comptime T: type) bool {
73 const Closure = struct.
74 {
75 pub fn trait(comptime T: type) bool
76 {
77 const info = @typeInfo(T);61 const info = @typeInfo(T);
78 const defs = switch(info)62 const defs = switch (info) {
79 {
80 builtin.TypeId.Struct => |s| s.defs,63 builtin.TypeId.Struct => |s| s.defs,
81 builtin.TypeId.Union => |u| u.defs,64 builtin.TypeId.Union => |u| u.defs,
82 builtin.TypeId.Enum => |e| e.defs,65 builtin.TypeId.Enum => |e| e.defs,
83 else => return false,66 else => return false,
84 };67 };
8568
86 inline for(defs) |def|69 inline for (defs) |def| {
87 {70 if (mem.eql(u8, def.name, name)) return def.is_pub;
88 if(mem.eql(u8, def.name, name)) return def.is_pub;
89 }71 }
90 72
91 return false;73 return false;
92 }74 }
93 };75 };
94 return Closure.trait;76 return Closure.trait;
95}77}
9678
97test "std.meta.trait.hasDef"79test "std.meta.trait.hasDef" {
98{80 const TestStruct = struct.{
99 const TestStruct = struct.
100 {
101 pub const value = u8(16);81 pub const value = u8(16);
102 };82 };
103 83
104 const TestStructFail = struct.84 const TestStructFail = struct.{
105 {
106 const value = u8(16);85 const value = u8(16);
107 };86 };
10887
...@@ -115,13 +94,10 @@ test "std.meta.trait.hasDef"...@@ -115,13 +94,10 @@ test "std.meta.trait.hasDef"
115}94}
11695
117///96///
118pub fn hasFn(comptime name: []const u8) TraitFn97pub fn hasFn(comptime name: []const u8) TraitFn {
119{98 const Closure = struct.{
120 const Closure = struct.99 pub fn trait(comptime T: type) bool {
121 {100 if (!comptime hasDef(name)(T)) return false;
122 pub fn trait(comptime T: type) bool
123 {
124 if(!comptime hasDef(name)(T)) return false;
125 const DefType = @typeOf(@field(T, name));101 const DefType = @typeOf(@field(T, name));
126 const def_type_id = @typeId(DefType);102 const def_type_id = @typeId(DefType);
127 return def_type_id == builtin.TypeId.Fn;103 return def_type_id == builtin.TypeId.Fn;
...@@ -130,10 +106,8 @@ pub fn hasFn(comptime name: []const u8) TraitFn...@@ -130,10 +106,8 @@ pub fn hasFn(comptime name: []const u8) TraitFn
130 return Closure.trait;106 return Closure.trait;
131}107}
132108
133test "std.meta.trait.hasFn"109test "std.meta.trait.hasFn" {
134{110 const TestStruct = struct.{
135 const TestStruct = struct.
136 {
137 pub fn useless() void {}111 pub fn useless() void {}
138 };112 };
139113
...@@ -143,36 +117,29 @@ test "std.meta.trait.hasFn"...@@ -143,36 +117,29 @@ test "std.meta.trait.hasFn"
143}117}
144118
145///119///
146pub fn hasField(comptime name: []const u8) TraitFn120pub fn hasField(comptime name: []const u8) TraitFn {
147{121 const Closure = struct.{
148 const Closure = struct.122 pub fn trait(comptime T: type) bool {
149 {
150 pub fn trait(comptime T: type) bool
151 {
152 const info = @typeInfo(T);123 const info = @typeInfo(T);
153 const fields = switch(info)124 const fields = switch (info) {
154 {
155 builtin.TypeId.Struct => |s| s.fields,125 builtin.TypeId.Struct => |s| s.fields,
156 builtin.TypeId.Union => |u| u.fields,126 builtin.TypeId.Union => |u| u.fields,
157 builtin.TypeId.Enum => |e| e.fields,127 builtin.TypeId.Enum => |e| e.fields,
158 else => return false,128 else => return false,
159 };129 };
160130
161 inline for(fields) |field|131 inline for (fields) |field| {
162 {132 if (mem.eql(u8, field.name, name)) return true;
163 if(mem.eql(u8, field.name, name)) return true;
164 }133 }
165 134
166 return false;135 return false;
167 }136 }
168 };137 };
169 return Closure.trait;138 return Closure.trait;
170}139}
171140
172test "std.meta.trait.hasField"141test "std.meta.trait.hasField" {
173{142 const TestStruct = struct.{
174 const TestStruct = struct.
175 {
176 value: u32,143 value: u32,
177 };144 };
178145
...@@ -184,21 +151,16 @@ test "std.meta.trait.hasField"...@@ -184,21 +151,16 @@ test "std.meta.trait.hasField"
184}151}
185152
186///153///
187154pub fn is(comptime id: builtin.TypeId) TraitFn {
188pub fn is(comptime id: builtin.TypeId) TraitFn155 const Closure = struct.{
189{156 pub fn trait(comptime T: type) bool {
190 const Closure = struct.
191 {
192 pub fn trait(comptime T: type) bool
193 {
194 return id == @typeId(T);157 return id == @typeId(T);
195 }158 }
196 };159 };
197 return Closure.trait;160 return Closure.trait;
198}161}
199162
200test "std.meta.trait.is"163test "std.meta.trait.is" {
201{
202 debug.assert(is(builtin.TypeId.Int)(u8));164 debug.assert(is(builtin.TypeId.Int)(u8));
203 debug.assert(!is(builtin.TypeId.Int)(f32));165 debug.assert(!is(builtin.TypeId.Int)(f32));
204 debug.assert(is(builtin.TypeId.Pointer)(*u8));166 debug.assert(is(builtin.TypeId.Pointer)(*u8));
...@@ -207,39 +169,31 @@ test "std.meta.trait.is"...@@ -207,39 +169,31 @@ test "std.meta.trait.is"
207}169}
208170
209///171///
210172pub fn isPtrTo(comptime id: builtin.TypeId) TraitFn {
211pub fn isPtrTo(comptime id: builtin.TypeId) TraitFn173 const Closure = struct.{
212{174 pub fn trait(comptime T: type) bool {
213 const Closure = struct.175 if (!comptime isSingleItemPtr(T)) return false;
214 {
215 pub fn trait(comptime T: type) bool
216 {
217 if(!comptime isSingleItemPtr(T)) return false;
218 return id == @typeId(meta.Child(T));176 return id == @typeId(meta.Child(T));
219 }177 }
220 };178 };
221 return Closure.trait;179 return Closure.trait;
222}180}
223181
224test "std.meta.trait.isPtrTo"182test "std.meta.trait.isPtrTo" {
225{
226 debug.assert(!isPtrTo(builtin.TypeId.Struct)(struct.{}));183 debug.assert(!isPtrTo(builtin.TypeId.Struct)(struct.{}));
227 debug.assert(isPtrTo(builtin.TypeId.Struct)(*struct.{}));184 debug.assert(isPtrTo(builtin.TypeId.Struct)(*struct.{}));
228 debug.assert(!isPtrTo(builtin.TypeId.Struct)(**struct.{}));185 debug.assert(!isPtrTo(builtin.TypeId.Struct)(**struct.{}));
229}186}
230187
231
232///////////Strait trait Fns188///////////Strait trait Fns
233189
234//@TODO:190//@TODO:
235// Somewhat limited since we can't apply this logic to normal variables, fields, or191// Somewhat limited since we can't apply this logic to normal variables, fields, or
236// Fns yet. Should be isExternType?192// Fns yet. Should be isExternType?
237pub fn isExtern(comptime T: type) bool193pub fn isExtern(comptime T: type) bool {
238{
239 const Extern = builtin.TypeInfo.ContainerLayout.Extern;194 const Extern = builtin.TypeInfo.ContainerLayout.Extern;
240 const info = @typeInfo(T);195 const info = @typeInfo(T);
241 return switch(info)196 return switch (info) {
242 {
243 builtin.TypeId.Struct => |s| s.layout == Extern,197 builtin.TypeId.Struct => |s| s.layout == Extern,
244 builtin.TypeId.Union => |u| u.layout == Extern,198 builtin.TypeId.Union => |u| u.layout == Extern,
245 builtin.TypeId.Enum => |e| e.layout == Extern,199 builtin.TypeId.Enum => |e| e.layout == Extern,
...@@ -247,8 +201,7 @@ pub fn isExtern(comptime T: type) bool...@@ -247,8 +201,7 @@ pub fn isExtern(comptime T: type) bool
247 };201 };
248}202}
249203
250test "std.meta.trait.isExtern"204test "std.meta.trait.isExtern" {
251{
252 const TestExStruct = extern struct.{};205 const TestExStruct = extern struct.{};
253 const TestStruct = struct.{};206 const TestStruct = struct.{};
254207
...@@ -258,13 +211,10 @@ test "std.meta.trait.isExtern"...@@ -258,13 +211,10 @@ test "std.meta.trait.isExtern"
258}211}
259212
260///213///
261214pub fn isPacked(comptime T: type) bool {
262pub fn isPacked(comptime T: type) bool
263{
264 const Packed = builtin.TypeInfo.ContainerLayout.Packed;215 const Packed = builtin.TypeInfo.ContainerLayout.Packed;
265 const info = @typeInfo(T);216 const info = @typeInfo(T);
266 return switch(info)217 return switch (info) {
267 {
268 builtin.TypeId.Struct => |s| s.layout == Packed,218 builtin.TypeId.Struct => |s| s.layout == Packed,
269 builtin.TypeId.Union => |u| u.layout == Packed,219 builtin.TypeId.Union => |u| u.layout == Packed,
270 builtin.TypeId.Enum => |e| e.layout == Packed,220 builtin.TypeId.Enum => |e| e.layout == Packed,
...@@ -272,8 +222,7 @@ pub fn isPacked(comptime T: type) bool...@@ -272,8 +222,7 @@ pub fn isPacked(comptime T: type) bool
272 };222 };
273}223}
274224
275test "std.meta.trait.isPacked"225test "std.meta.trait.isPacked" {
276{
277 const TestPStruct = packed struct.{};226 const TestPStruct = packed struct.{};
278 const TestStruct = struct.{};227 const TestStruct = struct.{};
279228
...@@ -283,19 +232,15 @@ test "std.meta.trait.isPacked"...@@ -283,19 +232,15 @@ test "std.meta.trait.isPacked"
283}232}
284233
285///234///
286235pub fn isSingleItemPtr(comptime T: type) bool {
287pub fn isSingleItemPtr(comptime T: type) bool236 if (comptime is(builtin.TypeId.Pointer)(T)) {
288{
289 if(comptime is(builtin.TypeId.Pointer)(T))
290 {
291 const info = @typeInfo(T);237 const info = @typeInfo(T);
292 return info.Pointer.size == builtin.TypeInfo.Pointer.Size.One;238 return info.Pointer.size == builtin.TypeInfo.Pointer.Size.One;
293 }239 }
294 return false;240 return false;
295}241}
296242
297test "std.meta.trait.isSingleItemPtr"243test "std.meta.trait.isSingleItemPtr" {
298{
299 const array = []u8.{0} ** 10;244 const array = []u8.{0} ** 10;
300 debug.assert(isSingleItemPtr(@typeOf(&array[0])));245 debug.assert(isSingleItemPtr(@typeOf(&array[0])));
301 debug.assert(!isSingleItemPtr(@typeOf(array)));246 debug.assert(!isSingleItemPtr(@typeOf(array)));
...@@ -303,19 +248,15 @@ test "std.meta.trait.isSingleItemPtr"...@@ -303,19 +248,15 @@ test "std.meta.trait.isSingleItemPtr"
303}248}
304249
305///250///
306251pub fn isManyItemPtr(comptime T: type) bool {
307pub fn isManyItemPtr(comptime T: type) bool252 if (comptime is(builtin.TypeId.Pointer)(T)) {
308{
309 if(comptime is(builtin.TypeId.Pointer)(T))
310 {
311 const info = @typeInfo(T);253 const info = @typeInfo(T);
312 return info.Pointer.size == builtin.TypeInfo.Pointer.Size.Many;254 return info.Pointer.size == builtin.TypeInfo.Pointer.Size.Many;
313 }255 }
314 return false;256 return false;
315}257}
316258
317test "std.meta.trait.isManyItemPtr"259test "std.meta.trait.isManyItemPtr" {
318{
319 const array = []u8.{0} ** 10;260 const array = []u8.{0} ** 10;
320 const mip = @ptrCast([*]const u8, &array[0]);261 const mip = @ptrCast([*]const u8, &array[0]);
321 debug.assert(isManyItemPtr(@typeOf(mip)));262 debug.assert(isManyItemPtr(@typeOf(mip)));
...@@ -324,19 +265,15 @@ test "std.meta.trait.isManyItemPtr"...@@ -324,19 +265,15 @@ test "std.meta.trait.isManyItemPtr"
324}265}
325266
326///267///
327268pub fn isSlice(comptime T: type) bool {
328pub fn isSlice(comptime T: type) bool269 if (comptime is(builtin.TypeId.Pointer)(T)) {
329{
330 if(comptime is(builtin.TypeId.Pointer)(T))
331 {
332 const info = @typeInfo(T);270 const info = @typeInfo(T);
333 return info.Pointer.size == builtin.TypeInfo.Pointer.Size.Slice;271 return info.Pointer.size == builtin.TypeInfo.Pointer.Size.Slice;
334 }272 }
335 return false;273 return false;
336}274}
337275
338test "std.meta.trait.isSlice"276test "std.meta.trait.isSlice" {
339{
340 const array = []u8.{0} ** 10;277 const array = []u8.{0} ** 10;
341 debug.assert(isSlice(@typeOf(array[0..])));278 debug.assert(isSlice(@typeOf(array[0..])));
342 debug.assert(!isSlice(@typeOf(array)));279 debug.assert(!isSlice(@typeOf(array)));
...@@ -344,27 +281,22 @@ test "std.meta.trait.isSlice"...@@ -344,27 +281,22 @@ test "std.meta.trait.isSlice"
344}281}
345282
346///283///
347284pub fn isIndexable(comptime T: type) bool {
348pub fn isIndexable(comptime T: type) bool285 if (comptime is(builtin.TypeId.Pointer)(T)) {
349{286 const info = @typeInfo(T);
350 if(comptime is(builtin.TypeId.Pointer)(T))287 if (info.Pointer.size == builtin.TypeInfo.Pointer.Size.One) {
351 {288 if (comptime is(builtin.TypeId.Array)(meta.Child(T))) return true;
352 const info = @typeInfo(T);289 return false;
353 if(info.Pointer.size == builtin.TypeInfo.Pointer.Size.One)290 }
354 {291 return true;
355 if(comptime is(builtin.TypeId.Array)(meta.Child(T))) return true;292 }
356 return false;293 return comptime is(builtin.TypeId.Array)(T);
357 }
358 return true;
359 }
360 return comptime is(builtin.TypeId.Array)(T);
361}294}
362295
363test "std.meta.trait.isIndexable"296test "std.meta.trait.isIndexable" {
364{
365 const array = []u8.{0} ** 10;297 const array = []u8.{0} ** 10;
366 const slice = array[0..];298 const slice = array[0..];
367 299
368 debug.assert(isIndexable(@typeOf(array)));300 debug.assert(isIndexable(@typeOf(array)));
369 debug.assert(isIndexable(@typeOf(&array)));301 debug.assert(isIndexable(@typeOf(&array)));
370 debug.assert(isIndexable(@typeOf(slice)));302 debug.assert(isIndexable(@typeOf(slice)));
...@@ -372,26 +304,18 @@ test "std.meta.trait.isIndexable"...@@ -372,26 +304,18 @@ test "std.meta.trait.isIndexable"
372}304}
373305
374///306///
375307pub fn isNumber(comptime T: type) bool {
376pub fn isNumber(comptime T: type) bool308 return switch (@typeId(T)) {
377{309 builtin.TypeId.Int, builtin.TypeId.Float, builtin.TypeId.ComptimeInt, builtin.TypeId.ComptimeFloat => true,
378 return switch(@typeId(T))
379 {
380 builtin.TypeId.Int,
381 builtin.TypeId.Float,
382 builtin.TypeId.ComptimeInt,
383 builtin.TypeId.ComptimeFloat => true,
384 else => false,310 else => false,
385 };311 };
386}312}
387313
388test "std.meta.trait.isNumber"314test "std.meta.trait.isNumber" {
389{315 const NotANumber = struct.{
390 const NotANumber = struct.
391 {
392 number: u8,316 number: u8,
393 };317 };
394 318
395 debug.assert(isNumber(u32));319 debug.assert(isNumber(u32));
396 debug.assert(isNumber(f32));320 debug.assert(isNumber(f32));
397 debug.assert(isNumber(u64));321 debug.assert(isNumber(u64));
...@@ -402,16 +326,13 @@ test "std.meta.trait.isNumber"...@@ -402,16 +326,13 @@ test "std.meta.trait.isNumber"
402}326}
403327
404///328///
405329pub fn isConstPtr(comptime T: type) bool {
406pub fn isConstPtr(comptime T: type) bool330 if (!comptime is(builtin.TypeId.Pointer)(T)) return false;
407{
408 if(!comptime is(builtin.TypeId.Pointer)(T)) return false;
409 const info = @typeInfo(T);331 const info = @typeInfo(T);
410 return info.Pointer.is_const;332 return info.Pointer.is_const;
411}333}
412334
413test "std.meta.trait.isConstPtr"335test "std.meta.trait.isConstPtr" {
414{
415 var t = u8(0);336 var t = u8(0);
416 const c = u8(0);337 const c = u8(0);
417 debug.assert(isConstPtr(*const @typeOf(t)));338 debug.assert(isConstPtr(*const @typeOf(t)));
...@@ -421,12 +342,9 @@ test "std.meta.trait.isConstPtr"...@@ -421,12 +342,9 @@ test "std.meta.trait.isConstPtr"
421}342}
422343
423///344///
424345pub fn isContainer(comptime T: type) bool {
425pub fn isContainer(comptime T: type) bool
426{
427 const info = @typeInfo(T);346 const info = @typeInfo(T);
428 return switch(info)347 return switch (info) {
429 {
430 builtin.TypeId.Struct => true,348 builtin.TypeId.Struct => true,
431 builtin.TypeId.Union => true,349 builtin.TypeId.Union => true,
432 builtin.TypeId.Enum => true,350 builtin.TypeId.Enum => true,
...@@ -434,16 +352,18 @@ pub fn isContainer(comptime T: type) bool...@@ -434,16 +352,18 @@ pub fn isContainer(comptime T: type) bool
434 };352 };
435}353}
436354
437test "std.meta.trait.isContainer"355test "std.meta.trait.isContainer" {
438{
439 const TestStruct = struct.{};356 const TestStruct = struct.{};
440 const TestUnion = union.{ a: void, };357 const TestUnion = union.{
441 const TestEnum = enum.{ A, B, };358 a: void,
442 359 };
360 const TestEnum = enum.{
361 A,
362 B,
363 };
364
443 debug.assert(isContainer(TestStruct));365 debug.assert(isContainer(TestStruct));
444 debug.assert(isContainer(TestUnion));366 debug.assert(isContainer(TestUnion));
445 debug.assert(isContainer(TestEnum));367 debug.assert(isContainer(TestEnum));
446 debug.assert(!isContainer(u8));368 debug.assert(!isContainer(u8));
447}369}
448
449///
\ No newline at end of file