Commit 7b9165b375
Changed files (1)
lib
std
lib/std/mem.zig
@@ -1911,7 +1911,7 @@ pub fn writePackedInt(comptime T: type, bytes: []u8, bit_offset: usize, value: T
/// Any extra bytes in buffer after writing the integer are set to zero. To
/// avoid the branch to check for extra buffer bytes, use writeIntLittle
/// instead.
-pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
+fn writeIntSliceLittleNative(comptime T: type, buffer: []u8, value: T) void {
assert(buffer.len >= @divExact(@typeInfo(T).Int.bits, 8));
if (@typeInfo(T).Int.bits == 0) {
@@ -1921,21 +1921,27 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
buffer[0] = @as(u8, @bitCast(value));
return;
}
- // TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough
- const uint = std.meta.Int(.unsigned, @typeInfo(T).Int.bits);
- var bits = @as(uint, @bitCast(value));
- for (buffer) |*b| {
- b.* = @as(u8, @truncate(bits));
- bits >>= 8;
- }
+
+ const write_end = @divExact(@typeInfo(T).Int.bits, 8);
+ @as(*align(1) T, @ptrCast(buffer)).* = value;
+ @memset(buffer[write_end..], 0);
+}
+
+fn writeIntSliceLittleForeign(comptime T: type, buffer: []u8, value: T) void {
+ return writeIntSliceLittleNative(T, buffer, @byteSwap(value));
}
+pub const writeIntSliceLittle = switch (native_endian) {
+ .Little => writeIntSliceLittleNative,
+ .Big => writeIntSliceLittleForeign,
+};
+
/// Writes a twos-complement big-endian integer to memory.
/// Asserts that buffer.len >= @typeInfo(T).Int.bits / 8.
/// The bit count of T must be divisible by 8.
/// Any extra bytes in buffer before writing the integer are set to zero. To
/// avoid the branch to check for extra buffer bytes, use writeIntBig instead.
-pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {
+fn writeIntSliceBigNative(comptime T: type, buffer: []u8, value: T) void {
assert(buffer.len >= @divExact(@typeInfo(T).Int.bits, 8));
if (@typeInfo(T).Int.bits == 0) {
@@ -1946,25 +1952,28 @@ pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {
return;
}
- // TODO I want to call writeIntBig here but comptime eval facilities aren't good enough
- const uint = std.meta.Int(.unsigned, @typeInfo(T).Int.bits);
- var bits = @as(uint, @bitCast(value));
- var index: usize = buffer.len;
- while (index != 0) {
- index -= 1;
- buffer[index] = @as(u8, @truncate(bits));
- bits >>= 8;
- }
+ const write_start = buffer.len - @divExact(@typeInfo(T).Int.bits, 8);
+ @memset(buffer[0..write_start], 0);
+ @as(*align(1) T, @ptrCast(buffer[write_start..])).* = value;
+}
+
+fn writeIntSliceBigForeign(comptime T: type, buffer: []u8, value: T) void {
+ return writeIntSliceBigNative(T, buffer, @byteSwap(value));
}
+pub const writeIntSliceBig = switch (native_endian) {
+ .Little => writeIntSliceBigForeign,
+ .Big => writeIntSliceBigNative,
+};
+
pub const writeIntSliceNative = switch (native_endian) {
- .Little => writeIntSliceLittle,
- .Big => writeIntSliceBig,
+ .Little => writeIntSliceLittleNative,
+ .Big => writeIntSliceBigNative,
};
pub const writeIntSliceForeign = switch (native_endian) {
- .Little => writeIntSliceBig,
- .Big => writeIntSliceLittle,
+ .Little => writeIntSliceBigForeign,
+ .Big => writeIntSliceLittleForeign,
};
/// Writes a twos-complement integer to memory, with the specified endianness.