aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorCortex <protoss2017@mail.ru>2023-05-29 13:01:54 +0300
committerGitHub <noreply@github.com>2023-05-29 13:01:54 +0300
commit6e6a61a3847092be8a754f70f19ad3c779648ba3 (patch)
tree9cd9c6578d0fd0ea5eb6e37be8538ea7be920e8f /lib/std
parent235b776d619d64dee62fc88e85bd53421cce37f7 (diff)
downloadzig-6e6a61a3847092be8a754f70f19ad3c779648ba3.tar.gz
zig-6e6a61a3847092be8a754f70f19ad3c779648ba3.zip
std.io.Writer: add support for non-power-of-two int sizes
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/io/writer.zig15
-rw-r--r--lib/std/math.zig17
2 files changed, 22 insertions, 10 deletions
diff --git a/lib/std/io/writer.zig b/lib/std/io/writer.zig
index f4b2643e77..cfc76de452 100644
--- a/lib/std/io/writer.zig
+++ b/lib/std/io/writer.zig
@@ -46,39 +46,34 @@ pub fn Writer(
}
/// Write a native-endian integer.
- /// TODO audit non-power-of-two int sizes
pub fn writeIntNative(self: Self, comptime T: type, value: T) Error!void {
var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
- mem.writeIntNative(T, &bytes, value);
+ mem.writeIntNative(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
return self.writeAll(&bytes);
}
/// Write a foreign-endian integer.
- /// TODO audit non-power-of-two int sizes
pub fn writeIntForeign(self: Self, comptime T: type, value: T) Error!void {
var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
- mem.writeIntForeign(T, &bytes, value);
+ mem.writeIntForeign(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
return self.writeAll(&bytes);
}
- /// TODO audit non-power-of-two int sizes
pub fn writeIntLittle(self: Self, comptime T: type, value: T) Error!void {
var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
- mem.writeIntLittle(T, &bytes, value);
+ mem.writeIntLittle(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
return self.writeAll(&bytes);
}
- /// TODO audit non-power-of-two int sizes
pub fn writeIntBig(self: Self, comptime T: type, value: T) Error!void {
var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
- mem.writeIntBig(T, &bytes, value);
+ mem.writeIntBig(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
return self.writeAll(&bytes);
}
- /// TODO audit non-power-of-two int sizes
pub fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void {
var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
- mem.writeInt(T, &bytes, value, endian);
+ mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian);
return self.writeAll(&bytes);
}
diff --git a/lib/std/math.zig b/lib/std/math.zig
index 4221118ba5..8bd7c364f9 100644
--- a/lib/std/math.zig
+++ b/lib/std/math.zig
@@ -1122,6 +1122,23 @@ pub fn isPowerOfTwo(v: anytype) bool {
return (v & (v - 1)) == 0;
}
+/// Aligns the given integer type bit width to a width divisible by 8.
+pub fn ByteAlignedInt(comptime T: type) type {
+ const info = @typeInfo(T).Int;
+ const bits = (info.bits + 7) / 8 * 8;
+ const extended_type = std.meta.Int(info.signedness, bits);
+ return extended_type;
+}
+
+test "ByteAlignedInt" {
+ try testing.expect(ByteAlignedInt(u0) == u0);
+ try testing.expect(ByteAlignedInt(i0) == i0);
+ try testing.expect(ByteAlignedInt(u3) == u8);
+ try testing.expect(ByteAlignedInt(u8) == u8);
+ try testing.expect(ByteAlignedInt(i111) == i112);
+ try testing.expect(ByteAlignedInt(u129) == u136);
+}
+
/// Rounds the given floating point number to an integer, away from zero.
/// Uses a dedicated hardware instruction when available.
/// This is the same as calling the builtin @round