From 5647a73fea7ecc9e1ee190362ef47f402eb95dff Mon Sep 17 00:00:00 2001 From: devins2518 Date: Sat, 23 Jul 2022 06:22:35 -0500 Subject: [PATCH] std.mem.Allocator: add alignedCreate --- lib/std/mem/Allocator.zig | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/lib/std/mem/Allocator.zig b/lib/std/mem/Allocator.zig index 2edfde04a..ddc48b65d 100644 --- a/lib/std/mem/Allocator.zig +++ b/lib/std/mem/Allocator.zig @@ -185,6 +185,64 @@ pub fn create(self: Allocator, comptime T: type) Error!*T { return &slice[0]; } +/// Returns an aligned pointer to undefined memory. +/// Call `destroy` with the result to free the memory. +pub fn alignedCreate( + self: Allocator, + comptime T: type, + // null means naturally aligned + comptime alignment: ?u29, +) Error!*align(alignment orelse @alignOf(T)) T { + if (@sizeOf(T) == 0) return @as(*T, undefined); + const slice = try self.allocAdvancedWithRetAddr(T, alignment, 1, .exact, @returnAddress()); + return &slice[0]; +} + +test "create" { + // Non-zero type, greater alignment + { + const x = try std.testing.allocator.alignedCreate(u8, @alignOf(u32)); + defer std.testing.allocator.destroy(x); + + assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(u32)); + } + // Non-zero type, null alignment + { + const x = try std.testing.allocator.alignedCreate(u8, null); + defer std.testing.allocator.destroy(x); + + assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(u8)); + } + // Non-zero type, lesser alignment + { + const x = try std.testing.allocator.alignedCreate(u32, @alignOf(u5)); + defer std.testing.allocator.destroy(x); + + assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(u5)); + } + // Zero type, greater alignment + { + const x = try std.testing.allocator.alignedCreate([0]u8, @alignOf(u32)); + defer std.testing.allocator.destroy(x); + + assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(void)); + } + // Zero type, null alignment + { + const x = try std.testing.allocator.alignedCreate([0]u8, null); + defer std.testing.allocator.destroy(x); + + assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(void)); + } + // Zero alignment, lesser alignment + { + const x = try std.testing.allocator.alignedCreate([0]u8, @alignOf(u5)); + defer std.testing.allocator.destroy(x); + + assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(void)); + } +} + /// `ptr` should be the return value of `create`, or otherwise /// have the same address and alignment property. pub fn destroy(self: Allocator, ptr: anytype) void {