| ... | @@ -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 | } |
| 1488 | | 1488 | |
| | 1489 | //TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues. |
| | 1490 | fn 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 | |
| | 1500 | pub 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 | |
| | 1515 | test "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. |
| | 1524 | fn 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 | |
| | 1534 | pub 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 | |
| | 1549 | test "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 | |
| 1489 | fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type { | 1559 | fn 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)); |