Add more list.Link Functions

- Add Link.replaceWith()
- Add Link.swapWith()
- Rename Link.insertAfter() -> Link.insert() as the status quo reads
  very poorly in practice.
This commit is contained in:
Isaac Freund
2023-02-26 12:06:48 +01:00
parent b3789919b7
commit d8f8e4a1d6
2 changed files with 30 additions and 10 deletions

View File

@@ -46,11 +46,10 @@ pub fn main() void {
while (it.next()) |b| std.debug.print("{}\n", .{b.data});
}
three.link.remove();
a.prepend(&three);
three.link.swapWith(&four.link);
{
std.debug.print("reverse moved three\n", .{});
std.debug.print("reverse swapped 3/4\n", .{});
var it = a.iterator(.reverse);
while (it.next()) |b| std.debug.print("{}\n", .{b.data});
}
@@ -81,11 +80,10 @@ pub fn main() void {
while (it.next()) |b| std.debug.print("{}\n", .{b.data});
}
three.link.remove();
a.prepend(&three);
two.link.swapWith(&five.link);
{
std.debug.print("reverse moved three\n", .{});
std.debug.print("reverse swapped 2/5\n", .{});
var it = a.iterator(.reverse);
while (it.next()) |b| std.debug.print("{}\n", .{b.data});
}

View File

@@ -372,7 +372,7 @@ pub const list = struct {
link.* = .{ .prev = link, .next = link };
}
pub fn insertAfter(link: *Link, other: *Link) void {
pub fn insert(link: *Link, other: *Link) void {
other.prev = link;
other.next = link.next;
link.next = other;
@@ -384,6 +384,28 @@ pub const list = struct {
link.next.?.prev = link.prev;
link.* = .{ .prev = null, .next = null };
}
pub fn replaceWith(link: *Link, other: *Link) void {
other.next = link.next;
other.next.?.prev = other;
other.prev = link.prev;
other.prev.?.next = other;
link.* = .{ .prev = null, .next = null };
}
pub fn swapWith(link: *Link, other: *Link) void {
const old_other_prev = other.prev.?;
other.remove();
link.replaceWith(other);
if (old_other_prev == link) {
other.insert(link);
} else {
old_other_prev.insert(link);
}
}
};
pub const Direction = enum {
@@ -406,12 +428,12 @@ pub const list = struct {
pub fn prepend(head: *Self, elem: *T) void {
const link = if (link_field) |f| &@field(elem, f) else elem.getLink();
head.link.insertAfter(link);
head.link.insert(link);
}
pub fn append(head: *Self, elem: *T) void {
const link = if (link_field) |f| &@field(elem, f) else elem.getLink();
head.link.prev.?.insertAfter(link);
head.link.prev.?.insert(link);
}
pub fn length(head: *const Self) usize {
@@ -577,7 +599,7 @@ pub fn Signal(comptime T: type) type {
const listener = @fieldParentPtr(Listener(T), "link", pos);
cursor.link.remove();
pos.insertAfter(&cursor.link);
pos.insert(&cursor.link);
listener.notify(listener, data);
}