authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-28 13:21:17-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-28 13:21:17-07:00
log8e93ec6d2491246c841c2f983bb48152b8de2837
tree0672d5b9ba482502f83ed8c6c2ef930c66df0f59
parente02caa7e2909c0ae7f7e8ea1378d78e0469b9ff8

std.ArrayListUnmanaged: implement writer()


1 files changed, 50 insertions(+), 0 deletions(-)

lib/std/array_list.zig+50
......@@ -590,6 +590,29 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
590590 mem.copy(T, self.items[old_len..], items);
591591 }
592592
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
593616 /// Append a value to the list `n` times.
594617 /// Allocates more memory as necessary.
595618 pub fn appendNTimes(self: *Self, allocator: *Allocator, value: T, n: usize) !void {
......@@ -1212,6 +1235,33 @@ test "std.ArrayList(u8)/ArrayListAligned implements writer" {
12121235 }
12131236}
12141237
1238test "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
12151265test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMemory" {
12161266 // use an arena allocator to make sure realloc returns error.OutOfMemory
12171267 var arena = std.heap.ArenaAllocator.init(testing.allocator);