| ... | ... | @@ -1,11 +1,12 @@ |
| 1 | 1 | //! The standard memory allocation interface. |
| 2 | const Allocator = @This(); |
| 3 | |
| 4 | const builtin = @import("builtin"); |
| 2 | 5 | |
| 3 | 6 | const std = @import("../std.zig"); |
| 4 | 7 | const assert = std.debug.assert; |
| 5 | 8 | const math = std.math; |
| 6 | 9 | const mem = std.mem; |
| 7 | | const Allocator = @This(); |
| 8 | | const builtin = @import("builtin"); |
| 9 | 10 | const Alignment = std.mem.Alignment; |
| 10 | 11 | |
| 11 | 12 | pub const Error = error{OutOfMemory}; |
| ... | ... | @@ -471,6 +472,61 @@ pub fn dupeSentinel( |
| 471 | 472 | return new_buf[0..m.len :sentinel]; |
| 472 | 473 | } |
| 473 | 474 | |
| 475 | /// Allocates a formatted string which is returned on success. |
| 476 | /// |
| 477 | /// Returned slice can be deallocated with `free`. If an arena-style allocator |
| 478 | /// is used instead, such as `std.heap.ArenaAllocator`, then no call to `free` |
| 479 | /// is necessary. |
| 480 | /// |
| 481 | /// See `std.Io.Writer.print`. |
| 482 | pub fn print(a: Allocator, comptime format: []const u8, args: anytype) Error![]u8 { |
| 483 | var aw = try std.Io.Writer.Allocating.initCapacity(a, format.len); |
| 484 | defer aw.deinit(); |
| 485 | aw.writer.print(format, args) catch |err| switch (err) { |
| 486 | error.WriteFailed => return error.OutOfMemory, |
| 487 | }; |
| 488 | return aw.toOwnedSlice(); |
| 489 | } |
| 490 | |
| 491 | test print { |
| 492 | const x: i32 = -1; |
| 493 | const y: []const u8 = "hi"; |
| 494 | const a = std.testing.allocator; |
| 495 | const s = try print(a, "{d}={s}", .{ x, y }); |
| 496 | defer free(a, s); |
| 497 | try std.testing.expectEqualStrings("-1=hi", s); |
| 498 | } |
| 499 | |
| 500 | /// Like `print` but returned slice has the provided sentinel. |
| 501 | /// |
| 502 | /// Returned slice can be deallocated with `free`. If an arena-style allocator |
| 503 | /// is used instead, such as `std.heap.ArenaAllocator`, then no call to `free` |
| 504 | /// is necessary. Illegal behavior occurs if the returned slice is type-coerced |
| 505 | /// to a slice without the sentinel and then passed to `free`. |
| 506 | pub fn printSentinel( |
| 507 | a: Allocator, |
| 508 | comptime format: []const u8, |
| 509 | args: anytype, |
| 510 | comptime sentinel: u8, |
| 511 | ) Allocator.Error![:sentinel]u8 { |
| 512 | var aw = try std.Io.Writer.Allocating.initCapacity(a, format.len); |
| 513 | defer aw.deinit(); |
| 514 | aw.writer.print(format, args) catch |err| switch (err) { |
| 515 | error.WriteFailed => return error.OutOfMemory, |
| 516 | }; |
| 517 | return aw.toOwnedSliceSentinel(sentinel); |
| 518 | } |
| 519 | |
| 520 | test printSentinel { |
| 521 | const x: i32 = -1; |
| 522 | const y: []const u8 = "hi"; |
| 523 | const a = std.testing.allocator; |
| 524 | const s = try printSentinel(a, "{d}={s}", .{ x, y }, 0); |
| 525 | defer free(a, s); |
| 526 | try std.testing.expectEqualStrings("-1=hi", s); |
| 527 | try std.testing.expectEqual(0, s[s.len]); |
| 528 | } |
| 529 | |
| 474 | 530 | /// An allocator that always fails to allocate. |
| 475 | 531 | pub const failing: Allocator = .{ |
| 476 | 532 | .ptr = undefined, |