Just an experience got after debugging a bug.
const std = @import("std");
const Data = union(enum) {
item: struct {
list: *Node,
fn ownerNode(self: *const @This()) *Node {
const data: *Data = @alignCast(@fieldParentPtr("item", @constCast(self)));
return data.ownerNode();
}
fn isFirst(self: *const @This()) bool {
return self.list.next.? == self.ownerNode();
}
},
list: struct {},
fn ownerNode(self: *const @This()) *Node {
const node: *Node = @alignCast(@fieldParentPtr("data", @constCast(self)));
return node;
}
};
const Node = struct {
prev: ?*Node = null,
next: ?*Node = null,
data: Data,
};
pub fn main() void {
var listNode = Node{.data = .{.list = .{}}};
var itemNode = Node{.data = .{.item = .{.list = &listNode}}};
listNode.next = &itemNode;
itemNode.prev = &listNode;
switch (itemNode.data) {
.item => |*item| std.debug.print("{}\n", .{item.isFirst()}), // true
else => {},
}
switch (itemNode.data) {
.item => |item| std.debug.print("{}\n", .{item.isFirst()}), // false
else => {},
}
}