authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-05 14:48:54-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-05 15:08:51-07:00
log1e5d24a009ffef49f0888b3d6ea46aec8a82d40b
treea6e16c36365387b062c72e12919b5d04f7af28ad
parentc9533046ca37a053f487f4002a999a29a96de517

std: extract mem.Allocator.SliceType to meta.Slice


2 files changed, 37 insertions(+), 31 deletions(-)

lib/std/mem/Allocator.zig+8-26
......@@ -8,6 +8,7 @@ const assert = std.debug.assert;
88const math = std.math;
99const mem = std.mem;
1010const Alignment = std.mem.Alignment;
11const Slice = std.meta.Slice;
1112
1213pub const Error = error{OutOfMemory};
1314pub const Log2Align = math.Log2Int(usize);
......@@ -305,25 +306,6 @@ pub fn allocBytesAligned(
305306 return @alignCast(byte_ptr);
306307}
307308
308fn SliceType(comptime Pointer: type) type {
309 const info = @typeInfo(Pointer).pointer;
310 switch (info.size) {
311 .slice => return Pointer,
312 .one => {
313 const child_info = @typeInfo(info.child);
314 comptime assert(child_info == .array);
315 const sentinel_ptr: ?*const child_info.array.child = @ptrCast(@alignCast(child_info.array.sentinel_ptr));
316 return @Pointer(
317 .slice,
318 info.attrs,
319 child_info.array.child,
320 if (sentinel_ptr) |ptr| ptr.* else null,
321 );
322 },
323 else => unreachable,
324 }
325}
326
327309/// Request to modify the size of an allocation.
328310///
329311/// It is guaranteed to not move the pointer, however the allocator
......@@ -336,7 +318,7 @@ fn SliceType(comptime Pointer: type) type {
336318pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
337319 const slice_info = @typeInfo(@TypeOf(allocation)).pointer;
338320 if (slice_info.size != .slice) {
339 const slice: SliceType(@TypeOf(allocation)) = allocation; // coerce *[len]T to []T
321 const slice: Slice(@TypeOf(allocation)) = allocation; // coerce *[len]T to []T
340322 return resize(self, slice, new_len);
341323 }
342324 comptime assert(slice_info.size == .slice);
......@@ -377,10 +359,10 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
377359/// `new_len` may be zero, in which case the allocation is freed.
378360///
379361/// If the allocation's elements' type is zero bytes sized, `allocation.len` is set to `new_len`.
380pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?SliceType(@TypeOf(allocation)) {
362pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?Slice(@TypeOf(allocation)) {
381363 const slice_info = @typeInfo(@TypeOf(allocation)).pointer;
382364 if (slice_info.size != .slice) {
383 const slice: SliceType(@TypeOf(allocation)) = allocation; // coerce *[len]T to []T
365 const slice: Slice(@TypeOf(allocation)) = allocation; // coerce *[len]T to []T
384366 return remap(self, slice, new_len);
385367 }
386368 comptime assert(slice_info.size == .slice);
......@@ -426,7 +408,7 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?SliceType(@T
426408/// do the realloc more efficiently than the caller
427409/// * `resize` which returns `false` when the `Allocator` implementation cannot
428410/// change the size without relocating the allocation.
429pub fn realloc(self: Allocator, old_mem: anytype, new_n: usize) Error!SliceType(@TypeOf(old_mem)) {
411pub fn realloc(self: Allocator, old_mem: anytype, new_n: usize) Error!Slice(@TypeOf(old_mem)) {
430412 return self.reallocAdvanced(old_mem, new_n, @returnAddress());
431413}
432414
......@@ -435,10 +417,10 @@ pub fn reallocAdvanced(
435417 old_mem: anytype,
436418 new_n: usize,
437419 return_address: usize,
438) Error!SliceType(@TypeOf(old_mem)) {
420) Error!Slice(@TypeOf(old_mem)) {
439421 const slice_info = @typeInfo(@TypeOf(old_mem)).pointer;
440422 if (slice_info.size != .slice) {
441 const slice: SliceType(@TypeOf(old_mem)) = old_mem; // coerce *[len]T to []T
423 const slice: Slice(@TypeOf(old_mem)) = old_mem; // coerce *[len]T to []T
442424 return reallocAdvanced(self, slice, new_n, return_address);
443425 }
444426 comptime assert(slice_info.size == .slice);
......@@ -477,7 +459,7 @@ pub fn reallocAdvanced(
477459pub fn free(self: Allocator, memory: anytype) void {
478460 const slice_info = @typeInfo(@TypeOf(memory)).pointer;
479461 if (slice_info.size != .slice) {
480 const slice: SliceType(@TypeOf(memory)) = memory; // coerce *[len]T to []T
462 const slice: Slice(@TypeOf(memory)) = memory; // coerce *[len]T to []T
481463 return free(self, slice);
482464 }
483465 comptime assert(slice_info.size == .slice);
lib/std/meta.zig+29-5
......@@ -1,10 +1,9 @@
11const builtin = @import("builtin");
2
23const std = @import("std.zig");
3const debug = std.debug;
4const assert = std.debug.assert;
45const mem = std.mem;
5const math = std.math;
66const testing = std.testing;
7const root = @import("root");
87
98pub const TrailerFlags = @import("meta/trailer_flags.zig").TrailerFlags;
109
......@@ -821,8 +820,8 @@ pub fn isError(error_union: anytype) bool {
821820}
822821
823822test isError {
824 try std.testing.expect(isError(math.divTrunc(u8, 5, 0)));
825 try std.testing.expect(!isError(math.divTrunc(u8, 5, 5)));
823 try std.testing.expect(isError(std.math.divTrunc(u8, 5, 0)));
824 try std.testing.expect(!isError(std.math.divTrunc(u8, 5, 5)));
826825}
827826
828827/// Returns true if a type has a namespace and the namespace contains `name`;
......@@ -1070,3 +1069,28 @@ test hasUniqueRepresentation {
10701069
10711070 try testing.expect(hasUniqueRepresentation(StructWithComptimeFields));
10721071}
1072
1073/// Given a pointer type, type-erases the array length if present, returning an
1074/// equivalent pointer type that is always a slice.
1075pub fn Slice(comptime Pointer: type) type {
1076 const info = @typeInfo(Pointer).pointer;
1077 switch (info.size) {
1078 .slice => return Pointer,
1079 .one => {
1080 const child_info = @typeInfo(info.child);
1081 comptime assert(child_info == .array);
1082 const sentinel_ptr: ?*const child_info.array.child = @ptrCast(@alignCast(child_info.array.sentinel_ptr));
1083 return @Pointer(
1084 .slice,
1085 info.attrs,
1086 child_info.array.child,
1087 if (sentinel_ptr) |ptr| ptr.* else null,
1088 );
1089 },
1090 else => unreachable,
1091 }
1092}
1093
1094test Slice {
1095 try testing.expectEqual([]i32, Slice(*[10]i32));
1096}