| ... | @@ -185,6 +185,64 @@ pub fn create(self: Allocator, comptime T: type) Error!*T { | ... | @@ -185,6 +185,64 @@ pub fn create(self: Allocator, comptime T: type) Error!*T { |
| 185 | return &slice[0]; | 185 | return &slice[0]; |
| 186 | } | 186 | } |
| 187 | | 187 | |
| | 188 | /// Returns an aligned pointer to undefined memory. |
| | 189 | /// Call `destroy` with the result to free the memory. |
| | 190 | pub fn alignedCreate( |
| | 191 | self: Allocator, |
| | 192 | comptime T: type, |
| | 193 | // null means naturally aligned |
| | 194 | comptime alignment: ?u29, |
| | 195 | ) Error!*align(alignment orelse @alignOf(T)) T { |
| | 196 | if (@sizeOf(T) == 0) return @as(*T, undefined); |
| | 197 | const slice = try self.allocAdvancedWithRetAddr(T, alignment, 1, .exact, @returnAddress()); |
| | 198 | return &slice[0]; |
| | 199 | } |
| | 200 | |
| | 201 | test "create" { |
| | 202 | // Non-zero type, greater alignment |
| | 203 | { |
| | 204 | const x = try std.testing.allocator.alignedCreate(u8, @alignOf(u32)); |
| | 205 | defer std.testing.allocator.destroy(x); |
| | 206 | |
| | 207 | assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(u32)); |
| | 208 | } |
| | 209 | // Non-zero type, null alignment |
| | 210 | { |
| | 211 | const x = try std.testing.allocator.alignedCreate(u8, null); |
| | 212 | defer std.testing.allocator.destroy(x); |
| | 213 | |
| | 214 | assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(u8)); |
| | 215 | } |
| | 216 | // Non-zero type, lesser alignment |
| | 217 | { |
| | 218 | const x = try std.testing.allocator.alignedCreate(u32, @alignOf(u5)); |
| | 219 | defer std.testing.allocator.destroy(x); |
| | 220 | |
| | 221 | assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(u5)); |
| | 222 | } |
| | 223 | // Zero type, greater alignment |
| | 224 | { |
| | 225 | const x = try std.testing.allocator.alignedCreate([0]u8, @alignOf(u32)); |
| | 226 | defer std.testing.allocator.destroy(x); |
| | 227 | |
| | 228 | assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(void)); |
| | 229 | } |
| | 230 | // Zero type, null alignment |
| | 231 | { |
| | 232 | const x = try std.testing.allocator.alignedCreate([0]u8, null); |
| | 233 | defer std.testing.allocator.destroy(x); |
| | 234 | |
| | 235 | assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(void)); |
| | 236 | } |
| | 237 | // Zero alignment, lesser alignment |
| | 238 | { |
| | 239 | const x = try std.testing.allocator.alignedCreate([0]u8, @alignOf(u5)); |
| | 240 | defer std.testing.allocator.destroy(x); |
| | 241 | |
| | 242 | assert(@typeInfo(@TypeOf(x)).Pointer.alignment == @alignOf(void)); |
| | 243 | } |
| | 244 | } |
| | 245 | |
| 188 | /// `ptr` should be the return value of `create`, or otherwise | 246 | /// `ptr` should be the return value of `create`, or otherwise |
| 189 | /// have the same address and alignment property. | 247 | /// have the same address and alignment property. |
| 190 | pub fn destroy(self: Allocator, ptr: anytype) void { | 248 | pub fn destroy(self: Allocator, ptr: anytype) void { |