authorgravatar for 14938807+xackus@users.noreply.github.comxackus <14938807+xackus@users.noreply.github.com> 2020-02-20 20:01:52+01:00
committergravatar for 14938807+xackus@users.noreply.github.comxackus <14938807+xackus@users.noreply.github.com> 2020-02-21 19:40:29+01:00
logfdae5f5a07c043d9eeefe4933bcfbd03df581fde
tree08a5e112f1ebbcea1b6bbb13a10090611529ca81
parente381a42de9c0f0c5439a926b0ac99026a0373f49

implement bytesAsSlice, sliceAsBytes


1 files changed, 70 insertions(+), 0 deletions(-)

lib/std/mem.zig+70
...@@ -1486,6 +1486,76 @@ test "bytesToValue" {...@@ -1486,6 +1486,76 @@ test "bytesToValue" {
1486 testing.expect(deadbeef == @as(u32, 0xDEADBEEF));1486 testing.expect(deadbeef == @as(u32, 0xDEADBEEF));
1487}1487}
14881488
1489//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
1490fn BytesAsSliceReturnType(comptime T: type, comptime bytesType: type) type {
1491 if (comptime !trait.isSlice(bytesType) or comptime meta.Child(bytesType) != u8) {
1492 @compileError("expected []u8, passed " ++ @typeName(bytesType));
1493 }
1494
1495 const alignment = comptime meta.alignment(bytesType);
1496
1497 return if (comptime trait.isConstPtr(bytesType)) []align(alignment) const T else []align(alignment) T;
1498}
1499
1500pub fn bytesAsSlice(comptime T: type, bytes: var) BytesAsSliceReturnType(T, @TypeOf(bytes)) {
1501 // let's not give an undefined pointer to @ptrCast
1502 // it may be equal to zero and fail a null check
1503 if (bytes.len == 0) {
1504 return &[0]T{};
1505 }
1506
1507 const bytesType = @TypeOf(bytes);
1508 const alignment = comptime meta.alignment(bytesType);
1509
1510 const castTarget = if (comptime trait.isConstPtr(bytesType)) [*]align(alignment) const T else [*]align(alignment) T;
1511
1512 return @ptrCast(castTarget, bytes.ptr)[0..@divExact(bytes.len, @sizeOf(T))];
1513}
1514
1515test "bytesAsSlice" {
1516 const bytes = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
1517 const slice = bytesAsSlice(u16, bytes[0..]);
1518 testing.expect(slice.len == 2);
1519 testing.expect(bigToNative(u16, slice[0]) == 0xDEAD);
1520 testing.expect(bigToNative(u16, slice[1]) == 0xBEEF);
1521}
1522
1523//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
1524fn SliceAsBytesReturnType(comptime sliceType: type) type {
1525 if (comptime !trait.isSlice(sliceType)) {
1526 @compileError("expected []T, passed " ++ @typeName(sliceType));
1527 }
1528
1529 const alignment = comptime meta.alignment(sliceType);
1530
1531 return if (comptime trait.isConstPtr(sliceType)) []align(alignment) const u8 else []align(alignment) u8;
1532}
1533
1534pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {
1535 // let's not give an undefined pointer to @ptrCast
1536 // it may be equal to zero and fail a null check
1537 if (slice.len == 0) {
1538 return &[0]u8{};
1539 }
1540
1541 const sliceType = @TypeOf(slice);
1542 const alignment = comptime meta.alignment(sliceType);
1543
1544 const castTarget = if (comptime trait.isConstPtr(sliceType)) [*]align(alignment) const u8 else [*]align(alignment) u8;
1545
1546 return @ptrCast(castTarget, slice.ptr)[0 .. slice.len * @sizeOf(comptime meta.Child(sliceType))];
1547}
1548
1549test "sliceAsBytes" {
1550 const bytes = [_]u16{ 0xDEAD, 0xBEEF };
1551 const slice = sliceAsBytes(bytes[0..]);
1552 testing.expect(slice.len == 4);
1553 testing.expect(eql(u8, slice, switch (builtin.endian) {
1554 .Big => "\xDE\xAD\xBE\xEF",
1555 .Little => "\xAD\xDE\xEF\xBE",
1556 }));
1557}
1558
1489fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {1559fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
1490 if (trait.isConstPtr(T))1560 if (trait.isConstPtr(T))
1491 return *const [length]meta.Child(meta.Child(T));1561 return *const [length]meta.Child(meta.Child(T));