From 272e72ea7a0fdb859d85b5fe25a93d6567dc67ad Mon Sep 17 00:00:00 2001 From: Hila Friedman Date: Thu, 9 Oct 2025 07:30:29 +0300 Subject: [PATCH 1/4] Simplify swapRemove --- lib/std/array_list.zig | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index 96a034444220..86891abe294a 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -277,14 +277,11 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type /// The empty slot is filled from the end of the list. /// This operation is O(1). /// This may not preserve item order. Use `orderedRemove` if you need to preserve order. - /// Asserts that the list is not empty. /// Asserts that the index is in bounds. pub fn swapRemove(self: *Self, i: usize) T { - if (self.items.len - 1 == i) return self.pop().?; - - const old_item = self.items[i]; - self.items[i] = self.pop().?; - return old_item; + assert(i < self.items.len); + defer self.items[i] = self.pop() orelse unreachable; + return self.items[i]; } /// Append the slice of items to the list. Allocates more @@ -956,14 +953,11 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { /// The empty slot is filled from the end of the list. /// Invalidates pointers to last element. /// This operation is O(1). - /// Asserts that the list is not empty. /// Asserts that the index is in bounds. pub fn swapRemove(self: *Self, i: usize) T { - if (self.items.len - 1 == i) return self.pop().?; - - const old_item = self.items[i]; - self.items[i] = self.pop().?; - return old_item; + assert(i < self.items.len); + defer self.items[i] = self.pop() orelse unreachable; + return self.items[i]; } /// Append the slice of items to the list. Allocates more From bc9809760c422df5295a7553b02047c2d4f501d8 Mon Sep 17 00:00:00 2001 From: Hila Friedman Date: Thu, 9 Oct 2025 08:54:54 +0300 Subject: [PATCH 2/4] remove explicit assert calls --- lib/std/array_list.zig | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index 86891abe294a..d85966750352 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -279,7 +279,6 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type /// This may not preserve item order. Use `orderedRemove` if you need to preserve order. /// Asserts that the index is in bounds. pub fn swapRemove(self: *Self, i: usize) T { - assert(i < self.items.len); defer self.items[i] = self.pop() orelse unreachable; return self.items[i]; } @@ -955,7 +954,6 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { /// This operation is O(1). /// Asserts that the index is in bounds. pub fn swapRemove(self: *Self, i: usize) T { - assert(i < self.items.len); defer self.items[i] = self.pop() orelse unreachable; return self.items[i]; } From 0d83c9a25008cb110b4348a5f343df425e739a24 Mon Sep 17 00:00:00 2001 From: Hila Friedman Date: Thu, 9 Oct 2025 09:04:33 +0300 Subject: [PATCH 3/4] split deferred line into small steps --- lib/std/array_list.zig | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index d85966750352..6f1dbb10e547 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -279,8 +279,10 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type /// This may not preserve item order. Use `orderedRemove` if you need to preserve order. /// Asserts that the index is in bounds. pub fn swapRemove(self: *Self, i: usize) T { - defer self.items[i] = self.pop() orelse unreachable; - return self.items[i]; + const item = self.items[i]; + self.items[i] = self.getLast(); + self.items.len -= 1; + return item; } /// Append the slice of items to the list. Allocates more @@ -954,8 +956,10 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { /// This operation is O(1). /// Asserts that the index is in bounds. pub fn swapRemove(self: *Self, i: usize) T { - defer self.items[i] = self.pop() orelse unreachable; - return self.items[i]; + const item = self.items[i]; + self.items[i] = self.getLast(); + self.items.len -= 1; + return item; } /// Append the slice of items to the list. Allocates more From 5040fb2305cbea0efb7eba09d9c5fc9d1013a8fa Mon Sep 17 00:00:00 2001 From: Hila Friedman Date: Fri, 10 Oct 2025 08:08:31 +0300 Subject: [PATCH 4/4] set removed element to undefined --- lib/std/array_list.zig | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index 6f1dbb10e547..11202a186e6d 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -279,10 +279,11 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type /// This may not preserve item order. Use `orderedRemove` if you need to preserve order. /// Asserts that the index is in bounds. pub fn swapRemove(self: *Self, i: usize) T { - const item = self.items[i]; - self.items[i] = self.getLast(); + const val = self.items[i]; + self.items[i] = self.items[self.items.len - 1]; + self.items[self.items.len - 1] = undefined; self.items.len -= 1; - return item; + return val; } /// Append the slice of items to the list. Allocates more @@ -520,6 +521,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type pub fn pop(self: *Self) ?T { if (self.items.len == 0) return null; const val = self.items[self.items.len - 1]; + self.items[self.items.len - 1] = undefined; self.items.len -= 1; return val; } @@ -542,8 +544,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type /// Returns the last element from the list. /// Asserts that the list is not empty. pub fn getLast(self: Self) T { - const val = self.items[self.items.len - 1]; - return val; + return self.items[self.items.len - 1]; } /// Returns the last element from the list, or `null` if list is empty. @@ -956,10 +957,11 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { /// This operation is O(1). /// Asserts that the index is in bounds. pub fn swapRemove(self: *Self, i: usize) T { - const item = self.items[i]; - self.items[i] = self.getLast(); + const val = self.items[i]; + self.items[i] = self.items[self.items.len - 1]; + self.items[self.items.len - 1] = undefined; self.items.len -= 1; - return item; + return val; } /// Append the slice of items to the list. Allocates more @@ -1323,6 +1325,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { pub fn pop(self: *Self) ?T { if (self.items.len == 0) return null; const val = self.items[self.items.len - 1]; + self.items[self.items.len - 1] = undefined; self.items.len -= 1; return val; } @@ -1344,8 +1347,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { /// Return the last element from the list. /// Asserts that the list is not empty. pub fn getLast(self: Self) T { - const val = self.items[self.items.len - 1]; - return val; + return self.items[self.items.len - 1]; } /// Return the last element from the list, or