diff --git a/std/array_list.zig b/std/array_list.zig index b71f5be6ab94..5deb3c5fb1e2 100644 --- 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 index 555e1e249db3..41c5d0c8a30a 100644 --- 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;