authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2023-03-11 14:52:38+01:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2023-03-12 11:02:53+00:00
loga097779b611577b75475336ee282615984f77edf
tree7dd420122fb3842c4b67d46b31e894f0162df45e
parent4ea2f441df36cec61e1017f4d795d4037326c98c

std: Add ArrayList.insertAssumeCapacity()

Also test and document that inserting at list.items.len is allowed.

1 files changed, 26 insertions(+), 7 deletions(-)

lib/std/array_list.zig+26-7
...@@ -141,11 +141,21 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -141,11 +141,21 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
141 return cloned;141 return cloned;
142 }142 }
143143
144 /// Insert `item` at index `n` by moving `list[n .. list.len]` to make room.144 /// Insert `item` at index `n`. Moves `list[n .. list.len]` to higher indices to make room.
145 /// If `n` is equal to the length of the list this operation is equivalent to append.
145 /// This operation is O(N).146 /// This operation is O(N).
146 /// Invalidates pointers if additional memory is needed.147 /// Invalidates pointers if additional memory is needed.
147 pub fn insert(self: *Self, n: usize, item: T) Allocator.Error!void {148 pub fn insert(self: *Self, n: usize, item: T) Allocator.Error!void {
148 try self.ensureUnusedCapacity(1);149 try self.ensureUnusedCapacity(1);
150 self.insertAssumeCapacity(n, item);
151 }
152
153 /// Insert `item` at index `n`. Moves `list[n .. list.len]` to higher indices to make room.
154 /// If `n` is equal to the length of the list this operation is equivalent to append.
155 /// This operation is O(N).
156 /// Asserts that there is enough capacity for the new item.
157 pub fn insertAssumeCapacity(self: *Self, n: usize, item: T) void {
158 assert(self.items.len < self.capacity);
149 self.items.len += 1;159 self.items.len += 1;
150160
151 mem.copyBackwards(T, self.items[n + 1 .. self.items.len], self.items[n .. self.items.len - 1]);161 mem.copyBackwards(T, self.items[n + 1 .. self.items.len], self.items[n .. self.items.len - 1]);
...@@ -609,12 +619,21 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -609,12 +619,21 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
609 return cloned;619 return cloned;
610 }620 }
611621
612 /// Insert `item` at index `n`. Moves `list[n .. list.len]`622 /// Insert `item` at index `n`. Moves `list[n .. list.len]` to higher indices to make room.
613 /// to higher indices to make room.623 /// If `n` is equal to the length of the list this operation is equivalent to append.
614 /// This operation is O(N).624 /// This operation is O(N).
615 /// Invalidates pointers if additional memory is needed.625 /// Invalidates pointers if additional memory is needed.
616 pub fn insert(self: *Self, allocator: Allocator, n: usize, item: T) Allocator.Error!void {626 pub fn insert(self: *Self, allocator: Allocator, n: usize, item: T) Allocator.Error!void {
617 try self.ensureUnusedCapacity(allocator, 1);627 try self.ensureUnusedCapacity(allocator, 1);
628 self.insertAssumeCapacity(n, item);
629 }
630
631 /// Insert `item` at index `n`. Moves `list[n .. list.len]` to higher indices to make room.
632 /// If `n` is equal to the length of the list this operation is equivalent to append.
633 /// This operation is O(N).
634 /// Asserts that there is enough capacity for the new item.
635 pub fn insertAssumeCapacity(self: *Self, n: usize, item: T) void {
636 assert(self.items.len < self.capacity);
618 self.items.len += 1;637 self.items.len += 1;
619638
620 mem.copyBackwards(T, self.items[n + 1 .. self.items.len], self.items[n .. self.items.len - 1]);639 mem.copyBackwards(T, self.items[n + 1 .. self.items.len], self.items[n .. self.items.len - 1]);
...@@ -1309,9 +1328,9 @@ test "std.ArrayList/ArrayListUnmanaged.insert" {...@@ -1309,9 +1328,9 @@ test "std.ArrayList/ArrayListUnmanaged.insert" {
1309 var list = ArrayList(i32).init(a);1328 var list = ArrayList(i32).init(a);
1310 defer list.deinit();1329 defer list.deinit();
13111330
1312 try list.append(1);1331 try list.insert(0, 1);
1313 try list.append(2);1332 try list.append(2);
1314 try list.append(3);1333 try list.insert(2, 3);
1315 try list.insert(0, 5);1334 try list.insert(0, 5);
1316 try testing.expect(list.items[0] == 5);1335 try testing.expect(list.items[0] == 5);
1317 try testing.expect(list.items[1] == 1);1336 try testing.expect(list.items[1] == 1);
...@@ -1322,9 +1341,9 @@ test "std.ArrayList/ArrayListUnmanaged.insert" {...@@ -1322,9 +1341,9 @@ test "std.ArrayList/ArrayListUnmanaged.insert" {
1322 var list = ArrayListUnmanaged(i32){};1341 var list = ArrayListUnmanaged(i32){};
1323 defer list.deinit(a);1342 defer list.deinit(a);
13241343
1325 try list.append(a, 1);1344 try list.insert(a, 0, 1);
1326 try list.append(a, 2);1345 try list.append(a, 2);
1327 try list.append(a, 3);1346 try list.insert(a, 2, 3);
1328 try list.insert(a, 0, 5);1347 try list.insert(a, 0, 5);
1329 try testing.expect(list.items[0] == 5);1348 try testing.expect(list.items[0] == 5);
1330 try testing.expect(list.items[1] == 1);1349 try testing.expect(list.items[1] == 1);