diff options
| author | Anthony Arian <anthonyarian96@gmail.com> | 2020-07-20 10:25:54 +0100 |
|---|---|---|
| committer | Anthony Arian <anthonyarian96@gmail.com> | 2020-07-20 10:25:54 +0100 |
| commit | 3658dd5e89cd16c011bdc52d334c1308f440157b (patch) | |
| tree | 09564ab2db65acc4a52d82bccbf0eb572fbc865f /lib/std/array_list.zig | |
| parent | 68fe3e116d9c4bde67df990b8e0cbb3e70fc98b2 (diff) | |
| parent | 596ca6cf70cf43c27e31bbcfc36bcdc70b13897a (diff) | |
| download | zig-3658dd5e89cd16c011bdc52d334c1308f440157b.tar.gz zig-3658dd5e89cd16c011bdc52d334c1308f440157b.zip | |
Merge branch 'master' of https://github.com/ziglang/zig into 5002-fix-entrypoint-with-winmain
Diffstat (limited to 'lib/std/array_list.zig')
| -rw-r--r-- | lib/std/array_list.zig | 123 |
1 files changed, 108 insertions, 15 deletions
diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index e096a65491..4d8cdc200c 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -53,7 +53,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { /// Deprecated: use `items` field directly. /// Return contents as a slice. Only valid while the list /// doesn't change size. - pub fn span(self: var) @TypeOf(self.items) { + pub fn span(self: anytype) @TypeOf(self.items) { return self.items; } @@ -162,19 +162,24 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { mem.copy(T, self.items[oldlen..], items); } - /// Same as `append` except it returns the number of bytes written, which is always the same - /// as `m.len`. The purpose of this function existing is to match `std.io.OutStream` API. - /// This function may be called only when `T` is `u8`. - fn appendWrite(self: *Self, m: []const u8) !usize { - try self.appendSlice(m); - return m.len; - } + pub usingnamespace if (T != u8) struct {} else struct { + pub const Writer = std.io.Writer(*Self, error{OutOfMemory}, appendWrite); - /// Initializes an OutStream which will append to the list. - /// This function may be called only when `T` is `u8`. - pub fn outStream(self: *Self) std.io.OutStream(*Self, error{OutOfMemory}, appendWrite) { - return .{ .context = self }; - } + /// Initializes a Writer which will append to the list. + pub fn writer(self: *Self) Writer { + return .{ .context = self }; + } + + /// Deprecated: use `writer` + pub const outStream = writer; + + /// Same as `append` except it returns the number of bytes written, which is always the same + /// as `m.len`. The purpose of this function existing is to match `std.io.Writer` API. + fn appendWrite(self: *Self, m: []const u8) !usize { + try self.appendSlice(m); + return m.len; + } + }; /// Append a value to the list `n` times. /// Allocates more memory as necessary. @@ -205,6 +210,14 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { self.capacity = new_len; } + /// Reduce length to `new_len`. + /// Invalidates element pointers. + /// Keeps capacity the same. + pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void { + assert(new_len <= self.items.len); + self.items.len = new_len; + } + pub fn ensureCapacity(self: *Self, new_capacity: usize) !void { var better_capacity = self.capacity; if (better_capacity >= new_capacity) return; @@ -214,7 +227,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { if (better_capacity >= new_capacity) break; } - const new_memory = try self.allocator.realloc(self.allocatedSlice(), better_capacity); + const new_memory = try self.allocator.reallocAtLeast(self.allocatedSlice(), better_capacity); self.items.ptr = new_memory.ptr; self.capacity = new_memory.len; } @@ -244,6 +257,24 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { return &self.items[self.items.len - 1]; } + /// Resize the array, adding `n` new elements, which have `undefined` values. + /// The return value is an array pointing to the newly allocated elements. + pub fn addManyAsArray(self: *Self, comptime n: usize) !*[n]T { + const prev_len = self.items.len; + try self.resize(self.items.len + n); + return self.items[prev_len..][0..n]; + } + + /// Resize the array, adding `n` new elements, which have `undefined` values. + /// The return value is an array pointing to the newly allocated elements. + /// Asserts that there is already space for the new item without allocating more. + pub fn addManyAsArrayAssumeCapacity(self: *Self, comptime n: usize) *[n]T { + assert(self.items.len + n <= self.capacity); + const prev_len = self.items.len; + self.items.len += n; + return self.items[prev_len..][0..n]; + } + /// Remove and return the last element from the list. /// Asserts the list has at least one item. pub fn pop(self: *Self) T { @@ -427,6 +458,14 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ self.capacity = new_len; } + /// Reduce length to `new_len`. + /// Invalidates element pointers. + /// Keeps capacity the same. + pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void { + assert(new_len <= self.items.len); + self.items.len = new_len; + } + pub fn ensureCapacity(self: *Self, allocator: *Allocator, new_capacity: usize) !void { var better_capacity = self.capacity; if (better_capacity >= new_capacity) return; @@ -436,7 +475,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ if (better_capacity >= new_capacity) break; } - const new_memory = try allocator.realloc(self.allocatedSlice(), better_capacity); + const new_memory = try allocator.reallocAtLeast(self.allocatedSlice(), better_capacity); self.items.ptr = new_memory.ptr; self.capacity = new_memory.len; } @@ -467,6 +506,24 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ return &self.items[self.items.len - 1]; } + /// Resize the array, adding `n` new elements, which have `undefined` values. + /// The return value is an array pointing to the newly allocated elements. + pub fn addManyAsArray(self: *Self, allocator: *Allocator, comptime n: usize) !*[n]T { + const prev_len = self.items.len; + try self.resize(allocator, self.items.len + n); + return self.items[prev_len..][0..n]; + } + + /// Resize the array, adding `n` new elements, which have `undefined` values. + /// The return value is an array pointing to the newly allocated elements. + /// Asserts that there is already space for the new item without allocating more. + pub fn addManyAsArrayAssumeCapacity(self: *Self, comptime n: usize) *[n]T { + assert(self.items.len + n <= self.capacity); + const prev_len = self.items.len; + self.items.len += n; + return self.items[prev_len..][0..n]; + } + /// Remove and return the last element from the list. /// Asserts the list has at least one item. /// This operation does not invalidate any element pointers. @@ -694,3 +751,39 @@ test "std.ArrayList.shrink still sets length on error.OutOfMemory" { list.shrink(1); testing.expect(list.items.len == 1); } + +test "std.ArrayList.writer" { + var list = ArrayList(u8).init(std.testing.allocator); + defer list.deinit(); + + const writer = list.writer(); + try writer.writeAll("a"); + try writer.writeAll("bc"); + try writer.writeAll("d"); + try writer.writeAll("efg"); + testing.expectEqualSlices(u8, list.items, "abcdefg"); +} + +test "addManyAsArray" { + const a = std.testing.allocator; + { + var list = ArrayList(u8).init(a); + defer list.deinit(); + + (try list.addManyAsArray(4)).* = "aoeu".*; + try list.ensureCapacity(8); + list.addManyAsArrayAssumeCapacity(4).* = "asdf".*; + + testing.expectEqualSlices(u8, list.items, "aoeuasdf"); + } + { + var list = ArrayListUnmanaged(u8){}; + defer list.deinit(a); + + (try list.addManyAsArray(a, 4)).* = "aoeu".*; + try list.ensureCapacity(a, 8); + list.addManyAsArrayAssumeCapacity(4).* = "asdf".*; + + testing.expectEqualSlices(u8, list.items, "aoeuasdf"); + } +} |
