authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-05-04 09:30:06+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-05-04 14:08:19+03:00
logb6be28ddcc50bd4bf085294ffcb696e31a7a1de5
tree17512a3cf21896f85c231d8a26d151cd107dec21
parent0e3930bb5a92a60de6faad4c348f062a7a420eca

std: Accept unaligned slice in several ArrayListAligned ops

Do not impose the internal alignment requirements to the user-supplied parameters. Closes #8647

1 files changed, 55 insertions(+), 29 deletions(-)

lib/std/array_list.zig+55-29
......@@ -50,7 +50,6 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
5050 allocator: *Allocator,
5151
5252 pub const Slice = if (alignment) |a| ([]align(a) T) else []T;
53 pub const SliceConst = if (alignment) |a| ([]align(a) const T) else []const T;
5453
5554 /// Deinitialize with `deinit` or use `toOwnedSlice`.
5655 pub fn init(allocator: *Allocator) Self {
......@@ -141,7 +140,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
141140
142141 /// Insert slice `items` at index `i` by moving `list[i .. list.len]` to make room.
143142 /// This operation is O(N).
144 pub fn insertSlice(self: *Self, i: usize, items: SliceConst) !void {
143 pub fn insertSlice(self: *Self, i: usize, items: []const T) !void {
145144 try self.ensureCapacity(self.items.len + items.len);
146145 self.items.len += items.len;
147146
......@@ -153,7 +152,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
153152 /// Grows list if `len < new_items.len`.
154153 /// Shrinks list if `len > new_items.len`.
155154 /// Invalidates pointers if this ArrayList is resized.
156 pub fn replaceRange(self: *Self, start: usize, len: usize, new_items: SliceConst) !void {
155 pub fn replaceRange(self: *Self, start: usize, len: usize, new_items: []const T) !void {
157156 const after_range = start + len;
158157 const range = self.items[start..after_range];
159158
......@@ -220,14 +219,14 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
220219
221220 /// Append the slice of items to the list. Allocates more
222221 /// memory as necessary.
223 pub fn appendSlice(self: *Self, items: SliceConst) !void {
222 pub fn appendSlice(self: *Self, items: []const T) !void {
224223 try self.ensureCapacity(self.items.len + items.len);
225224 self.appendSliceAssumeCapacity(items);
226225 }
227226
228227 /// Append the slice of items to the list, asserting the capacity is already
229228 /// enough to store the new items. **Does not** invalidate pointers.
230 pub fn appendSliceAssumeCapacity(self: *Self, items: SliceConst) void {
229 pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void {
231230 const oldlen = self.items.len;
232231 const newlen = self.items.len + items.len;
233232 self.items.len = newlen;
......@@ -429,7 +428,6 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
429428 capacity: usize = 0,
430429
431430 pub const Slice = if (alignment) |a| ([]align(a) T) else []T;
432 pub const SliceConst = if (alignment) |a| ([]align(a) const T) else []const T;
433431
434432 /// Initialize with capacity to hold at least num elements.
435433 /// Deinitialize with `deinit` or use `toOwnedSlice`.
......@@ -483,7 +481,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
483481 /// Insert slice `items` at index `i`. Moves `list[i .. list.len]` to
484482 /// higher indicices make room.
485483 /// This operation is O(N).
486 pub fn insertSlice(self: *Self, allocator: *Allocator, i: usize, items: SliceConst) !void {
484 pub fn insertSlice(self: *Self, allocator: *Allocator, i: usize, items: []const T) !void {
487485 try self.ensureCapacity(allocator, self.items.len + items.len);
488486 self.items.len += items.len;
489487
......@@ -495,7 +493,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
495493 /// Grows list if `len < new_items.len`.
496494 /// Shrinks list if `len > new_items.len`
497495 /// Invalidates pointers if this ArrayList is resized.
498 pub fn replaceRange(self: *Self, allocator: *Allocator, start: usize, len: usize, new_items: SliceConst) !void {
496 pub fn replaceRange(self: *Self, allocator: *Allocator, start: usize, len: usize, new_items: []const T) !void {
499497 var managed = self.toManaged(allocator);
500498 try managed.replaceRange(start, len, new_items);
501499 self.* = managed.toUnmanaged();
......@@ -543,14 +541,14 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
543541
544542 /// Append the slice of items to the list. Allocates more
545543 /// memory as necessary.
546 pub fn appendSlice(self: *Self, allocator: *Allocator, items: SliceConst) !void {
544 pub fn appendSlice(self: *Self, allocator: *Allocator, items: []const T) !void {
547545 try self.ensureCapacity(allocator, self.items.len + items.len);
548546 self.appendSliceAssumeCapacity(items);
549547 }
550548
551549 /// Append the slice of items to the list, asserting the capacity is enough
552550 /// to store the new items.
553 pub fn appendSliceAssumeCapacity(self: *Self, items: SliceConst) void {
551 pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void {
554552 const oldlen = self.items.len;
555553 const newlen = self.items.len + items.len;
556554
......@@ -1128,15 +1126,31 @@ test "std.ArrayList/ArrayListUnmanaged: ArrayList(T) of struct T" {
11281126 }
11291127}
11301128
1131test "std.ArrayList(u8) implements writer" {
1132 var buffer = ArrayList(u8).init(std.testing.allocator);
1133 defer buffer.deinit();
1129test "std.ArrayList(u8)/ArrayListAligned implements writer" {
1130 const a = testing.allocator;
1131
1132 {
1133 var buffer = ArrayList(u8).init(a);
1134 defer buffer.deinit();
1135
1136 const x: i32 = 42;
1137 const y: i32 = 1234;
1138 try buffer.writer().print("x: {}\ny: {}\n", .{ x, y });
11341139
1135 const x: i32 = 42;
1136 const y: i32 = 1234;
1137 try buffer.writer().print("x: {}\ny: {}\n", .{ x, y });
1140 testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.items);
1141 }
1142 {
1143 var list = ArrayListAligned(u8, 2).init(a);
1144 defer list.deinit();
11381145
1139 testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.items);
1146 const writer = list.writer();
1147 try writer.writeAll("a");
1148 try writer.writeAll("bc");
1149 try writer.writeAll("d");
1150 try writer.writeAll("efg");
1151
1152 testing.expectEqualSlices(u8, list.items, "abcdefg");
1153 }
11401154}
11411155
11421156test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMemory" {
......@@ -1167,18 +1181,6 @@ test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMe
11671181 }
11681182}
11691183
1170test "std.ArrayList.writer" {
1171 var list = ArrayList(u8).init(std.testing.allocator);
1172 defer list.deinit();
1173
1174 const writer = list.writer();
1175 try writer.writeAll("a");
1176 try writer.writeAll("bc");
1177 try writer.writeAll("d");
1178 try writer.writeAll("efg");
1179 testing.expectEqualSlices(u8, list.items, "abcdefg");
1180}
1181
11821184test "std.ArrayList/ArrayListUnmanaged.addManyAsArray" {
11831185 const a = std.testing.allocator;
11841186 {
......@@ -1226,3 +1228,27 @@ test "std.ArrayList/ArrayListUnmanaged.toOwnedSliceSentinel" {
12261228 testing.expectEqualStrings(result, mem.spanZ(result.ptr));
12271229 }
12281230}
1231
1232test "ArrayListAligned/ArrayListAlignedUnmanaged accepts unaligned slices" {
1233 const a = testing.allocator;
1234 {
1235 var list = std.ArrayListAligned(u8, 8).init(a);
1236 defer list.deinit();
1237
1238 try list.appendSlice(&.{ 0, 1, 2, 3 });
1239 try list.insertSlice(2, &.{ 4, 5, 6, 7 });
1240 try list.replaceRange(1, 3, &.{ 8, 9 });
1241
1242 testing.expectEqualSlices(u8, list.items, &.{ 0, 8, 9, 6, 7, 2, 3 });
1243 }
1244 {
1245 var list = std.ArrayListAlignedUnmanaged(u8, 8){};
1246 defer list.deinit(a);
1247
1248 try list.appendSlice(a, &.{ 0, 1, 2, 3 });
1249 try list.insertSlice(a, 2, &.{ 4, 5, 6, 7 });
1250 try list.replaceRange(a, 1, 3, &.{ 8, 9 });
1251
1252 testing.expectEqualSlices(u8, list.items, &.{ 0, 8, 9, 6, 7, 2, 3 });
1253 }
1254}