Given a slice, returns a slice of the underlying bytes, preserving pointer attributes.
pub fn sliceAsBytes(slice: anytype) SliceAsBytesReturnType(@TypeOf(slice))
pub fn sliceAsBytes(slice: anytype) SliceAsBytesReturnType(@TypeOf(slice)) {
const Slice = @TypeOf(slice);
// a slice of zero-bit values always occupies zero bytes
if (@sizeOf(std.meta.Elem(Slice)) == 0) return &[0]u8{};
// let's not give an undefined pointer to @ptrCast
// it may be equal to zero and fail a null check
if (slice.len == 0 and std.meta.sentinel(Slice) == null) return &[0]u8{};
const cast_target = CopyPtrAttrs(Slice, .many, u8);
return @as(cast_target, @ptrCast(slice))[0 .. slice.len * @sizeOf(std.meta.Elem(Slice))];
}