| ... | @@ -503,13 +503,13 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type { | ... | @@ -503,13 +503,13 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type { |
| 503 | /// containing them in the least significant end. The number of bits successfully | 503 | /// containing them in the least significant end. The number of bits successfully |
| 504 | /// read is placed in `out_bits`, as reaching the end of the stream is not an error. | 504 | /// read is placed in `out_bits`, as reaching the end of the stream is not an error. |
| 505 | pub fn readBits(self: *Self, comptime U: type, bits: usize, out_bits: *usize) Error!U { | 505 | pub fn readBits(self: *Self, comptime U: type, bits: usize, out_bits: *usize) Error!U { |
| 506 | debug.assert(trait.isUnsignedInt(U)); | 506 | comptime assert(trait.isUnsignedInt(U)); |
| 507 | | 507 | |
| 508 | //by extending the buffer to a minimum of u8 we can cover a number of edge cases | 508 | //by extending the buffer to a minimum of u8 we can cover a number of edge cases |
| 509 | // related to shifting and casting. | 509 | // related to shifting and casting. |
| 510 | const u_bit_count = comptime meta.bitCount(U); | 510 | const u_bit_count = comptime meta.bitCount(U); |
| 511 | const buf_bit_count = bc: { | 511 | const buf_bit_count = bc: { |
| 512 | debug.assert(u_bit_count >= bits); | 512 | assert(u_bit_count >= bits); |
| 513 | break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count; | 513 | break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count; |
| 514 | }; | 514 | }; |
| 515 | const Buf = @IntType(false, buf_bit_count); | 515 | const Buf = @IntType(false, buf_bit_count); |
| ... | @@ -664,7 +664,7 @@ test "io.SliceOutStream" { | ... | @@ -664,7 +664,7 @@ test "io.SliceOutStream" { |
| 664 | const stream = &slice_stream.stream; | 664 | const stream = &slice_stream.stream; |
| 665 | | 665 | |
| 666 | try stream.print("{}{}!", "Hello", "World"); | 666 | try stream.print("{}{}!", "Hello", "World"); |
| 667 | debug.assert(mem.eql(u8, "HelloWorld!", slice_stream.getWritten())); | 667 | debug.assertOrPanic(mem.eql(u8, "HelloWorld!", slice_stream.getWritten())); |
| 668 | } | 668 | } |
| 669 | | 669 | |
| 670 | var null_out_stream_state = NullOutStream.init(); | 670 | var null_out_stream_state = NullOutStream.init(); |
| ... | @@ -726,7 +726,7 @@ test "io.CountingOutStream" { | ... | @@ -726,7 +726,7 @@ test "io.CountingOutStream" { |
| 726 | | 726 | |
| 727 | const bytes = "yay" ** 10000; | 727 | const bytes = "yay" ** 10000; |
| 728 | stream.write(bytes) catch unreachable; | 728 | stream.write(bytes) catch unreachable; |
| 729 | debug.assert(counting_stream.bytes_written == bytes.len); | 729 | debug.assertOrPanic(counting_stream.bytes_written == bytes.len); |
| 730 | } | 730 | } |
| 731 | | 731 | |
| 732 | pub fn BufferedOutStream(comptime Error: type) type { | 732 | pub fn BufferedOutStream(comptime Error: type) type { |
| ... | @@ -835,13 +835,13 @@ pub fn BitOutStream(endian: builtin.Endian, comptime Error: type) type { | ... | @@ -835,13 +835,13 @@ pub fn BitOutStream(endian: builtin.Endian, comptime Error: type) type { |
| 835 | if (bits == 0) return; | 835 | if (bits == 0) return; |
| 836 | | 836 | |
| 837 | const U = @typeOf(value); | 837 | const U = @typeOf(value); |
| 838 | debug.assert(trait.isUnsignedInt(U)); | 838 | comptime assert(trait.isUnsignedInt(U)); |
| 839 | | 839 | |
| 840 | //by extending the buffer to a minimum of u8 we can cover a number of edge cases | 840 | //by extending the buffer to a minimum of u8 we can cover a number of edge cases |
| 841 | // related to shifting and casting. | 841 | // related to shifting and casting. |
| 842 | const u_bit_count = comptime meta.bitCount(U); | 842 | const u_bit_count = comptime meta.bitCount(U); |
| 843 | const buf_bit_count = bc: { | 843 | const buf_bit_count = bc: { |
| 844 | debug.assert(u_bit_count >= bits); | 844 | assert(u_bit_count >= bits); |
| 845 | break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count; | 845 | break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count; |
| 846 | }; | 846 | }; |
| 847 | const Buf = @IntType(false, buf_bit_count); | 847 | const Buf = @IntType(false, buf_bit_count); |
| ... | @@ -1013,10 +1013,10 @@ test "io.readLineFrom" { | ... | @@ -1013,10 +1013,10 @@ test "io.readLineFrom" { |
| 1013 | ); | 1013 | ); |
| 1014 | const stream = &mem_stream.stream; | 1014 | const stream = &mem_stream.stream; |
| 1015 | | 1015 | |
| 1016 | debug.assert(mem.eql(u8, "Line 1", try readLineFrom(stream, &buf))); | 1016 | debug.assertOrPanic(mem.eql(u8, "Line 1", try readLineFrom(stream, &buf))); |
| 1017 | debug.assert(mem.eql(u8, "Line 22", try readLineFrom(stream, &buf))); | 1017 | debug.assertOrPanic(mem.eql(u8, "Line 22", try readLineFrom(stream, &buf))); |
| 1018 | debug.assertError(readLineFrom(stream, &buf), error.EndOfStream); | 1018 | debug.assertError(readLineFrom(stream, &buf), error.EndOfStream); |
| 1019 | debug.assert(mem.eql(u8, buf.toSlice(), "Line 1Line 22Line 333")); | 1019 | debug.assertOrPanic(mem.eql(u8, buf.toSlice(), "Line 1Line 22Line 333")); |
| 1020 | } | 1020 | } |
| 1021 | | 1021 | |
| 1022 | pub fn readLineSlice(slice: []u8) ![]u8 { | 1022 | pub fn readLineSlice(slice: []u8) ![]u8 { |
| ... | @@ -1044,7 +1044,7 @@ test "io.readLineSliceFrom" { | ... | @@ -1044,7 +1044,7 @@ test "io.readLineSliceFrom" { |
| 1044 | ); | 1044 | ); |
| 1045 | const stream = &mem_stream.stream; | 1045 | const stream = &mem_stream.stream; |
| 1046 | | 1046 | |
| 1047 | debug.assert(mem.eql(u8, "Line 1", try readLineSliceFrom(stream, buf[0..]))); | 1047 | debug.assertOrPanic(mem.eql(u8, "Line 1", try readLineSliceFrom(stream, buf[0..]))); |
| 1048 | debug.assertError(readLineSliceFrom(stream, buf[0..]), error.OutOfMemory); | 1048 | debug.assertError(readLineSliceFrom(stream, buf[0..]), error.OutOfMemory); |
| 1049 | } | 1049 | } |
| 1050 | | 1050 | |
| ... | @@ -1057,7 +1057,7 @@ test "io.readLineSliceFrom" { | ... | @@ -1057,7 +1057,7 @@ test "io.readLineSliceFrom" { |
| 1057 | /// which will be called when the deserializer is used to deserialize | 1057 | /// which will be called when the deserializer is used to deserialize |
| 1058 | /// that type. It will pass a pointer to the type instance to deserialize | 1058 | /// that type. It will pass a pointer to the type instance to deserialize |
| 1059 | /// into and a pointer to the deserializer struct. | 1059 | /// into and a pointer to the deserializer struct. |
| 1060 | pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: type) type { | 1060 | pub fn Deserializer(comptime endian: builtin.Endian, is_packed: bool, comptime Error: type) type { |
| 1061 | return struct { | 1061 | return struct { |
| 1062 | const Self = @This(); | 1062 | const Self = @This(); |
| 1063 | | 1063 | |
| ... | @@ -1079,9 +1079,9 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ | ... | @@ -1079,9 +1079,9 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ |
| 1079 | | 1079 | |
| 1080 | //@BUG: inferred error issue. See: #1386 | 1080 | //@BUG: inferred error issue. See: #1386 |
| 1081 | fn deserializeInt(self: *Self, comptime T: type) (Stream.Error || error{EndOfStream})!T { | 1081 | fn deserializeInt(self: *Self, comptime T: type) (Stream.Error || error{EndOfStream})!T { |
| 1082 | debug.assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T)); | 1082 | comptime assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T)); |
| 1083 | | 1083 | |
| 1084 | const u8_bit_count = comptime meta.bitCount(u8); | 1084 | const u8_bit_count = 8; |
| 1085 | const t_bit_count = comptime meta.bitCount(T); | 1085 | const t_bit_count = comptime meta.bitCount(T); |
| 1086 | | 1086 | |
| 1087 | const U = @IntType(false, t_bit_count); | 1087 | const U = @IntType(false, t_bit_count); |
| ... | @@ -1097,13 +1097,17 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ | ... | @@ -1097,13 +1097,17 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ |
| 1097 | const read_size = try self.in_stream.read(buffer[0..]); | 1097 | const read_size = try self.in_stream.read(buffer[0..]); |
| 1098 | if (read_size < int_size) return error.EndOfStream; | 1098 | if (read_size < int_size) return error.EndOfStream; |
| 1099 | | 1099 | |
| 1100 | if (int_size == 1) return @bitCast(T, buffer[0]); | 1100 | if (int_size == 1) { |
| | 1101 | if (t_bit_count == 8) return @bitCast(T, buffer[0]); |
| | 1102 | const PossiblySignedByte = @IntType(T.is_signed, 8); |
| | 1103 | return @truncate(T, @bitCast(PossiblySignedByte, buffer[0])); |
| | 1104 | } |
| 1101 | | 1105 | |
| 1102 | var result = U(0); | 1106 | var result = U(0); |
| 1103 | for (buffer) |byte, i| { | 1107 | for (buffer) |byte, i| { |
| 1104 | switch (endian) { | 1108 | switch (endian) { |
| 1105 | builtin.Endian.Big => { | 1109 | builtin.Endian.Big => { |
| 1106 | result = (result << @intCast(u4, u8_bit_count)) | byte; | 1110 | result = (result << u8_bit_count) | byte; |
| 1107 | }, | 1111 | }, |
| 1108 | builtin.Endian.Little => { | 1112 | builtin.Endian.Little => { |
| 1109 | result |= U(byte) << @intCast(Log2U, u8_bit_count * i); | 1113 | result |= U(byte) << @intCast(Log2U, u8_bit_count * i); |
| ... | @@ -1118,12 +1122,12 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ | ... | @@ -1118,12 +1122,12 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ |
| 1118 | // see: #1315 | 1122 | // see: #1315 |
| 1119 | fn setTag(ptr: var, tag: var) void { | 1123 | fn setTag(ptr: var, tag: var) void { |
| 1120 | const T = @typeOf(ptr); | 1124 | const T = @typeOf(ptr); |
| 1121 | comptime debug.assert(trait.isPtrTo(builtin.TypeId.Union)(T)); | 1125 | comptime assert(trait.isPtrTo(builtin.TypeId.Union)(T)); |
| 1122 | const U = meta.Child(T); | 1126 | const U = meta.Child(T); |
| 1123 | | 1127 | |
| 1124 | const info = @typeInfo(U).Union; | 1128 | const info = @typeInfo(U).Union; |
| 1125 | if (info.tag_type) |TagType| { | 1129 | if (info.tag_type) |TagType| { |
| 1126 | debug.assert(TagType == @typeOf(tag)); | 1130 | comptime assert(TagType == @typeOf(tag)); |
| 1127 | | 1131 | |
| 1128 | var ptr_tag = ptr: { | 1132 | var ptr_tag = ptr: { |
| 1129 | if (@alignOf(TagType) >= @alignOf(U)) break :ptr @ptrCast(*TagType, ptr); | 1133 | if (@alignOf(TagType) >= @alignOf(U)) break :ptr @ptrCast(*TagType, ptr); |
| ... | @@ -1151,7 +1155,7 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ | ... | @@ -1151,7 +1155,7 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ |
| 1151 | /// Deserializes data into the type pointed to by `ptr` | 1155 | /// Deserializes data into the type pointed to by `ptr` |
| 1152 | pub fn deserializeInto(self: *Self, ptr: var) !void { | 1156 | pub fn deserializeInto(self: *Self, ptr: var) !void { |
| 1153 | const T = @typeOf(ptr); | 1157 | const T = @typeOf(ptr); |
| 1154 | debug.assert(trait.is(builtin.TypeId.Pointer)(T)); | 1158 | comptime assert(trait.is(builtin.TypeId.Pointer)(T)); |
| 1155 | | 1159 | |
| 1156 | if (comptime trait.isSlice(T) or comptime trait.isPtrTo(builtin.TypeId.Array)(T)) { | 1160 | if (comptime trait.isSlice(T) or comptime trait.isPtrTo(builtin.TypeId.Array)(T)) { |
| 1157 | for (ptr) |*v| | 1161 | for (ptr) |*v| |
| ... | @@ -1159,7 +1163,7 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ | ... | @@ -1159,7 +1163,7 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ |
| 1159 | return; | 1163 | return; |
| 1160 | } | 1164 | } |
| 1161 | | 1165 | |
| 1162 | comptime debug.assert(trait.isSingleItemPtr(T)); | 1166 | comptime assert(trait.isSingleItemPtr(T)); |
| 1163 | | 1167 | |
| 1164 | const C = comptime meta.Child(T); | 1168 | const C = comptime meta.Child(T); |
| 1165 | const child_type_id = @typeId(C); | 1169 | const child_type_id = @typeId(C); |
| ... | @@ -1266,7 +1270,7 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ | ... | @@ -1266,7 +1270,7 @@ pub fn Deserializer(endian: builtin.Endian, is_packed: bool, comptime Error: typ |
| 1266 | /// which will be called when the serializer is used to serialize that type. It will | 1270 | /// which will be called when the serializer is used to serialize that type. It will |
| 1267 | /// pass a const pointer to the type instance to be serialized and a pointer | 1271 | /// pass a const pointer to the type instance to be serialized and a pointer |
| 1268 | /// to the serializer struct. | 1272 | /// to the serializer struct. |
| 1269 | pub fn Serializer(endian: builtin.Endian, is_packed: bool, comptime Error: type) type { | 1273 | pub fn Serializer(comptime endian: builtin.Endian, comptime is_packed: bool, comptime Error: type) type { |
| 1270 | return struct { | 1274 | return struct { |
| 1271 | const Self = @This(); | 1275 | const Self = @This(); |
| 1272 | | 1276 | |
| ... | @@ -1288,7 +1292,7 @@ pub fn Serializer(endian: builtin.Endian, is_packed: bool, comptime Error: type) | ... | @@ -1288,7 +1292,7 @@ pub fn Serializer(endian: builtin.Endian, is_packed: bool, comptime Error: type) |
| 1288 | | 1292 | |
| 1289 | fn serializeInt(self: *Self, value: var) !void { | 1293 | fn serializeInt(self: *Self, value: var) !void { |
| 1290 | const T = @typeOf(value); | 1294 | const T = @typeOf(value); |
| 1291 | debug.assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T)); | 1295 | comptime assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T)); |
| 1292 | | 1296 | |
| 1293 | const t_bit_count = comptime meta.bitCount(T); | 1297 | const t_bit_count = comptime meta.bitCount(T); |
| 1294 | const u8_bit_count = comptime meta.bitCount(u8); | 1298 | const u8_bit_count = comptime meta.bitCount(u8); |