const std = @import("std"); pub fn Queue(comptime Child: type) type { return struct { const This = @This(); const Node = struct { data: Child, next: ?*Node, }; gpa: std.mem.Allocator, start: ?*Node, end: ?*Node, pub fn init(gpa: std.mem.Allocator) This { return This{ .gpa = gpa, .start = null, .end = null, }; } pub fn enqueue(this: *This, value: Child) !void { const node = try this.gpa.create(Node); node.* = .{ .data = value, .next = null }; if (this.end) |end| end.next = node // else this.start = node; this.end = node; } pub fn dequeue(this: *This) ?Child { const start = this.start orelse return null; defer this.gpa.destroy(start); if (start.next) |next| this.start = next else { this.start = null; this.end = null; } return start.data; } }; } pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; var int_queue = Queue(i32).init(gpa.allocator()); std.debug.print("I dequeue {any}\n", .{int_queue.dequeue()}); const result = int_queue.enqueue(10); std.debug.print("Result is {any}\n", .{result}); try int_queue.enqueue(25); try int_queue.enqueue(50); try int_queue.enqueue(75); try int_queue.enqueue(100); std.debug.print("I dequeue {any}\n", .{int_queue.dequeue()}); std.debug.print("I dequeue {any}\n", .{int_queue.dequeue()}); std.debug.print("I dequeue {any}\n", .{int_queue.dequeue()}); }