diff options
Diffstat (limited to 'std/array_list.zig')
| -rw-r--r-- | std/array_list.zig | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/std/array_list.zig b/std/array_list.zig index 65b7e023e2..04db4dd280 100644 --- a/std/array_list.zig +++ b/std/array_list.zig @@ -3,42 +3,46 @@ const assert = debug.assert; const mem = @import("mem.zig"); const Allocator = mem.Allocator; -pub fn ArrayList(comptime T: type) -> type{ - struct { +pub fn ArrayList(comptime T: type) -> type { + return AlignedArrayList(T, @alignOf(T)); +} + +pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{ + return struct { const Self = this; /// Use toSlice instead of slicing this directly, because if you don't /// specify the end position of the slice, this will potentially give /// you uninitialized memory. - items: []T, + items: []align(A) T, len: usize, allocator: &Allocator, /// Deinitialize with `deinit` or use `toOwnedSlice`. pub fn init(allocator: &Allocator) -> Self { - Self { - .items = []T{}, + return Self { + .items = []align(A) T{}, .len = 0, .allocator = allocator, - } + }; } pub fn deinit(l: &Self) { l.allocator.free(l.items); } - pub fn toSlice(l: &Self) -> []T { + pub fn toSlice(l: &Self) -> []align(A) T { return l.items[0..l.len]; } - pub fn toSliceConst(l: &const Self) -> []const T { + pub fn toSliceConst(l: &const Self) -> []align(A) const T { return l.items[0..l.len]; } /// ArrayList takes ownership of the passed in slice. The slice must have been /// allocated with `allocator`. /// Deinitialize with `deinit` or use `toOwnedSlice`. - pub fn fromOwnedSlice(allocator: &Allocator, slice: []T) -> Self { + pub fn fromOwnedSlice(allocator: &Allocator, slice: []align(A) T) -> Self { return Self { .items = slice, .len = slice.len, @@ -47,9 +51,9 @@ pub fn ArrayList(comptime T: type) -> type{ } /// The caller owns the returned memory. ArrayList becomes empty. - pub fn toOwnedSlice(self: &Self) -> []T { + pub fn toOwnedSlice(self: &Self) -> []align(A) T { const allocator = self.allocator; - const result = allocator.shrink(T, self.items, self.len); + const result = allocator.alignedShrink(T, A, self.items, self.len); *self = init(allocator); return result; } @@ -59,7 +63,7 @@ pub fn ArrayList(comptime T: type) -> type{ *new_item_ptr = *item; } - pub fn appendSlice(l: &Self, items: []const T) -> %void { + pub fn appendSlice(l: &Self, items: []align(A) const T) -> %void { %return l.ensureCapacity(l.len + items.len); mem.copy(T, l.items[l.len..], items); l.len += items.len; @@ -82,7 +86,7 @@ pub fn ArrayList(comptime T: type) -> type{ better_capacity += better_capacity / 2 + 8; if (better_capacity >= new_capacity) break; } - l.items = %return l.allocator.realloc(T, l.items, better_capacity); + l.items = %return l.allocator.alignedRealloc(T, A, l.items, better_capacity); } pub fn addOne(l: &Self) -> %&T { @@ -97,7 +101,13 @@ pub fn ArrayList(comptime T: type) -> type{ self.len -= 1; return self.items[self.len]; } - } + + pub fn popOrNull(self: &Self) -> ?T { + if (self.len == 0) + return null; + return self.pop(); + } + }; } test "basic ArrayList test" { |
