| ... | @@ -590,6 +590,29 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ | ... | @@ -590,6 +590,29 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 590 | mem.copy(T, self.items[old_len..], items); | 590 | mem.copy(T, self.items[old_len..], items); |
| 591 | } | 591 | } |
| 592 | | 592 | |
| | 593 | pub const WriterContext = struct { |
| | 594 | self: *Self, |
| | 595 | allocator: *Allocator, |
| | 596 | }; |
| | 597 | |
| | 598 | pub const Writer = if (T != u8) |
| | 599 | @compileError("The Writer interface is only defined for ArrayList(u8) " ++ |
| | 600 | "but the given type is ArrayList(" ++ @typeName(T) ++ ")") |
| | 601 | else |
| | 602 | std.io.Writer(WriterContext, error{OutOfMemory}, appendWrite); |
| | 603 | |
| | 604 | /// Initializes a Writer which will append to the list. |
| | 605 | pub fn writer(self: *Self, allocator: *Allocator) Writer { |
| | 606 | return .{ .context = .{ .self = self, .allocator = allocator } }; |
| | 607 | } |
| | 608 | |
| | 609 | /// Same as `append` except it returns the number of bytes written, which is always the same |
| | 610 | /// as `m.len`. The purpose of this function existing is to match `std.io.Writer` API. |
| | 611 | fn appendWrite(context: WriterContext, m: []const u8) !usize { |
| | 612 | try context.self.appendSlice(context.allocator, m); |
| | 613 | return m.len; |
| | 614 | } |
| | 615 | |
| 593 | /// Append a value to the list `n` times. | 616 | /// Append a value to the list `n` times. |
| 594 | /// Allocates more memory as necessary. | 617 | /// Allocates more memory as necessary. |
| 595 | pub fn appendNTimes(self: *Self, allocator: *Allocator, value: T, n: usize) !void { | 618 | pub fn appendNTimes(self: *Self, allocator: *Allocator, value: T, n: usize) !void { |
| ... | @@ -1212,6 +1235,33 @@ test "std.ArrayList(u8)/ArrayListAligned implements writer" { | ... | @@ -1212,6 +1235,33 @@ test "std.ArrayList(u8)/ArrayListAligned implements writer" { |
| 1212 | } | 1235 | } |
| 1213 | } | 1236 | } |
| 1214 | | 1237 | |
| | 1238 | test "std.ArrayListUnmanaged(u8) implements writer" { |
| | 1239 | const a = testing.allocator; |
| | 1240 | |
| | 1241 | { |
| | 1242 | var buffer: ArrayListUnmanaged(u8) = .{}; |
| | 1243 | defer buffer.deinit(a); |
| | 1244 | |
| | 1245 | const x: i32 = 42; |
| | 1246 | const y: i32 = 1234; |
| | 1247 | try buffer.writer(a).print("x: {}\ny: {}\n", .{ x, y }); |
| | 1248 | |
| | 1249 | try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.items); |
| | 1250 | } |
| | 1251 | { |
| | 1252 | var list: ArrayListAlignedUnmanaged(u8, 2) = .{}; |
| | 1253 | defer list.deinit(a); |
| | 1254 | |
| | 1255 | const writer = list.writer(a); |
| | 1256 | try writer.writeAll("a"); |
| | 1257 | try writer.writeAll("bc"); |
| | 1258 | try writer.writeAll("d"); |
| | 1259 | try writer.writeAll("efg"); |
| | 1260 | |
| | 1261 | try testing.expectEqualSlices(u8, list.items, "abcdefg"); |
| | 1262 | } |
| | 1263 | } |
| | 1264 | |
| 1215 | test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMemory" { | 1265 | test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMemory" { |
| 1216 | // use an arena allocator to make sure realloc returns error.OutOfMemory | 1266 | // use an arena allocator to make sure realloc returns error.OutOfMemory |
| 1217 | var arena = std.heap.ArenaAllocator.init(testing.allocator); | 1267 | var arena = std.heap.ArenaAllocator.init(testing.allocator); |