Commit fe98a2da70

Bas van den Berg <mailbasvandenberg@gmail.com>
2018-07-13 23:01:21
Add a copyBackwards to fix the broken insert methods for ArrayList.
1 parent a1cafa6
Changed files (2)
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);
         }
 
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;