aboutsummaryrefslogtreecommitdiff
path: root/lib/std/mem.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-06-24 16:58:19 -0700
committerGitHub <noreply@github.com>2023-06-24 16:58:19 -0700
commit146b79af153bbd5dafda0ba12a040385c7fc58f8 (patch)
tree67e3db8b444d65c667e314770fc983a7fc8ba293 /lib/std/mem.zig
parent13853bef0df3c90633021850cc6d6abaeea03282 (diff)
parent21ac0beb436f49fe49c6982a872f2dc48e4bea5e (diff)
downloadzig-146b79af153bbd5dafda0ba12a040385c7fc58f8.tar.gz
zig-146b79af153bbd5dafda0ba12a040385c7fc58f8.zip
Merge pull request #16163 from mlugg/feat/builtins-infer-dest-ty
Infer destination type of cast builtins using result type
Diffstat (limited to 'lib/std/mem.zig')
-rw-r--r--lib/std/mem.zig223
1 files changed, 110 insertions, 113 deletions
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
index bbeecdda23..229bc0b63e 100644
--- a/lib/std/mem.zig
+++ b/lib/std/mem.zig
@@ -69,7 +69,7 @@ pub fn ValidationAllocator(comptime T: type) type {
ret_addr: usize,
) ?[*]u8 {
assert(n > 0);
- const self = @ptrCast(*Self, @alignCast(@alignOf(Self), ctx));
+ const self: *Self = @ptrCast(@alignCast(ctx));
const underlying = self.getUnderlyingAllocatorPtr();
const result = underlying.rawAlloc(n, log2_ptr_align, ret_addr) orelse
return null;
@@ -84,7 +84,7 @@ pub fn ValidationAllocator(comptime T: type) type {
new_len: usize,
ret_addr: usize,
) bool {
- const self = @ptrCast(*Self, @alignCast(@alignOf(Self), ctx));
+ const self: *Self = @ptrCast(@alignCast(ctx));
assert(buf.len > 0);
const underlying = self.getUnderlyingAllocatorPtr();
return underlying.rawResize(buf, log2_buf_align, new_len, ret_addr);
@@ -96,7 +96,7 @@ pub fn ValidationAllocator(comptime T: type) type {
log2_buf_align: u8,
ret_addr: usize,
) void {
- const self = @ptrCast(*Self, @alignCast(@alignOf(Self), ctx));
+ const self: *Self = @ptrCast(@alignCast(ctx));
assert(buf.len > 0);
const underlying = self.getUnderlyingAllocatorPtr();
underlying.rawFree(buf, log2_buf_align, ret_addr);
@@ -169,7 +169,7 @@ test "Allocator.resize" {
var values = try testing.allocator.alloc(T, 100);
defer testing.allocator.free(values);
- for (values, 0..) |*v, i| v.* = @intCast(T, i);
+ for (values, 0..) |*v, i| v.* = @as(T, @intCast(i));
if (!testing.allocator.resize(values, values.len + 10)) return error.OutOfMemory;
values = values.ptr[0 .. values.len + 10];
try testing.expect(values.len == 110);
@@ -185,7 +185,7 @@ test "Allocator.resize" {
var values = try testing.allocator.alloc(T, 100);
defer testing.allocator.free(values);
- for (values, 0..) |*v, i| v.* = @floatFromInt(T, i);
+ for (values, 0..) |*v, i| v.* = @as(T, @floatFromInt(i));
if (!testing.allocator.resize(values, values.len + 10)) return error.OutOfMemory;
values = values.ptr[0 .. values.len + 10];
try testing.expect(values.len == 110);
@@ -233,7 +233,7 @@ pub fn zeroes(comptime T: type) T {
return @as(T, 0);
},
.Enum, .EnumLiteral => {
- return @enumFromInt(T, 0);
+ return @as(T, @enumFromInt(0));
},
.Void => {
return {};
@@ -264,7 +264,7 @@ pub fn zeroes(comptime T: type) T {
switch (ptr_info.size) {
.Slice => {
if (ptr_info.sentinel) |sentinel| {
- if (ptr_info.child == u8 and @ptrCast(*const u8, sentinel).* == 0) {
+ if (ptr_info.child == u8 and @as(*const u8, @ptrCast(sentinel)).* == 0) {
return ""; // A special case for the most common use-case: null-terminated strings.
}
@compileError("Can't set a sentinel slice to zero. This would require allocating memory.");
@@ -282,7 +282,7 @@ pub fn zeroes(comptime T: type) T {
},
.Array => |info| {
if (info.sentinel) |sentinel_ptr| {
- const sentinel = @ptrCast(*align(1) const info.child, sentinel_ptr).*;
+ const sentinel = @as(*align(1) const info.child, @ptrCast(sentinel_ptr)).*;
return [_:sentinel]info.child{zeroes(info.child)} ** info.len;
}
return [_]info.child{zeroes(info.child)} ** info.len;
@@ -456,7 +456,7 @@ pub fn zeroInit(comptime T: type, init: anytype) T {
},
}
} else if (field.default_value) |default_value_ptr| {
- const default_value = @ptrCast(*align(1) const field.type, default_value_ptr).*;
+ const default_value = @as(*align(1) const field.type, @ptrCast(default_value_ptr)).*;
@field(value, field.name) = default_value;
} else {
switch (@typeInfo(field.type)) {
@@ -709,7 +709,7 @@ pub fn span(ptr: anytype) Span(@TypeOf(ptr)) {
const l = len(ptr);
const ptr_info = @typeInfo(Result).Pointer;
if (ptr_info.sentinel) |s_ptr| {
- const s = @ptrCast(*align(1) const ptr_info.child, s_ptr).*;
+ const s = @as(*align(1) const ptr_info.child, @ptrCast(s_ptr)).*;
return ptr[0..l :s];
} else {
return ptr[0..l];
@@ -740,7 +740,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type {
// to find the value searched for, which is only the case if it matches
// the sentinel of the type passed.
if (array_info.sentinel) |sentinel_ptr| {
- const sentinel = @ptrCast(*align(1) const array_info.child, sentinel_ptr).*;
+ const sentinel = @as(*align(1) const array_info.child, @ptrCast(sentinel_ptr)).*;
if (end == sentinel) {
new_ptr_info.sentinel = &end;
} else {
@@ -755,7 +755,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type {
// to find the value searched for, which is only the case if it matches
// the sentinel of the type passed.
if (ptr_info.sentinel) |sentinel_ptr| {
- const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*;
+ const sentinel = @as(*align(1) const ptr_info.child, @ptrCast(sentinel_ptr)).*;
if (end == sentinel) {
new_ptr_info.sentinel = &end;
} else {
@@ -793,7 +793,7 @@ pub fn sliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) SliceTo(@Typ
const length = lenSliceTo(ptr, end);
const ptr_info = @typeInfo(Result).Pointer;
if (ptr_info.sentinel) |s_ptr| {
- const s = @ptrCast(*align(1) const ptr_info.child, s_ptr).*;
+ const s = @as(*align(1) const ptr_info.child, @ptrCast(s_ptr)).*;
return ptr[0..length :s];
} else {
return ptr[0..length];
@@ -810,11 +810,11 @@ test "sliceTo" {
try testing.expectEqualSlices(u16, array[0..2], sliceTo(&array, 3));
try testing.expectEqualSlices(u16, array[0..2], sliceTo(array[0..3], 3));
- const sentinel_ptr = @ptrCast([*:5]u16, &array);
+ const sentinel_ptr = @as([*:5]u16, @ptrCast(&array));
try testing.expectEqualSlices(u16, array[0..2], sliceTo(sentinel_ptr, 3));
try testing.expectEqualSlices(u16, array[0..4], sliceTo(sentinel_ptr, 99));
- const optional_sentinel_ptr = @ptrCast(?[*:5]u16, &array);
+ const optional_sentinel_ptr = @as(?[*:5]u16, @ptrCast(&array));
try testing.expectEqualSlices(u16, array[0..2], sliceTo(optional_sentinel_ptr, 3).?);
try testing.expectEqualSlices(u16, array[0..4], sliceTo(optional_sentinel_ptr, 99).?);
@@ -846,7 +846,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize {
.One => switch (@typeInfo(ptr_info.child)) {
.Array => |array_info| {
if (array_info.sentinel) |sentinel_ptr| {
- const sentinel = @ptrCast(*align(1) const array_info.child, sentinel_ptr).*;
+ const sentinel = @as(*align(1) const array_info.child, @ptrCast(sentinel_ptr)).*;
if (sentinel == end) {
return indexOfSentinel(array_info.child, end, ptr);
}
@@ -856,7 +856,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize {
else => {},
},
.Many => if (ptr_info.sentinel) |sentinel_ptr| {
- const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*;
+ const sentinel = @as(*align(1) const ptr_info.child, @ptrCast(sentinel_ptr)).*;
// We may be looking for something other than the sentinel,
// but iterating past the sentinel would be a bug so we need
// to check for both.
@@ -870,7 +870,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize {
},
.Slice => {
if (ptr_info.sentinel) |sentinel_ptr| {
- const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*;
+ const sentinel = @as(*align(1) const ptr_info.child, @ptrCast(sentinel_ptr)).*;
if (sentinel == end) {
return indexOfSentinel(ptr_info.child, sentinel, ptr);
}
@@ -893,7 +893,7 @@ test "lenSliceTo" {
try testing.expectEqual(@as(usize, 2), lenSliceTo(&array, 3));
try testing.expectEqual(@as(usize, 2), lenSliceTo(array[0..3], 3));
- const sentinel_ptr = @ptrCast([*:5]u16, &array);
+ const sentinel_ptr = @as([*:5]u16, @ptrCast(&array));
try testing.expectEqual(@as(usize, 2), lenSliceTo(sentinel_ptr, 3));
try testing.expectEqual(@as(usize, 4), lenSliceTo(sentinel_ptr, 99));
@@ -925,7 +925,7 @@ pub fn len(value: anytype) usize {
.Many => {
const sentinel_ptr = info.sentinel orelse
@compileError("invalid type given to std.mem.len: " ++ @typeName(@TypeOf(value)));
- const sentinel = @ptrCast(*align(1) const info.child, sentinel_ptr).*;
+ const sentinel = @as(*align(1) const info.child, @ptrCast(sentinel_ptr)).*;
return indexOfSentinel(info.child, sentinel, value);
},
.C => {
@@ -1331,7 +1331,7 @@ pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: Endian)
.Little => {
const ShiftType = math.Log2Int(ReturnType);
for (bytes, 0..) |b, index| {
- result = result | (@as(ReturnType, b) << @intCast(ShiftType, index * 8));
+ result = result | (@as(ReturnType, b) << @as(ShiftType, @intCast(index * 8)));
}
},
}
@@ -1359,8 +1359,8 @@ pub fn readVarPackedInt(
const Log2N = std.math.Log2Int(T);
const read_size = (bit_count + (bit_offset % 8) + 7) / 8;
- const bit_shift = @intCast(u3, bit_offset % 8);
- const pad = @intCast(Log2N, @bitSizeOf(T) - bit_count);
+ const bit_shift = @as(u3, @intCast(bit_offset % 8));
+ const pad = @as(Log2N, @intCast(@bitSizeOf(T) - bit_count));
const lowest_byte = switch (endian) {
.Big => bytes.len - (bit_offset / 8) - read_size,
@@ -1372,17 +1372,17 @@ pub fn readVarPackedInt(
// These are the same shifts/masks we perform below, but adds `@truncate`/`@intCast`
// where needed since int is smaller than a byte.
const value = if (read_size == 1) b: {
- break :b @truncate(uN, read_bytes[0] >> bit_shift);
+ break :b @as(uN, @truncate(read_bytes[0] >> bit_shift));
} else b: {
const i: u1 = @intFromBool(endian == .Big);
- const head = @truncate(uN, read_bytes[i] >> bit_shift);
- const tail_shift = @intCast(Log2N, @as(u4, 8) - bit_shift);
- const tail = @truncate(uN, read_bytes[1 - i]);
+ const head = @as(uN, @truncate(read_bytes[i] >> bit_shift));
+ const tail_shift = @as(Log2N, @intCast(@as(u4, 8) - bit_shift));
+ const tail = @as(uN, @truncate(read_bytes[1 - i]));
break :b (tail << tail_shift) | head;
};
switch (signedness) {
- .signed => return @intCast(T, (@bitCast(iN, value) << pad) >> pad),
- .unsigned => return @intCast(T, (@bitCast(uN, value) << pad) >> pad),
+ .signed => return @as(T, @intCast((@as(iN, @bitCast(value)) << pad) >> pad)),
+ .unsigned => return @as(T, @intCast((@as(uN, @bitCast(value)) << pad) >> pad)),
}
}
@@ -1398,13 +1398,13 @@ pub fn readVarPackedInt(
.Little => {
int = read_bytes[0] >> bit_shift;
for (read_bytes[1..], 0..) |elem, i| {
- int |= (@as(uN, elem) << @intCast(Log2N, (8 * (i + 1) - bit_shift)));
+ int |= (@as(uN, elem) << @as(Log2N, @intCast((8 * (i + 1) - bit_shift))));
}
},
}
switch (signedness) {
- .signed => return @intCast(T, (@bitCast(iN, int) << pad) >> pad),
- .unsigned => return @intCast(T, (@bitCast(uN, int) << pad) >> pad),
+ .signed => return @as(T, @intCast((@as(iN, @bitCast(int)) << pad) >> pad)),
+ .unsigned => return @as(T, @intCast((@as(uN, @bitCast(int)) << pad) >> pad)),
}
}
@@ -1414,7 +1414,7 @@ pub fn readVarPackedInt(
/// Assumes the endianness of memory is native. This means the function can
/// simply pointer cast memory.
pub fn readIntNative(comptime T: type, bytes: *const [@divExact(@typeInfo(T).Int.bits, 8)]u8) T {
- return @ptrCast(*align(1) const T, bytes).*;
+ return @as(*align(1) const T, @ptrCast(bytes)).*;
}
/// Reads an integer from memory with bit count specified by T.
@@ -1480,10 +1480,10 @@ fn readPackedIntLittle(comptime T: type, bytes: []const u8, bit_offset: usize) T
const Log2N = std.math.Log2Int(T);
const bit_count = @as(usize, @bitSizeOf(T));
- const bit_shift = @intCast(u3, bit_offset % 8);
+ const bit_shift = @as(u3, @intCast(bit_offset % 8));
const load_size = (bit_count + 7) / 8;
- const load_tail_bits = @intCast(u3, (load_size * 8) - bit_count);
+ const load_tail_bits = @as(u3, @intCast((load_size * 8) - bit_count));
const LoadInt = std.meta.Int(.unsigned, load_size * 8);
if (bit_count == 0)
@@ -1492,13 +1492,13 @@ fn readPackedIntLittle(comptime T: type, bytes: []const u8, bit_offset: usize) T
// Read by loading a LoadInt, and then follow it up with a 1-byte read
// of the tail if bit_offset pushed us over a byte boundary.
const read_bytes = bytes[bit_offset / 8 ..];
- const val = @truncate(uN, readIntLittle(LoadInt, read_bytes[0..load_size]) >> bit_shift);
+ const val = @as(uN, @truncate(readIntLittle(LoadInt, read_bytes[0..load_size]) >> bit_shift));
if (bit_shift > load_tail_bits) {
- const tail_bits = @intCast(Log2N, bit_shift - load_tail_bits);
+ const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits));
const tail_byte = read_bytes[load_size];
- const tail_truncated = if (bit_count < 8) @truncate(uN, tail_byte) else @as(uN, tail_byte);
- return @bitCast(T, val | (tail_truncated << (@truncate(Log2N, bit_count) -% tail_bits)));
- } else return @bitCast(T, val);
+ const tail_truncated = if (bit_count < 8) @as(uN, @truncate(tail_byte)) else @as(uN, tail_byte);
+ return @as(T, @bitCast(val | (tail_truncated << (@as(Log2N, @truncate(bit_count)) -% tail_bits))));
+ } else return @as(T, @bitCast(val));
}
fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T {
@@ -1506,11 +1506,11 @@ fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T {
const Log2N = std.math.Log2Int(T);
const bit_count = @as(usize, @bitSizeOf(T));
- const bit_shift = @intCast(u3, bit_offset % 8);
+ const bit_shift = @as(u3, @intCast(bit_offset % 8));
const byte_count = (@as(usize, bit_shift) + bit_count + 7) / 8;
const load_size = (bit_count + 7) / 8;
- const load_tail_bits = @intCast(u3, (load_size * 8) - bit_count);
+ const load_tail_bits = @as(u3, @intCast((load_size * 8) - bit_count));
const LoadInt = std.meta.Int(.unsigned, load_size * 8);
if (bit_count == 0)
@@ -1520,12 +1520,12 @@ fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T {
// of the tail if bit_offset pushed us over a byte boundary.
const end = bytes.len - (bit_offset / 8);
const read_bytes = bytes[(end - byte_count)..end];
- const val = @truncate(uN, readIntBig(LoadInt, bytes[(end - load_size)..end][0..load_size]) >> bit_shift);
+ const val = @as(uN, @truncate(readIntBig(LoadInt, bytes[(end - load_size)..end][0..load_size]) >> bit_shift));
if (bit_shift > load_tail_bits) {
- const tail_bits = @intCast(Log2N, bit_shift - load_tail_bits);
- const tail_byte = if (bit_count < 8) @truncate(uN, read_bytes[0]) else @as(uN, read_bytes[0]);
- return @bitCast(T, val | (tail_byte << (@truncate(Log2N, bit_count) -% tail_bits)));
- } else return @bitCast(T, val);
+ const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits));
+ const tail_byte = if (bit_count < 8) @as(uN, @truncate(read_bytes[0])) else @as(uN, read_bytes[0]);
+ return @as(T, @bitCast(val | (tail_byte << (@as(Log2N, @truncate(bit_count)) -% tail_bits))));
+ } else return @as(T, @bitCast(val));
}
pub const readPackedIntNative = switch (native_endian) {
@@ -1605,7 +1605,7 @@ test "readIntBig and readIntLittle" {
/// This function stores in native endian, which means it is implemented as a simple
/// memory store.
pub fn writeIntNative(comptime T: type, buf: *[(@typeInfo(T).Int.bits + 7) / 8]u8, value: T) void {
- @ptrCast(*align(1) T, buf).* = value;
+ @as(*align(1) T, @ptrCast(buf)).* = value;
}
/// Writes an integer to memory, storing it in twos-complement.
@@ -1642,10 +1642,10 @@ fn writePackedIntLittle(comptime T: type, bytes: []u8, bit_offset: usize, value:
const Log2N = std.math.Log2Int(T);
const bit_count = @as(usize, @bitSizeOf(T));
- const bit_shift = @intCast(u3, bit_offset % 8);
+ const bit_shift = @as(u3, @intCast(bit_offset % 8));
const store_size = (@bitSizeOf(T) + 7) / 8;
- const store_tail_bits = @intCast(u3, (store_size * 8) - bit_count);
+ const store_tail_bits = @as(u3, @intCast((store_size * 8) - bit_count));
const StoreInt = std.meta.Int(.unsigned, store_size * 8);
if (bit_count == 0)
@@ -1656,11 +1656,11 @@ fn writePackedIntLittle(comptime T: type, bytes: []u8, bit_offset: usize, value:
const write_bytes = bytes[bit_offset / 8 ..];
const head = write_bytes[0] & ((@as(u8, 1) << bit_shift) - 1);
- var write_value = (@as(StoreInt, @bitCast(uN, value)) << bit_shift) | @intCast(StoreInt, head);
+ var write_value = (@as(StoreInt, @as(uN, @bitCast(value))) << bit_shift) | @as(StoreInt, @intCast(head));
if (bit_shift > store_tail_bits) {
- const tail_len = @intCast(Log2N, bit_shift - store_tail_bits);
- write_bytes[store_size] &= ~((@as(u8, 1) << @intCast(u3, tail_len)) - 1);
- write_bytes[store_size] |= @intCast(u8, (@bitCast(uN, value) >> (@truncate(Log2N, bit_count) -% tail_len)));
+ const tail_len = @as(Log2N, @intCast(bit_shift - store_tail_bits));
+ write_bytes[store_size] &= ~((@as(u8, 1) << @as(u3, @intCast(tail_len))) - 1);
+ write_bytes[store_size] |= @as(u8, @intCast((@as(uN, @bitCast(value)) >> (@as(Log2N, @truncate(bit_count)) -% tail_len))));
} else if (bit_shift < store_tail_bits) {
const tail_len = store_tail_bits - bit_shift;
const tail = write_bytes[store_size - 1] & (@as(u8, 0xfe) << (7 - tail_len));
@@ -1675,11 +1675,11 @@ fn writePackedIntBig(comptime T: type, bytes: []u8, bit_offset: usize, value: T)
const Log2N = std.math.Log2Int(T);
const bit_count = @as(usize, @bitSizeOf(T));
- const bit_shift = @intCast(u3, bit_offset % 8);
+ const bit_shift = @as(u3, @intCast(bit_offset % 8));
const byte_count = (bit_shift + bit_count + 7) / 8;
const store_size = (@bitSizeOf(T) + 7) / 8;
- const store_tail_bits = @intCast(u3, (store_size * 8) - bit_count);
+ const store_tail_bits = @as(u3, @intCast((store_size * 8) - bit_count));
const StoreInt = std.meta.Int(.unsigned, store_size * 8);
if (bit_count == 0)
@@ -1691,11 +1691,11 @@ fn writePackedIntBig(comptime T: type, bytes: []u8, bit_offset: usize, value: T)
const write_bytes = bytes[(end - byte_count)..end];
const head = write_bytes[byte_count - 1] & ((@as(u8, 1) << bit_shift) - 1);
- var write_value = (@as(StoreInt, @bitCast(uN, value)) << bit_shift) | @intCast(StoreInt, head);
+ var write_value = (@as(StoreInt, @as(uN, @bitCast(value))) << bit_shift) | @as(StoreInt, @intCast(head));
if (bit_shift > store_tail_bits) {
- const tail_len = @intCast(Log2N, bit_shift - store_tail_bits);
- write_bytes[0] &= ~((@as(u8, 1) << @intCast(u3, tail_len)) - 1);
- write_bytes[0] |= @intCast(u8, (@bitCast(uN, value) >> (@truncate(Log2N, bit_count) -% tail_len)));
+ const tail_len = @as(Log2N, @intCast(bit_shift - store_tail_bits));
+ write_bytes[0] &= ~((@as(u8, 1) << @as(u3, @intCast(tail_len))) - 1);
+ write_bytes[0] |= @as(u8, @intCast((@as(uN, @bitCast(value)) >> (@as(Log2N, @truncate(bit_count)) -% tail_len))));
} else if (bit_shift < store_tail_bits) {
const tail_len = store_tail_bits - bit_shift;
const tail = write_bytes[0] & (@as(u8, 0xfe) << (7 - tail_len));
@@ -1744,14 +1744,14 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
return @memset(buffer, 0);
} else if (@typeInfo(T).Int.bits == 8) {
@memset(buffer, 0);
- buffer[0] = @bitCast(u8, value);
+ 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 = @bitCast(uint, value);
+ var bits = @as(uint, @bitCast(value));
for (buffer) |*b| {
- b.* = @truncate(u8, bits);
+ b.* = @as(u8, @truncate(bits));
bits >>= 8;
}
}
@@ -1768,17 +1768,17 @@ pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {
return @memset(buffer, 0);
} else if (@typeInfo(T).Int.bits == 8) {
@memset(buffer, 0);
- buffer[buffer.len - 1] = @bitCast(u8, value);
+ buffer[buffer.len - 1] = @as(u8, @bitCast(value));
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 = @bitCast(uint, value);
+ var bits = @as(uint, @bitCast(value));
var index: usize = buffer.len;
while (index != 0) {
index -= 1;
- buffer[index] = @truncate(u8, bits);
+ buffer[index] = @as(u8, @truncate(bits));
bits >>= 8;
}
}
@@ -1822,7 +1822,7 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
const uN = std.meta.Int(.unsigned, @bitSizeOf(T));
const Log2N = std.math.Log2Int(T);
- const bit_shift = @intCast(u3, bit_offset % 8);
+ const bit_shift = @as(u3, @intCast(bit_offset % 8));
const write_size = (bit_count + bit_shift + 7) / 8;
const lowest_byte = switch (endian) {
.Big => bytes.len - (bit_offset / 8) - write_size,
@@ -1833,8 +1833,8 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
if (write_size == 1) {
// Single byte writes are handled specially, since we need to mask bits
// on both ends of the byte.
- const mask = (@as(u8, 0xff) >> @intCast(u3, 8 - bit_count));
- const new_bits = @intCast(u8, @bitCast(uN, value) & mask) << bit_shift;
+ const mask = (@as(u8, 0xff) >> @as(u3, @intCast(8 - bit_count)));
+ const new_bits = @as(u8, @intCast(@as(uN, @bitCast(value)) & mask)) << bit_shift;
write_bytes[0] = (write_bytes[0] & ~(mask << bit_shift)) | new_bits;
return;
}
@@ -1843,31 +1843,31 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
// Iterate bytes forward for Little-endian, backward for Big-endian
const delta: i2 = if (endian == .Big) -1 else 1;
- const start = if (endian == .Big) @intCast(isize, write_bytes.len - 1) else 0;
+ const start = if (endian == .Big) @as(isize, @intCast(write_bytes.len - 1)) else 0;
var i: isize = start; // isize for signed index arithmetic
// Write first byte, using a mask to protects bits preceding bit_offset
const head_mask = @as(u8, 0xff) >> bit_shift;
- write_bytes[@intCast(usize, i)] &= ~(head_mask << bit_shift);
- write_bytes[@intCast(usize, i)] |= @intCast(u8, @bitCast(uN, remaining) & head_mask) << bit_shift;
- remaining >>= @intCast(Log2N, @as(u4, 8) - bit_shift);
+ write_bytes[@as(usize, @intCast(i))] &= ~(head_mask << bit_shift);
+ write_bytes[@as(usize, @intCast(i))] |= @as(u8, @intCast(@as(uN, @bitCast(remaining)) & head_mask)) << bit_shift;
+ remaining >>= @as(Log2N, @intCast(@as(u4, 8) - bit_shift));
i += delta;
// Write bytes[1..bytes.len - 1]
if (@bitSizeOf(T) > 8) {
- const loop_end = start + delta * (@intCast(isize, write_size) - 1);
+ const loop_end = start + delta * (@as(isize, @intCast(write_size)) - 1);
while (i != loop_end) : (i += delta) {
- write_bytes[@intCast(usize, i)] = @truncate(u8, @bitCast(uN, remaining));
+ write_bytes[@as(usize, @intCast(i))] = @as(u8, @truncate(@as(uN, @bitCast(remaining))));
remaining >>= 8;
}
}
// Write last byte, using a mask to protect bits following bit_offset + bit_count
- const following_bits = -%@truncate(u3, bit_shift + bit_count);
+ const following_bits = -%@as(u3, @truncate(bit_shift + bit_count));
const tail_mask = (@as(u8, 0xff) << following_bits) >> following_bits;
- write_bytes[@intCast(usize, i)] &= ~tail_mask;
- write_bytes[@intCast(usize, i)] |= @intCast(u8, @bitCast(uN, remaining) & tail_mask);
+ write_bytes[@as(usize, @intCast(i))] &= ~tail_mask;
+ write_bytes[@as(usize, @intCast(i))] |= @as(u8, @intCast(@as(uN, @bitCast(remaining)) & tail_mask));
}
test "writeIntBig and writeIntLittle" {
@@ -3799,15 +3799,14 @@ pub fn alignPointerOffset(ptr: anytype, align_to: usize) ?usize {
/// type.
pub fn alignPointer(ptr: anytype, align_to: usize) ?@TypeOf(ptr) {
const adjust_off = alignPointerOffset(ptr, align_to) orelse return null;
- const T = @TypeOf(ptr);
// Avoid the use of ptrFromInt to avoid losing the pointer provenance info.
- return @alignCast(@typeInfo(T).Pointer.alignment, ptr + adjust_off);
+ return @alignCast(ptr + adjust_off);
}
test "alignPointer" {
const S = struct {
fn checkAlign(comptime T: type, base: usize, align_to: usize, expected: usize) !void {
- var ptr = @ptrFromInt(T, base);
+ var ptr = @as(T, @ptrFromInt(base));
var aligned = alignPointer(ptr, align_to);
try testing.expectEqual(expected, @intFromPtr(aligned));
}
@@ -3854,9 +3853,7 @@ fn AsBytesReturnType(comptime P: type) type {
/// Given a pointer to a single item, returns a slice of the underlying bytes, preserving pointer attributes.
pub fn asBytes(ptr: anytype) AsBytesReturnType(@TypeOf(ptr)) {
- const P = @TypeOf(ptr);
- const T = AsBytesReturnType(P);
- return @ptrCast(T, @alignCast(meta.alignment(T), ptr));
+ return @ptrCast(@alignCast(ptr));
}
test "asBytes" {
@@ -3902,7 +3899,7 @@ test "asBytes" {
test "asBytes preserves pointer attributes" {
const inArr: u32 align(16) = 0xDEADBEEF;
- const inPtr = @ptrCast(*align(16) const volatile u32, &inArr);
+ const inPtr = @as(*align(16) const volatile u32, @ptrCast(&inArr));
const outSlice = asBytes(inPtr);
const in = @typeInfo(@TypeOf(inPtr)).Pointer;
@@ -3948,7 +3945,7 @@ fn BytesAsValueReturnType(comptime T: type, comptime B: type) type {
/// Given a pointer to an array of bytes, returns a pointer to a value of the specified type
/// backed by those bytes, preserving pointer attributes.
pub fn bytesAsValue(comptime T: type, bytes: anytype) BytesAsValueReturnType(T, @TypeOf(bytes)) {
- return @ptrCast(BytesAsValueReturnType(T, @TypeOf(bytes)), bytes);
+ return @as(BytesAsValueReturnType(T, @TypeOf(bytes)), @ptrCast(bytes));
}
test "bytesAsValue" {
@@ -3993,7 +3990,7 @@ test "bytesAsValue" {
test "bytesAsValue preserves pointer attributes" {
const inArr align(16) = [4]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
- const inSlice = @ptrCast(*align(16) const volatile [4]u8, &inArr)[0..];
+ const inSlice = @as(*align(16) const volatile [4]u8, @ptrCast(&inArr))[0..];
const outPtr = bytesAsValue(u32, inSlice);
const in = @typeInfo(@TypeOf(inSlice)).Pointer;
@@ -4043,7 +4040,7 @@ pub fn bytesAsSlice(comptime T: type, bytes: anytype) BytesAsSliceReturnType(T,
const cast_target = CopyPtrAttrs(@TypeOf(bytes), .Many, T);
- return @ptrCast(cast_target, bytes)[0..@divExact(bytes.len, @sizeOf(T))];
+ return @as(cast_target, @ptrCast(bytes))[0..@divExact(bytes.len, @sizeOf(T))];
}
test "bytesAsSlice" {
@@ -4101,7 +4098,7 @@ test "bytesAsSlice with specified alignment" {
test "bytesAsSlice preserves pointer attributes" {
const inArr align(16) = [4]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
- const inSlice = @ptrCast(*align(16) const volatile [4]u8, &inArr)[0..];
+ const inSlice = @as(*align(16) const volatile [4]u8, @ptrCast(&inArr))[0..];
const outSlice = bytesAsSlice(u16, inSlice);
const in = @typeInfo(@TypeOf(inSlice)).Pointer;
@@ -4133,7 +4130,7 @@ pub fn sliceAsBytes(slice: anytype) SliceAsBytesReturnType(@TypeOf(slice)) {
const cast_target = CopyPtrAttrs(Slice, .Many, u8);
- return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Elem(Slice))];
+ return @as(cast_target, @ptrCast(slice))[0 .. slice.len * @sizeOf(meta.Elem(Slice))];
}
test "sliceAsBytes" {
@@ -4197,7 +4194,7 @@ test "sliceAsBytes and bytesAsSlice back" {
test "sliceAsBytes preserves pointer attributes" {
const inArr align(16) = [2]u16{ 0xDEAD, 0xBEEF };
- const inSlice = @ptrCast(*align(16) const volatile [2]u16, &inArr)[0..];
+ const inSlice = @as(*align(16) const volatile [2]u16, @ptrCast(&inArr))[0..];
const outSlice = sliceAsBytes(inSlice);
const in = @typeInfo(@TypeOf(inSlice)).Pointer;
@@ -4218,7 +4215,7 @@ pub fn alignForward(comptime T: type, addr: T, alignment: T) T {
}
pub fn alignForwardLog2(addr: usize, log2_alignment: u8) usize {
- const alignment = @as(usize, 1) << @intCast(math.Log2Int(usize), log2_alignment);
+ const alignment = @as(usize, 1) << @as(math.Log2Int(usize), @intCast(log2_alignment));
return alignForward(usize, addr, alignment);
}
@@ -4282,7 +4279,7 @@ pub fn doNotOptimizeAway(val: anytype) void {
/// .stage2_c doesn't support asm blocks yet, so use volatile stores instead
var deopt_target: if (builtin.zig_backend == .stage2_c) u8 else void = undefined;
fn doNotOptimizeAwayC(ptr: anytype) void {
- const dest = @ptrCast(*volatile u8, &deopt_target);
+ const dest = @as(*volatile u8, @ptrCast(&deopt_target));
for (asBytes(ptr)) |b| {
dest.* = b;
}
@@ -4433,7 +4430,7 @@ pub fn alignInBytes(bytes: []u8, comptime new_alignment: usize) ?[]align(new_ali
error.Overflow => return null,
};
const alignment_offset = begin_address_aligned - begin_address;
- return @alignCast(new_alignment, bytes[alignment_offset .. alignment_offset + new_length]);
+ return @alignCast(bytes[alignment_offset .. alignment_offset + new_length]);
}
/// Returns the largest sub-slice within the given slice that conforms to the new alignment,
@@ -4445,7 +4442,7 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice
const Element = @TypeOf(slice[0]);
const slice_length_bytes = aligned_bytes.len - (aligned_bytes.len % @sizeOf(Element));
const aligned_slice = bytesAsSlice(Element, aligned_bytes[0..slice_length_bytes]);
- return @alignCast(new_alignment, aligned_slice);
+ return @alignCast(aligned_slice);
}
test "read/write(Var)PackedInt" {
@@ -4490,8 +4487,8 @@ test "read/write(Var)PackedInt" {
for ([_]PackedType{
~@as(PackedType, 0), // all ones: -1 iN / maxInt uN
@as(PackedType, 0), // all zeros: 0 iN / 0 uN
- @bitCast(PackedType, @as(iPackedType, math.maxInt(iPackedType))), // maxInt iN
- @bitCast(PackedType, @as(iPackedType, math.minInt(iPackedType))), // maxInt iN
+ @as(PackedType, @bitCast(@as(iPackedType, math.maxInt(iPackedType)))), // maxInt iN
+ @as(PackedType, @bitCast(@as(iPackedType, math.minInt(iPackedType)))), // maxInt iN
random.int(PackedType), // random
random.int(PackedType), // random
}) |write_value| {
@@ -4502,11 +4499,11 @@ test "read/write(Var)PackedInt" {
// Read
const read_value1 = readPackedInt(PackedType, asBytes(&value), offset, native_endian);
- try expect(read_value1 == @bitCast(PackedType, @truncate(uPackedType, value >> @intCast(Log2T, offset))));
+ try expect(read_value1 == @as(PackedType, @bitCast(@as(uPackedType, @truncate(value >> @as(Log2T, @intCast(offset)))))));
// Write
writePackedInt(PackedType, asBytes(&value), offset, write_value, native_endian);
- try expect(write_value == @bitCast(PackedType, @truncate(uPackedType, value >> @intCast(Log2T, offset))));
+ try expect(write_value == @as(PackedType, @bitCast(@as(uPackedType, @truncate(value >> @as(Log2T, @intCast(offset)))))));
// Read again
const read_value2 = readPackedInt(PackedType, asBytes(&value), offset, native_endian);
@@ -4515,9 +4512,9 @@ test "read/write(Var)PackedInt" {
// Verify bits outside of the target integer are unmodified
const diff_bits = init_value ^ value;
if (offset != offset_at_end)
- try expect(diff_bits >> @intCast(Log2T, offset + @bitSizeOf(PackedType)) == 0);
+ try expect(diff_bits >> @as(Log2T, @intCast(offset + @bitSizeOf(PackedType))) == 0);
if (offset != 0)
- try expect(diff_bits << @intCast(Log2T, @bitSizeOf(BackingType) - offset) == 0);
+ try expect(diff_bits << @as(Log2T, @intCast(@bitSizeOf(BackingType) - offset)) == 0);
}
{ // Fixed-size Read/Write (Foreign-endian)
@@ -4527,11 +4524,11 @@ test "read/write(Var)PackedInt" {
// Read
const read_value1 = readPackedInt(PackedType, asBytes(&value), offset, foreign_endian);
- try expect(read_value1 == @bitCast(PackedType, @truncate(uPackedType, @byteSwap(value) >> @intCast(Log2T, offset))));
+ try expect(read_value1 == @as(PackedType, @bitCast(@as(uPackedType, @truncate(@byteSwap(value) >> @as(Log2T, @intCast(offset)))))));
// Write
writePackedInt(PackedType, asBytes(&value), offset, write_value, foreign_endian);
- try expect(write_value == @bitCast(PackedType, @truncate(uPackedType, @byteSwap(value) >> @intCast(Log2T, offset))));
+ try expect(write_value == @as(PackedType, @bitCast(@as(uPackedType, @truncate(@byteSwap(value) >> @as(Log2T, @intCast(offset)))))));
// Read again
const read_value2 = readPackedInt(PackedType, asBytes(&value), offset, foreign_endian);
@@ -4540,9 +4537,9 @@ test "read/write(Var)PackedInt" {
// Verify bits outside of the target integer are unmodified
const diff_bits = init_value ^ @byteSwap(value);
if (offset != offset_at_end)
- try expect(diff_bits >> @intCast(Log2T, offset + @bitSizeOf(PackedType)) == 0);
+ try expect(diff_bits >> @as(Log2T, @intCast(offset + @bitSizeOf(PackedType))) == 0);
if (offset != 0)
- try expect(diff_bits << @intCast(Log2T, @bitSizeOf(BackingType) - offset) == 0);
+ try expect(diff_bits << @as(Log2T, @intCast(@bitSizeOf(BackingType) - offset)) == 0);
}
const signedness = @typeInfo(PackedType).Int.signedness;
@@ -4559,11 +4556,11 @@ test "read/write(Var)PackedInt" {
// Read
const read_value1 = readVarPackedInt(U, asBytes(&value), offset, @bitSizeOf(PackedType), native_endian, signedness);
- try expect(read_value1 == @bitCast(PackedType, @truncate(uPackedType, value >> @intCast(Log2T, offset))));
+ try expect(read_value1 == @as(PackedType, @bitCast(@as(uPackedType, @truncate(value >> @as(Log2T, @intCast(offset)))))));
// Write
writeVarPackedInt(asBytes(&value), offset, @bitSizeOf(PackedType), @as(U, write_value), native_endian);
- try expect(write_value == @bitCast(PackedType, @truncate(uPackedType, value >> @intCast(Log2T, offset))));
+ try expect(write_value == @as(PackedType, @bitCast(@as(uPackedType, @truncate(value >> @as(Log2T, @intCast(offset)))))));
// Read again
const read_value2 = readVarPackedInt(U, asBytes(&value), offset, @bitSizeOf(PackedType), native_endian, signedness);
@@ -4572,9 +4569,9 @@ test "read/write(Var)PackedInt" {
// Verify bits outside of the target integer are unmodified
const diff_bits = init_value ^ value;
if (offset != offset_at_end)
- try expect(diff_bits >> @intCast(Log2T, offset + @bitSizeOf(PackedType)) == 0);
+ try expect(diff_bits >> @as(Log2T, @intCast(offset + @bitSizeOf(PackedType))) == 0);
if (offset != 0)
- try expect(diff_bits << @intCast(Log2T, @bitSizeOf(BackingType) - offset) == 0);
+ try expect(diff_bits << @as(Log2T, @intCast(@bitSizeOf(BackingType) - offset)) == 0);
}
{ // Variable-size Read/Write (Foreign-endian)
@@ -4587,11 +4584,11 @@ test "read/write(Var)PackedInt" {
// Read
const read_value1 = readVarPackedInt(U, asBytes(&value), offset, @bitSizeOf(PackedType), foreign_endian, signedness);
- try expect(read_value1 == @bitCast(PackedType, @truncate(uPackedType, @byteSwap(value) >> @intCast(Log2T, offset))));
+ try expect(read_value1 == @as(PackedType, @bitCast(@as(uPackedType, @truncate(@byteSwap(value) >> @as(Log2T, @intCast(offset)))))));
// Write
writeVarPackedInt(asBytes(&value), offset, @bitSizeOf(PackedType), @as(U, write_value), foreign_endian);
- try expect(write_value == @bitCast(PackedType, @truncate(uPackedType, @byteSwap(value) >> @intCast(Log2T, offset))));
+ try expect(write_value == @as(PackedType, @bitCast(@as(uPackedType, @truncate(@byteSwap(value) >> @as(Log2T, @intCast(offset)))))));
// Read again
const read_value2 = readVarPackedInt(U, asBytes(&value), offset, @bitSizeOf(PackedType), foreign_endian, signedness);
@@ -4600,9 +4597,9 @@ test "read/write(Var)PackedInt" {
// Verify bits outside of the target integer are unmodified
const diff_bits = init_value ^ @byteSwap(value);
if (offset != offset_at_end)
- try expect(diff_bits >> @intCast(Log2T, offset + @bitSizeOf(PackedType)) == 0);
+ try expect(diff_bits >> @as(Log2T, @intCast(offset + @bitSizeOf(PackedType))) == 0);
if (offset != 0)
- try expect(diff_bits << @intCast(Log2T, @bitSizeOf(BackingType) - offset) == 0);
+ try expect(diff_bits << @as(Log2T, @intCast(@bitSizeOf(BackingType) - offset)) == 0);
}
}
}