authorgravatar for protoss2017@mail.ruCortex <protoss2017@mail.ru> 2023-05-29 13:01:54+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-05-29 13:01:54+03:00
log6e6a61a3847092be8a754f70f19ad3c779648ba3
tree9cd9c6578d0fd0ea5eb6e37be8538ea7be920e8f
parent235b776d619d64dee62fc88e85bd53421cce37f7
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

std.io.Writer: add support for non-power-of-two int sizes


2 files changed, 22 insertions(+), 10 deletions(-)

lib/std/io/writer.zig+5-10
...@@ -46,39 +46,34 @@ pub fn Writer(...@@ -46,39 +46,34 @@ pub fn Writer(
46 }46 }
4747
48 /// Write a native-endian integer.48 /// Write a native-endian integer.
49 /// TODO audit non-power-of-two int sizes
50 pub fn writeIntNative(self: Self, comptime T: type, value: T) Error!void {49 pub fn writeIntNative(self: Self, comptime T: type, value: T) Error!void {
51 var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;50 var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
52 mem.writeIntNative(T, &bytes, value);51 mem.writeIntNative(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
53 return self.writeAll(&bytes);52 return self.writeAll(&bytes);
54 }53 }
5554
56 /// Write a foreign-endian integer.55 /// Write a foreign-endian integer.
57 /// TODO audit non-power-of-two int sizes
58 pub fn writeIntForeign(self: Self, comptime T: type, value: T) Error!void {56 pub fn writeIntForeign(self: Self, comptime T: type, value: T) Error!void {
59 var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;57 var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
60 mem.writeIntForeign(T, &bytes, value);58 mem.writeIntForeign(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
61 return self.writeAll(&bytes);59 return self.writeAll(&bytes);
62 }60 }
6361
64 /// TODO audit non-power-of-two int sizes
65 pub fn writeIntLittle(self: Self, comptime T: type, value: T) Error!void {62 pub fn writeIntLittle(self: Self, comptime T: type, value: T) Error!void {
66 var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;63 var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
67 mem.writeIntLittle(T, &bytes, value);64 mem.writeIntLittle(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
68 return self.writeAll(&bytes);65 return self.writeAll(&bytes);
69 }66 }
7067
71 /// TODO audit non-power-of-two int sizes
72 pub fn writeIntBig(self: Self, comptime T: type, value: T) Error!void {68 pub fn writeIntBig(self: Self, comptime T: type, value: T) Error!void {
73 var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;69 var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
74 mem.writeIntBig(T, &bytes, value);70 mem.writeIntBig(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
75 return self.writeAll(&bytes);71 return self.writeAll(&bytes);
76 }72 }
7773
78 /// TODO audit non-power-of-two int sizes
79 pub fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void {74 pub fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void {
80 var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;75 var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
81 mem.writeInt(T, &bytes, value, endian);76 mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian);
82 return self.writeAll(&bytes);77 return self.writeAll(&bytes);
83 }78 }
8479
lib/std/math.zig+17
...@@ -1122,6 +1122,23 @@ pub fn isPowerOfTwo(v: anytype) bool {...@@ -1122,6 +1122,23 @@ pub fn isPowerOfTwo(v: anytype) bool {
1122 return (v & (v - 1)) == 0;1122 return (v & (v - 1)) == 0;
1123}1123}
11241124
1125/// Aligns the given integer type bit width to a width divisible by 8.
1126pub fn ByteAlignedInt(comptime T: type) type {
1127 const info = @typeInfo(T).Int;
1128 const bits = (info.bits + 7) / 8 * 8;
1129 const extended_type = std.meta.Int(info.signedness, bits);
1130 return extended_type;
1131}
1132
1133test "ByteAlignedInt" {
1134 try testing.expect(ByteAlignedInt(u0) == u0);
1135 try testing.expect(ByteAlignedInt(i0) == i0);
1136 try testing.expect(ByteAlignedInt(u3) == u8);
1137 try testing.expect(ByteAlignedInt(u8) == u8);
1138 try testing.expect(ByteAlignedInt(i111) == i112);
1139 try testing.expect(ByteAlignedInt(u129) == u136);
1140}
1141
1125/// Rounds the given floating point number to an integer, away from zero.1142/// Rounds the given floating point number to an integer, away from zero.
1126/// Uses a dedicated hardware instruction when available.1143/// Uses a dedicated hardware instruction when available.
1127/// This is the same as calling the builtin @round1144/// This is the same as calling the builtin @round