authorgravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-07-20 00:52:36-07:00
committergravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-09-26 12:35:38-07:00
log5f457157573edbd99c9e685892b8f81c49cf5967
treef90438464ad309ebbe008f1dc3102df81d415117
parent6d21ffce6ee79bba8238db9f8012579f3cec7e57

Add `alignedCreate`


2 files changed, 24 insertions(+), 4 deletions(-)

lib/std/mem/Allocator.zig+22-1
...@@ -168,14 +168,35 @@ pub inline fn rawFree(a: Allocator, memory: []u8, alignment: Alignment, ret_addr...@@ -168,14 +168,35 @@ pub inline fn rawFree(a: Allocator, memory: []u8, alignment: Alignment, ret_addr
168/// Returns a pointer to undefined memory.168/// Returns a pointer to undefined memory.
169/// Call `destroy` with the result to free the memory.169/// Call `destroy` with the result to free the memory.
170pub fn create(a: Allocator, comptime T: type) Error!*T {170pub fn create(a: Allocator, comptime T: type) Error!*T {
171 return a.createAdvancedWithRetAddr(T, null, @returnAddress());
172}
173
174pub fn alignedCreate(
175 self: Allocator,
176 comptime T: type,
177 /// null means naturally aligned
178 comptime alignment: ?Alignment,
179) Error!*align(if (alignment) |a| a.toByteUnits() else @alignOf(T)) T {
180 return self.createAdvancedWithRetAddr(T, alignment, @returnAddress());
181}
182
183pub inline fn createAdvancedWithRetAddr(
184 self: Allocator,
185 comptime T: type,
186 /// null means naturally aligned
187 comptime alignment: ?Alignment,
188 return_address: usize,
189) Error!*align(if (alignment) |a| a.toByteUnits() else @alignOf(T)) T {
171 if (@sizeOf(T) == 0) {190 if (@sizeOf(T) == 0) {
172 const ptr = comptime std.mem.alignBackward(usize, math.maxInt(usize), @alignOf(T));191 const ptr = comptime std.mem.alignBackward(usize, math.maxInt(usize), @alignOf(T));
173 return @ptrFromInt(ptr);192 return @ptrFromInt(ptr);
174 }193 }
175 const ptr: *T = @ptrCast(try a.allocBytesAligned(.of(T), @sizeOf(T), @returnAddress()));194 const a: Alignment = alignment orelse comptime .of(T);
195 const ptr: *align(a.toByteUnits()) T = @ptrCast(try self.allocBytesAligned(a, @sizeOf(T), return_address));
176 return ptr;196 return ptr;
177}197}
178198
199
179/// `ptr` should be the return value of `create`, or otherwise200/// `ptr` should be the return value of `create`, or otherwise
180/// have the same address and alignment property.201/// have the same address and alignment property.
181pub fn destroy(self: Allocator, ptr: anytype) void {202pub fn destroy(self: Allocator, ptr: anytype) void {
lib/std/zon/parse.zig+2-3
...@@ -473,11 +473,10 @@ const Parser = struct {...@@ -473,11 +473,10 @@ const Parser = struct {
473 // If the existing value is initialized and non const, use it473 // If the existing value is initialized and non const, use it
474 if (initialized and !pointer.attrs.@"const") break :b out.*;474 if (initialized and !pointer.attrs.@"const") break :b out.*;
475 // Otherwise, allocate new memory475 // Otherwise, allocate new memory
476 const new = &(try self.arena.alignedAlloc(476 const new = try self.arena.alignedCreate(
477 pointer.child,477 pointer.child,
478 if (pointer.attrs.@"align") |a| .fromByteUnits(a) else null,478 if (pointer.attrs.@"align") |a| .fromByteUnits(a) else null,
479 1,479 );
480 ))[0];
481 // If the original value was initialized, dupe it into the new memory480 // If the original value was initialized, dupe it into the new memory
482 if (initialized) new.* = out.*.*;481 if (initialized) new.* = out.*.*;
483 break :b new;482 break :b new;