| ... | ... | @@ -590,6 +590,29 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 590 | 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 | 616 | /// Append a value to the list `n` times. |
| 594 | 617 | /// Allocates more memory as necessary. |
| 595 | 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 | 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 | 1265 | test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMemory" { |
| 1216 | 1266 | // use an arena allocator to make sure realloc returns error.OutOfMemory |
| 1217 | 1267 | var arena = std.heap.ArenaAllocator.init(testing.allocator); |