mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
implement bytesAsSlice, sliceAsBytes
This commit is contained in:
parent
e381a42de9
commit
fdae5f5a07
@ -1486,6 +1486,76 @@ test "bytesToValue" {
|
||||
testing.expect(deadbeef == @as(u32, 0xDEADBEEF));
|
||||
}
|
||||
|
||||
//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
|
||||
fn BytesAsSliceReturnType(comptime T: type, comptime bytesType: type) type {
|
||||
if (comptime !trait.isSlice(bytesType) or comptime meta.Child(bytesType) != u8) {
|
||||
@compileError("expected []u8, passed " ++ @typeName(bytesType));
|
||||
}
|
||||
|
||||
const alignment = comptime meta.alignment(bytesType);
|
||||
|
||||
return if (comptime trait.isConstPtr(bytesType)) []align(alignment) const T else []align(alignment) T;
|
||||
}
|
||||
|
||||
pub fn bytesAsSlice(comptime T: type, bytes: var) BytesAsSliceReturnType(T, @TypeOf(bytes)) {
|
||||
// let's not give an undefined pointer to @ptrCast
|
||||
// it may be equal to zero and fail a null check
|
||||
if (bytes.len == 0) {
|
||||
return &[0]T{};
|
||||
}
|
||||
|
||||
const bytesType = @TypeOf(bytes);
|
||||
const alignment = comptime meta.alignment(bytesType);
|
||||
|
||||
const castTarget = if (comptime trait.isConstPtr(bytesType)) [*]align(alignment) const T else [*]align(alignment) T;
|
||||
|
||||
return @ptrCast(castTarget, bytes.ptr)[0..@divExact(bytes.len, @sizeOf(T))];
|
||||
}
|
||||
|
||||
test "bytesAsSlice" {
|
||||
const bytes = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
|
||||
const slice = bytesAsSlice(u16, bytes[0..]);
|
||||
testing.expect(slice.len == 2);
|
||||
testing.expect(bigToNative(u16, slice[0]) == 0xDEAD);
|
||||
testing.expect(bigToNative(u16, slice[1]) == 0xBEEF);
|
||||
}
|
||||
|
||||
//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
|
||||
fn SliceAsBytesReturnType(comptime sliceType: type) type {
|
||||
if (comptime !trait.isSlice(sliceType)) {
|
||||
@compileError("expected []T, passed " ++ @typeName(sliceType));
|
||||
}
|
||||
|
||||
const alignment = comptime meta.alignment(sliceType);
|
||||
|
||||
return if (comptime trait.isConstPtr(sliceType)) []align(alignment) const u8 else []align(alignment) u8;
|
||||
}
|
||||
|
||||
pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {
|
||||
// let's not give an undefined pointer to @ptrCast
|
||||
// it may be equal to zero and fail a null check
|
||||
if (slice.len == 0) {
|
||||
return &[0]u8{};
|
||||
}
|
||||
|
||||
const sliceType = @TypeOf(slice);
|
||||
const alignment = comptime meta.alignment(sliceType);
|
||||
|
||||
const castTarget = if (comptime trait.isConstPtr(sliceType)) [*]align(alignment) const u8 else [*]align(alignment) u8;
|
||||
|
||||
return @ptrCast(castTarget, slice.ptr)[0 .. slice.len * @sizeOf(comptime meta.Child(sliceType))];
|
||||
}
|
||||
|
||||
test "sliceAsBytes" {
|
||||
const bytes = [_]u16{ 0xDEAD, 0xBEEF };
|
||||
const slice = sliceAsBytes(bytes[0..]);
|
||||
testing.expect(slice.len == 4);
|
||||
testing.expect(eql(u8, slice, switch (builtin.endian) {
|
||||
.Big => "\xDE\xAD\xBE\xEF",
|
||||
.Little => "\xAD\xDE\xEF\xBE",
|
||||
}));
|
||||
}
|
||||
|
||||
fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
|
||||
if (trait.isConstPtr(T))
|
||||
return *const [length]meta.Child(meta.Child(T));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user