Hacker News new | ask | show | jobs
by tiehuis 2673 days ago
A comparable implementation in Zig. Key detail is `@fieldParentPtr` [1], which has the same functionality as `container_of`.

    const std = @import("std");

    const wl_list = struct {
        prev: *wl_list,
        next: *wl_list,

        fn init(list: *wl_list) void {
            list.prev = list;
            list.next = list;
        }

        fn insert(list: *wl_list, elem: *wl_list) void {
            elem.prev = list;
            elem.next = list.next;
            list.next = elem;
            elem.next.prev = elem;
        }
    };

    const Data = struct {
        data: i32,
        link: wl_list,

        fn init(data: i32) Data {
            return Data{
                .data = data,
                .link = undefined,
            };
        }
    };

    pub fn main() void {
        var foo_list: wl_list = undefined;
        foo_list.init();

        var e1 = Data.init(1);
        var e2 = Data.init(2);
        var e3 = Data.init(3);

        foo_list.insert(&e1.link);
        foo_list.insert(&e2.link);
        e2.link.insert(&e3.link);

        var entry = @fieldParentPtr(Data, "link", foo_list.next);
        while (&entry.link != &foo_list) : (entry = @fieldParentPtr(Data, "link", entry.link.next)) {
            std.debug.warn("{}\n", entry.data);
        }
    }

[1] https://ziglang.org/documentation/master/#fieldParentPtr