commit 5f1aa3505d387bcc164cb102be11fd5cb054f4ef (tree)
parent e78b1b810fd15dfd135c80d06d621851a59f42c6
Author: Andrew Kelley <superjoe30@gmail.com>
Date: Sat, 14 Jul 2018 09:35:50 -0400
Merge pull request #1232 from BarabasGitHub/fix-array-list-insert
Fix array list insert
Diffstat:
2 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/std/array_list.zig b/std/array_list.zig
@@ -85,7 +85,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
try self.ensureCapacity(self.len + 1);
self.len += 1;
- mem.copy(T, self.items[n + 1 .. self.len], self.items[n .. self.len - 1]);
+ mem.copyBackwards(T, self.items[n + 1 .. self.len], self.items[n .. self.len - 1]);
self.items[n] = item;
}
@@ -93,7 +93,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
try self.ensureCapacity(self.len + items.len);
self.len += items.len;
- mem.copy(T, self.items[n + items.len .. self.len], self.items[n .. self.len - items.len]);
+ mem.copyBackwards(T, self.items[n + items.len .. self.len], self.items[n .. self.len - items.len]);
mem.copy(T, self.items[n .. n + items.len], items);
}
@@ -266,19 +266,36 @@ test "insert ArrayList test" {
defer list.deinit();
try list.append(1);
+ try list.append(2);
+ try list.append(3);
try list.insert(0, 5);
assert(list.items[0] == 5);
assert(list.items[1] == 1);
+ assert(list.items[2] == 2);
+ assert(list.items[3] == 3);
+}
+
+test "insertSlice ArrayList test" {
+ var list = ArrayList(i32).init(debug.global_allocator);
+ defer list.deinit();
+ try list.append(1);
+ try list.append(2);
+ try list.append(3);
+ try list.append(4);
try list.insertSlice(1, []const i32{
9,
8,
});
- assert(list.items[0] == 5);
+ assert(list.items[0] == 1);
assert(list.items[1] == 9);
assert(list.items[2] == 8);
+ assert(list.items[3] == 2);
+ assert(list.items[4] == 3);
+ assert(list.items[5] == 4);
const items = []const i32{1};
try list.insertSlice(0, items[0..0]);
- assert(list.items[0] == 5);
+ assert(list.len == 6);
+ assert(list.items[0] == 1);
}
diff --git a/std/mem.zig b/std/mem.zig
@@ -125,6 +125,7 @@ pub const Allocator = struct {
/// Copy all of source into dest at position 0.
/// dest.len must be >= source.len.
+/// dest.ptr must be <= src.ptr.
pub fn copy(comptime T: type, dest: []T, source: []const T) void {
// TODO instead of manually doing this check for the whole array
// and turning off runtime safety, the compiler should detect loops like
@@ -135,6 +136,23 @@ pub fn copy(comptime T: type, dest: []T, source: []const T) void {
dest[i] = s;
}
+/// Copy all of source into dest at position 0.
+/// dest.len must be >= source.len.
+/// dest.ptr must be >= src.ptr.
+pub fn copyBackwards(comptime T: type, dest: []T, source: []const T) void {
+ // TODO instead of manually doing this check for the whole array
+ // and turning off runtime safety, the compiler should detect loops like
+ // this and automatically omit safety checks for loops
+ @setRuntimeSafety(false);
+ assert(dest.len >= source.len);
+ var i = source.len;
+ while(i > 0){
+ i -= 1;
+ dest[i] = source[i];
+ }
+}
+
+
pub fn set(comptime T: type, dest: []T, value: T) void {
for (dest) |*d|
d.* = value;