const std = @import("std"); const Allocator = std.mem.Allocator; pub fn Stack(comptime T: type) type { return struct { items: []T, capacity: usize, length: usize, allocator: Allocator, const Self = @This(); pub fn init(allocator: Allocator, capacity: usize) !Stack(T) { var buf = try allocator.alloc(T, capacity); return .{ .items = buf[0..], .capacity = capacity, .length = 0, .allocator = allocator, }; } pub fn push(self: *Self, item: T) !void { if (self.length == self.capacity) { const new_capacity: usize = self.capacity * 2; var new_buf = try self.allocator.alloc(T, new_capacity); @memcpy(new_buf[0..self.capacity], self.items); self.allocator.free(self.items); self.items = new_buf; self.capacity = new_capacity; } self.items[self.length] = item; self.length += 1; } pub fn pop(self: *Self) ?T { if (self.length == 0) { return null; } const index: usize = self.length - 1; const out = self.items[index]; self.items[index] = undefined; self.length -= 1; return out; } pub fn deinit(self: *Self) void { self.allocator.free(self.items); self.capacity = 0; self.length = 0; } }; }