const std = @import("std"); pub fn vector(comptime T: type) type { return struct { const Self: type = @This(); const VectorType: type = T; const VectorError: type = error { OutOfBounds, }; allocator: std.mem.Allocator, array: []VectorType, length: usize, pub fn new(allocator: std.mem.Allocator) !Self { const DEFAULT_SIZE: usize = 16; return Self { .allocator = allocator, .array = try allocator.alloc(VectorType, DEFAULT_SIZE), .length = 0, }; } pub fn new_with_capacity(allocator: std.mem.Allocator, capacity: usize) !Self { return Self { .allocator = allocator, .array = try allocator.alloc(VectorType, capacity), .length = 0, }; } pub fn push(self: *Self, item: VectorType) !void { if (self.length >= self.array.len) { const new_buffer: []VectorType = try self.allocator.alloc(VectorType, 2 * self.array.len); @memcpy(new_buffer, self.array); self.allocator.free(self.array); self.array = new_buffer; } self.array[self.length] = item; self.length += 1; } pub fn pop(self: *Self) VectorType { self.length -= 1; return self.array[self.length]; } pub fn drain(self: *Self, range: [2]usize) VectorError![]VectorType { if (2 != range.len or range[1] <= range[0] or range[0] > self.array.len or range[1] > self.array.len) { return VectorError.OutOfBounds; } // TODO: return array instead of pointer const slice: []VectorType = self.array[range[0]..range[1]]; @memmove(self.array.ptr, self.array[range[1]..]); self.length -= range[1] - range[0] + 1; return slice; } }; }