mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
std.mem: Improve writeIntSlice performance
This commit is contained in:
parent
14efbf5ed1
commit
7b9165b375
@ -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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user