Created
September 9, 2021 13:36
-
-
Save DutchGhost/369e994dcb5108b9f094fd49b7f24dcb to your computer and use it in GitHub Desktop.
arrayvec
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const std = @import("std"); | |
| pub fn ArrayList(comptime T: type) type { | |
| return struct { | |
| const Self = @This(); | |
| items: []T, | |
| length: usize = 0, | |
| pub fn init(comptime SIZE: usize) Self { | |
| comptime var initial: [SIZE]T = undefined; | |
| return Self{ | |
| .items = &initial, | |
| }; | |
| } | |
| pub fn capacity(comptime self: *const Self) usize { | |
| return self.items.len; | |
| } | |
| pub fn len(comptime self: *const Self) usize { | |
| return self.length; | |
| } | |
| pub fn append(comptime self: *Self, element: T) !void { | |
| const selfLen = self.len(); | |
| const selfCap = self.capacity(); | |
| if (selfLen < selfCap) { | |
| self.items[selfLen] = element; | |
| self.setLen(selfLen + 1); | |
| } | |
| } | |
| pub fn append_slice(comptime self: *Self, slice: []T) void { | |
| comptime var new: [self.items.len + slice.len]T = undefined; | |
| const selfslice = self.asSlice(); | |
| for(selfslice) |elem, idx| { | |
| new[idx] = elem; | |
| } | |
| for(slice) |elem, idx| { | |
| new[idx + selfslice.len] = elem; | |
| } | |
| self.items = &new; | |
| const selfLen = self.len(); | |
| self.setLen(selfLen + slice.len); | |
| } | |
| pub fn pop(comptime self: *Self) ?T { | |
| const selfLen = self.len(); | |
| return if (selfLen > 0) blk: { | |
| const item = self.items[self.length - 1]; | |
| self.items[self.length - 1] = undefined; | |
| self.setLen(selfLen - 1); | |
| break :blk item; | |
| } else null; | |
| } | |
| pub fn asConstSlice(comptime self: *const Self) []const T { | |
| return self.items[0..self.length]; | |
| } | |
| pub fn asSlice(comptime self: *Self) []T { | |
| return self.items[0..self.length]; | |
| } | |
| pub fn setLen(comptime self: *Self, newLen: usize) void { | |
| self.length = newLen; | |
| } | |
| }; | |
| } | |
| test "append" { | |
| comptime { | |
| var list = ArrayList(u8).init(200); | |
| try list.append(20); | |
| try std.testing.expectEqual(list.len(), 1); | |
| var list2 = ArrayList(u8).init(200); | |
| try list.append(30); | |
| try std.testing.expectEqual(list.asSlice()[0], 20); | |
| try std.testing.expectEqualSlices(u8, list.asSlice(), &.{ 20, 30 }); | |
| try std.testing.expectEqual(list.pop(), 30); | |
| try std.testing.expectEqual(list.pop(), 20); | |
| try std.testing.expectEqual(list.pop(), null); | |
| } | |
| } | |
| test "mutation" { | |
| comptime { | |
| var list = ArrayList(u8).init(200); | |
| var list2 = ArrayList(u8).init(200); | |
| var s = [5]u8 { 1, 2, 3, 4, 5}; | |
| list.append_slice(&s); | |
| for(list.asSlice()) |*elem| { | |
| elem.* *= 10; | |
| } | |
| try std.testing.expectEqual(list2.len(), 0); | |
| try std.testing.expectEqual(list2.pop(), null); | |
| try std.testing.expectEqual(list.len(), 5); | |
| try std.testing.expectEqual(list.pop(), 50); | |
| try std.testing.expectEqual(list.pop(), 40); | |
| try std.testing.expectEqual(list.pop(), 30); | |
| try std.testing.expectEqual(list.pop(), 20); | |
| try std.testing.expectEqual(list.pop(), 10); | |
| try std.testing.expectEqual(list.pop(), null); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment