From d8f8e4a1d6632be0b61ad73711bea2775df1c4b9 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Sun, 26 Feb 2023 12:06:48 +0100 Subject: [PATCH] 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. --- example/list.zig | 10 ++++------ src/wayland_server_core.zig | 30 ++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/example/list.zig b/example/list.zig index 88cbdbc..6208bb8 100644 --- a/example/list.zig +++ b/example/list.zig @@ -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}); } diff --git a/src/wayland_server_core.zig b/src/wayland_server_core.zig index 6eac6d3..a256083 100644 --- a/src/wayland_server_core.zig +++ b/src/wayland_server_core.zig @@ -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); }