authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-13 15:56:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-13 15:56:52-07:00
loga8e2a21a86673c2f5ebecb3d21701e12bdca683c
tree60bff94cb54dbceade3ef79e8fbfee756375e4ef
parente5a95c6af123d614522de57f875b620deb152cc0

std.array_list: promote tests to doctests

This moves most tests from ArrayList and ArrayListUnmanaged into the corresponding namespace and provides a doctest for nearly every method.

1 files changed, 798 insertions(+), 699 deletions(-)

lib/std/array_list.zig+798-699
......@@ -58,6 +58,14 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
5858 };
5959 }
6060
61 test init {
62 var list = ArrayList(i32).init(testing.allocator);
63 defer list.deinit();
64
65 try testing.expect(list.items.len == 0);
66 try testing.expect(list.capacity == 0);
67 }
68
6169 /// Initialize with capacity to hold `num` elements.
6270 /// The resulting capacity will equal `num` exactly.
6371 /// Deinitialize with `deinit` or use `toOwnedSlice`.
......@@ -67,6 +75,13 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
6775 return self;
6876 }
6977
78 test initCapacity {
79 var list = try ArrayList(i8).initCapacity(testing.allocator, 200);
80 defer list.deinit();
81 try testing.expect(list.items.len == 0);
82 try testing.expect(list.capacity >= 200);
83 }
84
7085 /// Release all allocated memory.
7186 pub fn deinit(self: Self) void {
7287 if (@sizeOf(T) > 0) {
......@@ -85,17 +100,31 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
85100 };
86101 }
87102
103 test fromOwnedSlice {
104 const slice = try testing.allocator.dupe(u8, "foobar");
105 var list = ArrayList(u8).fromOwnedSlice(testing.allocator, slice);
106 defer list.deinit();
107 try testing.expectEqualStrings(list.items, "foobar");
108 }
109
88110 /// ArrayList takes ownership of the passed in slice. The slice must have been
89111 /// allocated with `allocator`.
90112 /// Deinitialize with `deinit` or use `toOwnedSlice`.
91113 pub fn fromOwnedSliceSentinel(allocator: Allocator, comptime sentinel: T, slice: [:sentinel]T) Self {
92 return Self{
114 return .{
93115 .items = slice,
94116 .capacity = slice.len + 1,
95117 .allocator = allocator,
96118 };
97119 }
98120
121 test fromOwnedSliceSentinel {
122 const sentinel_slice = try testing.allocator.dupeZ(u8, "foobar");
123 var list = ArrayList(u8).fromOwnedSliceSentinel(testing.allocator, 0, sentinel_slice);
124 defer list.deinit();
125 try testing.expectEqualStrings(list.items, "foobar");
126 }
127
99128 /// Initializes an ArrayListUnmanaged with the `items` and `capacity` fields
100129 /// of this ArrayList. Empties this ArrayList.
101130 pub fn moveToUnmanaged(self: *Self) ArrayListAlignedUnmanaged(T, alignment) {
......@@ -125,14 +154,29 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
125154 }
126155
127156 /// The caller owns the returned memory. Empties this ArrayList.
128 pub fn toOwnedSliceSentinel(self: *Self, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) {
129 // This addition can never overflow because `self.items` can never occupy the whole address space
157 pub fn toOwnedSliceSentinel(
158 self: *Self,
159 comptime sentinel: T,
160 ) Allocator.Error!SentinelSlice(sentinel) {
161 // This addition can never overflow because `self.items` can never
162 // occupy the whole address space
130163 try self.ensureTotalCapacityPrecise(self.items.len + 1);
131164 self.appendAssumeCapacity(sentinel);
132165 const result = try self.toOwnedSlice();
133166 return result[0 .. result.len - 1 :sentinel];
134167 }
135168
169 test toOwnedSliceSentinel {
170 var list = ArrayList(u8).init(testing.allocator);
171 defer list.deinit();
172
173 try list.appendSlice("foobar");
174
175 const result = try list.toOwnedSliceSentinel(0);
176 defer testing.allocator.free(result);
177 try testing.expectEqualStrings(result, mem.sliceTo(result.ptr, 0));
178 }
179
136180 /// Creates a copy of this ArrayList, using the same allocator.
137181 pub fn clone(self: Self) Allocator.Error!Self {
138182 var cloned = try Self.initCapacity(self.allocator, self.capacity);
......@@ -140,6 +184,26 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
140184 return cloned;
141185 }
142186
187 test clone {
188 var array = ArrayList(i32).init(testing.allocator);
189 try array.append(-1);
190 try array.append(3);
191 try array.append(5);
192
193 const cloned = try array.clone();
194 defer cloned.deinit();
195
196 try testing.expectEqualSlices(i32, array.items, cloned.items);
197 try testing.expectEqual(array.allocator, cloned.allocator);
198 try testing.expect(cloned.capacity >= array.capacity);
199
200 array.deinit();
201
202 try testing.expectEqual(@as(i32, -1), cloned.items[0]);
203 try testing.expectEqual(@as(i32, 3), cloned.items[1]);
204 try testing.expectEqual(@as(i32, 5), cloned.items[2]);
205 }
206
143207 /// Insert `item` at index `i`. Moves `list[i .. list.len]` to higher indices to make room.
144208 /// If `i` is equal to the length of the list this operation is equivalent to append.
145209 /// This operation is O(N).
......@@ -150,6 +214,20 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
150214 dst[0] = item;
151215 }
152216
217 test insert {
218 var list = ArrayList(i32).init(testing.allocator);
219 defer list.deinit();
220
221 try list.insert(0, 1);
222 try list.append(2);
223 try list.insert(2, 3);
224 try list.insert(0, 5);
225 try testing.expect(list.items[0] == 5);
226 try testing.expect(list.items[1] == 1);
227 try testing.expect(list.items[2] == 2);
228 try testing.expect(list.items[3] == 3);
229 }
230
153231 /// Insert `item` at index `i`. Moves `list[i .. list.len]` to higher indices to make room.
154232 /// If `i` is equal to the length of the list this operation is
155233 /// equivalent to appendAssumeCapacity.
......@@ -238,6 +316,28 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
238316 @memcpy(dst, items);
239317 }
240318
319 test insertSlice {
320 var list = ArrayList(i32).init(testing.allocator);
321 defer list.deinit();
322
323 try list.append(1);
324 try list.append(2);
325 try list.append(3);
326 try list.append(4);
327 try list.insertSlice(1, &[_]i32{ 9, 8 });
328 try testing.expect(list.items[0] == 1);
329 try testing.expect(list.items[1] == 9);
330 try testing.expect(list.items[2] == 8);
331 try testing.expect(list.items[3] == 2);
332 try testing.expect(list.items[4] == 3);
333 try testing.expect(list.items[5] == 4);
334
335 const items = [_]i32{1};
336 try list.insertSlice(0, items[0..0]);
337 try testing.expect(list.items.len == 6);
338 try testing.expect(list.items[0] == 1);
339 }
340
241341 /// Grows or shrinks the list as necessary.
242342 /// Invalidates element pointers if additional capacity is allocated.
243343 /// Asserts that the range is in bounds.
......@@ -247,6 +347,46 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
247347 return unmanaged.replaceRange(self.allocator, start, len, new_items);
248348 }
249349
350 test replaceRange {
351 const init_value = [_]i32{ 1, 2, 3, 4, 5 };
352 const new = [_]i32{ 0, 0, 0 };
353
354 const result_zero = [_]i32{ 1, 0, 0, 0, 2, 3, 4, 5 };
355 const result_eq = [_]i32{ 1, 0, 0, 0, 5 };
356 const result_le = [_]i32{ 1, 0, 0, 0, 4, 5 };
357 const result_gt = [_]i32{ 1, 0, 0, 0 };
358
359 var list_zero = ArrayList(i32).init(testing.allocator);
360 defer list_zero.deinit();
361
362 var list_eq = ArrayList(i32).init(testing.allocator);
363 defer list_eq.deinit();
364
365 var list_lt = ArrayList(i32).init(testing.allocator);
366 defer list_lt.deinit();
367
368 var list_gt = ArrayList(i32).init(testing.allocator);
369 defer list_gt.deinit();
370
371 try list_zero.appendSlice(&init_value);
372 try list_eq.appendSlice(&init_value);
373 try list_lt.appendSlice(&init_value);
374 try list_gt.appendSlice(&init_value);
375
376 try list_zero.replaceRange(1, 0, &new);
377 try list_eq.replaceRange(1, 3, &new);
378 try list_lt.replaceRange(1, 2, &new);
379
380 // after_range > new_items.len in function body
381 try testing.expect(1 + 4 > new.len);
382 try list_gt.replaceRange(1, 4, &new);
383
384 try testing.expectEqualSlices(i32, list_zero.items, &result_zero);
385 try testing.expectEqualSlices(i32, list_eq.items, &result_eq);
386 try testing.expectEqualSlices(i32, list_lt.items, &result_le);
387 try testing.expectEqualSlices(i32, list_gt.items, &result_gt);
388 }
389
250390 /// Grows or shrinks the list as necessary.
251391 /// Never invalidates element pointers.
252392 /// Asserts the capacity is enough for additional items.
......@@ -256,6 +396,46 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
256396 return unmanaged.replaceRangeAssumeCapacity(start, len, new_items);
257397 }
258398
399 test replaceRangeAssumeCapacity {
400 const init_value = [_]i32{ 1, 2, 3, 4, 5 };
401 const new = [_]i32{ 0, 0, 0 };
402
403 const result_zero = [_]i32{ 1, 0, 0, 0, 2, 3, 4, 5 };
404 const result_eq = [_]i32{ 1, 0, 0, 0, 5 };
405 const result_le = [_]i32{ 1, 0, 0, 0, 4, 5 };
406 const result_gt = [_]i32{ 1, 0, 0, 0 };
407
408 var list_zero = ArrayList(i32).init(testing.allocator);
409 defer list_zero.deinit();
410
411 var list_eq = ArrayList(i32).init(testing.allocator);
412 defer list_eq.deinit();
413
414 var list_lt = ArrayList(i32).init(testing.allocator);
415 defer list_lt.deinit();
416
417 var list_gt = ArrayList(i32).init(testing.allocator);
418 defer list_gt.deinit();
419
420 try list_zero.appendSlice(&init_value);
421 try list_eq.appendSlice(&init_value);
422 try list_lt.appendSlice(&init_value);
423 try list_gt.appendSlice(&init_value);
424
425 list_zero.replaceRangeAssumeCapacity(1, 0, &new);
426 list_eq.replaceRangeAssumeCapacity(1, 3, &new);
427 list_lt.replaceRangeAssumeCapacity(1, 2, &new);
428
429 // after_range > new_items.len in function body
430 try testing.expect(1 + 4 > new.len);
431 list_gt.replaceRangeAssumeCapacity(1, 4, &new);
432
433 try testing.expectEqualSlices(i32, list_zero.items, &result_zero);
434 try testing.expectEqualSlices(i32, list_eq.items, &result_eq);
435 try testing.expectEqualSlices(i32, list_lt.items, &result_le);
436 try testing.expectEqualSlices(i32, list_gt.items, &result_gt);
437 }
438
259439 /// Extends the list by 1 element. Allocates more memory as necessary.
260440 /// Invalidates element pointers if additional memory is needed.
261441 pub fn append(self: *Self, item: T) Allocator.Error!void {
......@@ -284,6 +464,44 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
284464 return old_item;
285465 }
286466
467 test orderedRemove {
468 {
469 var list = ArrayList(i32).init(testing.allocator);
470 defer list.deinit();
471
472 try list.append(1);
473 try list.append(2);
474 try list.append(3);
475 try list.append(4);
476 try list.append(5);
477 try list.append(6);
478 try list.append(7);
479
480 //remove from middle
481 try testing.expectEqual(@as(i32, 4), list.orderedRemove(3));
482 try testing.expectEqual(@as(i32, 5), list.items[3]);
483 try testing.expectEqual(@as(usize, 6), list.items.len);
484
485 //remove from end
486 try testing.expectEqual(@as(i32, 7), list.orderedRemove(5));
487 try testing.expectEqual(@as(usize, 5), list.items.len);
488
489 //remove from front
490 try testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
491 try testing.expectEqual(@as(i32, 2), list.items[0]);
492 try testing.expectEqual(@as(usize, 4), list.items.len);
493 }
494 {
495 // remove last item
496 var list = ArrayList(i32).init(testing.allocator);
497 defer list.deinit();
498
499 try list.append(1);
500 try testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
501 try testing.expectEqual(@as(usize, 0), list.items.len);
502 }
503 }
504
287505 /// Removes the element at the specified index and returns it.
288506 /// The empty slot is filled from the end of the list.
289507 /// This operation is O(1).
......@@ -298,6 +516,33 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
298516 return old_item;
299517 }
300518
519 test swapRemove {
520 var list = ArrayList(i32).init(testing.allocator);
521 defer list.deinit();
522
523 try list.append(1);
524 try list.append(2);
525 try list.append(3);
526 try list.append(4);
527 try list.append(5);
528 try list.append(6);
529 try list.append(7);
530
531 //remove from middle
532 try testing.expect(list.swapRemove(3) == 4);
533 try testing.expect(list.items[3] == 7);
534 try testing.expect(list.items.len == 6);
535
536 //remove from end
537 try testing.expect(list.swapRemove(5) == 6);
538 try testing.expect(list.items.len == 5);
539
540 //remove from front
541 try testing.expect(list.swapRemove(0) == 1);
542 try testing.expect(list.items[0] == 5);
543 try testing.expect(list.items.len == 4);
544 }
545
301546 /// Append the slice of items to the list. Allocates more
302547 /// memory as necessary.
303548 /// Invalidates element pointers if additional memory is needed.
......@@ -351,6 +596,17 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
351596 return .{ .context = self };
352597 }
353598
599 test writer {
600 var buffer = ArrayList(u8).init(testing.allocator);
601 defer buffer.deinit();
602
603 const x: i32 = 42;
604 const y: i32 = 1234;
605 try buffer.writer().print("x: {}\ny: {}\n", .{ x, y });
606
607 try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.items);
608 }
609
354610 /// Same as `append` except it returns the number of bytes written, which is always the same
355611 /// as `m.len`. The purpose of this function existing is to match `std.io.Writer` API.
356612 /// Invalidates element pointers if additional memory is needed.
......@@ -370,6 +626,17 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
370626 @memset(self.items[old_len..self.items.len], value);
371627 }
372628
629 test appendNTimes {
630 var list = ArrayList(i32).init(testing.allocator);
631 defer list.deinit();
632
633 try list.appendNTimes(2, 10);
634 try testing.expectEqual(@as(usize, 10), list.items.len);
635 for (list.items) |element| {
636 try testing.expectEqual(@as(i32, 2), element);
637 }
638 }
639
373640 /// Append a value to the list `n` times.
374641 /// Never invalidates element pointers.
375642 /// The function is inline so that a comptime-known `value` parameter will
......@@ -399,6 +666,24 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
399666 self.* = unmanaged.toManaged(self.allocator);
400667 }
401668
669 test shrinkAndFree {
670 var failing_allocator = testing.FailingAllocator.init(testing.allocator, .{});
671
672 var list = ArrayList(i32).init(failing_allocator.allocator());
673 defer list.deinit();
674
675 try list.append(1);
676 try list.append(2);
677 try list.append(3);
678
679 // Even though our allocator fails to resize in place here, the
680 // shrinkAndFree operation succeeds by moving the allocation.
681 failing_allocator.resize_fail_index = failing_allocator.resize_index;
682 list.shrinkAndFree(1);
683 try testing.expect(list.items.len == 1);
684 try testing.expect(list.capacity == 1);
685 }
686
402687 /// Reduce length to `new_len`.
403688 /// Invalidates element pointers for the elements `items[new_len..]`.
404689 /// Asserts that the new length is less than or equal to the previous length.
......@@ -504,6 +789,17 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
504789 return self.items[prev_len..][0..n];
505790 }
506791
792 test addManyAsArray {
793 var list = ArrayList(u8).init(testing.allocator);
794 defer list.deinit();
795
796 (try list.addManyAsArray(4)).* = "aoeu".*;
797 try list.ensureTotalCapacity(8);
798 list.addManyAsArrayAssumeCapacity(4).* = "asdf".*;
799
800 try testing.expectEqualSlices(u8, list.items, "aoeuasdf");
801 }
802
507803 /// Resize the array, adding `n` new elements, which have `undefined` values.
508804 /// The return value is an array pointing to the newly allocated elements.
509805 /// Never invalidates element pointers.
......@@ -555,6 +851,21 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
555851 return self.pop();
556852 }
557853
854 test popOrNull {
855 var list = ArrayList(?u33).init(testing.allocator);
856 defer list.deinit();
857
858 try list.append(null);
859 try list.append(1);
860 try list.append(2);
861 try testing.expectEqual(list.items.len, 3);
862
863 try testing.expect(list.popOrNull().? == @as(u32, 2));
864 try testing.expect(list.popOrNull().? == @as(u32, 1));
865 try testing.expect(list.popOrNull().? == null);
866 try testing.expect(list.popOrNull() == null);
867 }
868
558869 /// Returns a slice of all the items plus the extra capacity, whose memory
559870 /// contents are `undefined`.
560871 pub fn allocatedSlice(self: Self) Slice {
......@@ -577,11 +888,31 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
577888 return val;
578889 }
579890
891 test getLast {
892 var list = ArrayList(u32).init(testing.allocator);
893 defer list.deinit();
894
895 try list.append(2);
896 const const_list = list;
897 try testing.expectEqual(const_list.getLast(), 2);
898 }
899
580900 /// Returns the last element from the list, or `null` if list is empty.
581901 pub fn getLastOrNull(self: Self) ?T {
582902 if (self.items.len == 0) return null;
583903 return self.getLast();
584904 }
905
906 test getLastOrNull {
907 var list = ArrayList(u32).init(testing.allocator);
908 defer list.deinit();
909
910 try testing.expectEqual(list.getLastOrNull(), null);
911
912 try list.append(2);
913 const const_list = list;
914 try testing.expectEqual(const_list.getLastOrNull().?, 2);
915 }
585916 };
586917}
587918
......@@ -635,6 +966,14 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
635966 return self;
636967 }
637968
969 test initCapacity {
970 const a = testing.allocator;
971 var list = try ArrayListUnmanaged(i8).initCapacity(a, 200);
972 defer list.deinit(a);
973 try testing.expect(list.items.len == 0);
974 try testing.expect(list.capacity >= 200);
975 }
976
638977 /// Initialize with externally-managed memory. The buffer determines the
639978 /// capacity, and the length is set to zero.
640979 /// When initialized this way, all functions that accept an Allocator
......@@ -662,22 +1001,38 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
6621001 /// allocated with `allocator`.
6631002 /// Deinitialize with `deinit` or use `toOwnedSlice`.
6641003 pub fn fromOwnedSlice(slice: Slice) Self {
665 return Self{
1004 return .{
6661005 .items = slice,
6671006 .capacity = slice.len,
6681007 };
6691008 }
6701009
1010 test fromOwnedSlice {
1011 const a = testing.allocator;
1012 const slice = try a.dupe(u8, "foobar");
1013 var list = ArrayListUnmanaged(u8).fromOwnedSlice(slice);
1014 defer list.deinit(a);
1015 try testing.expectEqualStrings(list.items, "foobar");
1016 }
1017
6711018 /// ArrayListUnmanaged takes ownership of the passed in slice. The slice must have been
6721019 /// allocated with `allocator`.
6731020 /// Deinitialize with `deinit` or use `toOwnedSlice`.
6741021 pub fn fromOwnedSliceSentinel(comptime sentinel: T, slice: [:sentinel]T) Self {
675 return Self{
1022 return .{
6761023 .items = slice,
6771024 .capacity = slice.len + 1,
6781025 };
6791026 }
6801027
1028 test fromOwnedSliceSentinel {
1029 const a = testing.allocator;
1030 const sentinel_slice = try a.dupeZ(u8, "foobar");
1031 var list = ArrayListUnmanaged(u8).fromOwnedSliceSentinel(0, sentinel_slice);
1032 defer list.deinit(a);
1033 try testing.expectEqualStrings(list.items, "foobar");
1034 }
1035
6811036 /// The caller owns the returned memory. Empties this ArrayList.
6821037 /// Its capacity is cleared, making deinit() safe but unnecessary to call.
6831038 pub fn toOwnedSlice(self: *Self, allocator: Allocator) Allocator.Error!Slice {
......@@ -696,14 +1051,32 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
6961051 }
6971052
6981053 /// The caller owns the returned memory. ArrayList becomes empty.
699 pub fn toOwnedSliceSentinel(self: *Self, allocator: Allocator, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) {
700 // This addition can never overflow because `self.items` can never occupy the whole address space
1054 pub fn toOwnedSliceSentinel(
1055 self: *Self,
1056 allocator: Allocator,
1057 comptime sentinel: T,
1058 ) Allocator.Error!SentinelSlice(sentinel) {
1059 // This addition can never overflow because `self.items` can never
1060 // occupy the whole address space
7011061 try self.ensureTotalCapacityPrecise(allocator, self.items.len + 1);
7021062 self.appendAssumeCapacity(sentinel);
7031063 const result = try self.toOwnedSlice(allocator);
7041064 return result[0 .. result.len - 1 :sentinel];
7051065 }
7061066
1067 test toOwnedSliceSentinel {
1068 const gpa = testing.allocator;
1069
1070 var list: ArrayListUnmanaged(u8) = .{};
1071 defer list.deinit(gpa);
1072
1073 try list.appendSlice(gpa, "foobar");
1074
1075 const result = try list.toOwnedSliceSentinel(gpa, 0);
1076 defer testing.allocator.free(result);
1077 try testing.expectEqualStrings(result, mem.sliceTo(result.ptr, 0));
1078 }
1079
7071080 /// Creates a copy of this ArrayList.
7081081 pub fn clone(self: Self, allocator: Allocator) Allocator.Error!Self {
7091082 var cloned = try Self.initCapacity(allocator, self.capacity);
......@@ -711,6 +1084,27 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
7111084 return cloned;
7121085 }
7131086
1087 test clone {
1088 const a = testing.allocator;
1089
1090 var array: ArrayListUnmanaged(i32) = .{};
1091 try array.append(a, -1);
1092 try array.append(a, 3);
1093 try array.append(a, 5);
1094
1095 var cloned = try array.clone(a);
1096 defer cloned.deinit(a);
1097
1098 try testing.expectEqualSlices(i32, array.items, cloned.items);
1099 try testing.expect(cloned.capacity >= array.capacity);
1100
1101 array.deinit(a);
1102
1103 try testing.expectEqual(@as(i32, -1), cloned.items[0]);
1104 try testing.expectEqual(@as(i32, 3), cloned.items[1]);
1105 try testing.expectEqual(@as(i32, 5), cloned.items[2]);
1106 }
1107
7141108 /// Insert `item` at index `i`. Moves `list[i .. list.len]` to higher indices to make room.
7151109 /// If `i` is equal to the length of the list this operation is equivalent to append.
7161110 /// This operation is O(N).
......@@ -721,6 +1115,22 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
7211115 dst[0] = item;
7221116 }
7231117
1118 test insert {
1119 const a = testing.allocator;
1120
1121 var list: ArrayListUnmanaged(i32) = .{};
1122 defer list.deinit(a);
1123
1124 try list.insert(a, 0, 1);
1125 try list.append(a, 2);
1126 try list.insert(a, 2, 3);
1127 try list.insert(a, 0, 5);
1128 try testing.expect(list.items[0] == 5);
1129 try testing.expect(list.items[1] == 1);
1130 try testing.expect(list.items[2] == 2);
1131 try testing.expect(list.items[3] == 3);
1132 }
1133
7241134 /// Insert `item` at index `i`. Moves `list[i .. list.len]` to higher indices to make room.
7251135 /// If in` is equal to the length of the list this operation is equivalent to append.
7261136 /// This operation is O(N).
......@@ -792,6 +1202,30 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
7921202 @memcpy(dst, items);
7931203 }
7941204
1205 test insertSlice {
1206 const a = testing.allocator;
1207
1208 var list: ArrayListUnmanaged(i32) = .{};
1209 defer list.deinit(a);
1210
1211 try list.append(a, 1);
1212 try list.append(a, 2);
1213 try list.append(a, 3);
1214 try list.append(a, 4);
1215 try list.insertSlice(a, 1, &[_]i32{ 9, 8 });
1216 try testing.expect(list.items[0] == 1);
1217 try testing.expect(list.items[1] == 9);
1218 try testing.expect(list.items[2] == 8);
1219 try testing.expect(list.items[3] == 2);
1220 try testing.expect(list.items[4] == 3);
1221 try testing.expect(list.items[5] == 4);
1222
1223 const items = [_]i32{1};
1224 try list.insertSlice(a, 0, items[0..0]);
1225 try testing.expect(list.items.len == 6);
1226 try testing.expect(list.items[0] == 1);
1227 }
1228
7951229 /// Grows or shrinks the list as necessary.
7961230 /// Invalidates element pointers if additional capacity is allocated.
7971231 /// Asserts that the range is in bounds.
......@@ -814,6 +1248,48 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
8141248 }
8151249 }
8161250
1251 test replaceRange {
1252 const init_value = [_]i32{ 1, 2, 3, 4, 5 };
1253 const new = [_]i32{ 0, 0, 0 };
1254
1255 const result_zero = [_]i32{ 1, 0, 0, 0, 2, 3, 4, 5 };
1256 const result_eq = [_]i32{ 1, 0, 0, 0, 5 };
1257 const result_le = [_]i32{ 1, 0, 0, 0, 4, 5 };
1258 const result_gt = [_]i32{ 1, 0, 0, 0 };
1259
1260 const a = testing.allocator;
1261
1262 var list_zero: ArrayListUnmanaged(i32) = .{};
1263 defer list_zero.deinit(a);
1264
1265 var list_eq: ArrayListUnmanaged(i32) = .{};
1266 defer list_eq.deinit(a);
1267
1268 var list_lt: ArrayListUnmanaged(i32) = .{};
1269 defer list_lt.deinit(a);
1270
1271 var list_gt: ArrayListUnmanaged(i32) = .{};
1272 defer list_gt.deinit(a);
1273
1274 try list_zero.appendSlice(a, &init_value);
1275 try list_eq.appendSlice(a, &init_value);
1276 try list_lt.appendSlice(a, &init_value);
1277 try list_gt.appendSlice(a, &init_value);
1278
1279 try list_zero.replaceRange(a, 1, 0, &new);
1280 try list_eq.replaceRange(a, 1, 3, &new);
1281 try list_lt.replaceRange(a, 1, 2, &new);
1282
1283 // after_range > new_items.len in function body
1284 try testing.expect(1 + 4 > new.len);
1285 try list_gt.replaceRange(a, 1, 4, &new);
1286
1287 try testing.expectEqualSlices(i32, list_zero.items, &result_zero);
1288 try testing.expectEqualSlices(i32, list_eq.items, &result_eq);
1289 try testing.expectEqualSlices(i32, list_lt.items, &result_le);
1290 try testing.expectEqualSlices(i32, list_gt.items, &result_gt);
1291 }
1292
8171293 /// Grows or shrinks the list as necessary.
8181294 /// Never invalidates element pointers.
8191295 /// Asserts the capacity is enough for additional items.
......@@ -842,6 +1318,48 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
8421318 }
8431319 }
8441320
1321 test replaceRangeAssumeCapacity {
1322 const init_value = [_]i32{ 1, 2, 3, 4, 5 };
1323 const new = [_]i32{ 0, 0, 0 };
1324
1325 const result_zero = [_]i32{ 1, 0, 0, 0, 2, 3, 4, 5 };
1326 const result_eq = [_]i32{ 1, 0, 0, 0, 5 };
1327 const result_le = [_]i32{ 1, 0, 0, 0, 4, 5 };
1328 const result_gt = [_]i32{ 1, 0, 0, 0 };
1329
1330 const a = testing.allocator;
1331
1332 var list_zero: ArrayListUnmanaged(i32) = .{};
1333 defer list_zero.deinit(a);
1334
1335 var list_eq: ArrayListUnmanaged(i32) = .{};
1336 defer list_eq.deinit(a);
1337
1338 var list_lt: ArrayListUnmanaged(i32) = .{};
1339 defer list_lt.deinit(a);
1340
1341 var list_gt: ArrayListUnmanaged(i32) = .{};
1342 defer list_gt.deinit(a);
1343
1344 try list_zero.appendSlice(a, &init_value);
1345 try list_eq.appendSlice(a, &init_value);
1346 try list_lt.appendSlice(a, &init_value);
1347 try list_gt.appendSlice(a, &init_value);
1348
1349 list_zero.replaceRangeAssumeCapacity(1, 0, &new);
1350 list_eq.replaceRangeAssumeCapacity(1, 3, &new);
1351 list_lt.replaceRangeAssumeCapacity(1, 2, &new);
1352
1353 // after_range > new_items.len in function body
1354 try testing.expect(1 + 4 > new.len);
1355 list_gt.replaceRangeAssumeCapacity(1, 4, &new);
1356
1357 try testing.expectEqualSlices(i32, list_zero.items, &result_zero);
1358 try testing.expectEqualSlices(i32, list_eq.items, &result_eq);
1359 try testing.expectEqualSlices(i32, list_lt.items, &result_le);
1360 try testing.expectEqualSlices(i32, list_gt.items, &result_gt);
1361 }
1362
8451363 /// Extend the list by 1 element. Allocates more memory as necessary.
8461364 /// Invalidates element pointers if additional memory is needed.
8471365 pub fn append(self: *Self, allocator: Allocator, item: T) Allocator.Error!void {
......@@ -868,6 +1386,44 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
8681386 return old_item;
8691387 }
8701388
1389 test orderedRemove {
1390 const a = testing.allocator;
1391 {
1392 var list: ArrayListUnmanaged(i32) = .{};
1393 defer list.deinit(a);
1394
1395 try list.append(a, 1);
1396 try list.append(a, 2);
1397 try list.append(a, 3);
1398 try list.append(a, 4);
1399 try list.append(a, 5);
1400 try list.append(a, 6);
1401 try list.append(a, 7);
1402
1403 //remove from middle
1404 try testing.expectEqual(@as(i32, 4), list.orderedRemove(3));
1405 try testing.expectEqual(@as(i32, 5), list.items[3]);
1406 try testing.expectEqual(@as(usize, 6), list.items.len);
1407
1408 //remove from end
1409 try testing.expectEqual(@as(i32, 7), list.orderedRemove(5));
1410 try testing.expectEqual(@as(usize, 5), list.items.len);
1411
1412 //remove from front
1413 try testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
1414 try testing.expectEqual(@as(i32, 2), list.items[0]);
1415 try testing.expectEqual(@as(usize, 4), list.items.len);
1416 }
1417 {
1418 // remove last item
1419 var list: ArrayListUnmanaged(i32) = .{};
1420 defer list.deinit(a);
1421 try list.append(a, 1);
1422 try testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
1423 try testing.expectEqual(@as(usize, 0), list.items.len);
1424 }
1425 }
1426
8711427 /// Removes the element at the specified index and returns it.
8721428 /// The empty slot is filled from the end of the list.
8731429 /// Invalidates pointers to last element.
......@@ -882,6 +1438,34 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
8821438 return old_item;
8831439 }
8841440
1441 test swapRemove {
1442 const a = testing.allocator;
1443 var list: ArrayListUnmanaged(i32) = .{};
1444 defer list.deinit(a);
1445
1446 try list.append(a, 1);
1447 try list.append(a, 2);
1448 try list.append(a, 3);
1449 try list.append(a, 4);
1450 try list.append(a, 5);
1451 try list.append(a, 6);
1452 try list.append(a, 7);
1453
1454 //remove from middle
1455 try testing.expect(list.swapRemove(3) == 4);
1456 try testing.expect(list.items[3] == 7);
1457 try testing.expect(list.items.len == 6);
1458
1459 //remove from end
1460 try testing.expect(list.swapRemove(5) == 6);
1461 try testing.expect(list.items.len == 5);
1462
1463 //remove from front
1464 try testing.expect(list.swapRemove(0) == 1);
1465 try testing.expect(list.items[0] == 5);
1466 try testing.expect(list.items.len == 4);
1467 }
1468
8851469 /// Append the slice of items to the list. Allocates more
8861470 /// memory as necessary.
8871471 /// Invalidates element pointers if additional memory is needed.
......@@ -937,6 +1521,33 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
9371521 return .{ .context = .{ .self = self, .allocator = allocator } };
9381522 }
9391523
1524 test writer {
1525 const a = testing.allocator;
1526
1527 {
1528 var buffer: ArrayListUnmanaged(u8) = .{};
1529 defer buffer.deinit(a);
1530
1531 const x: i32 = 42;
1532 const y: i32 = 1234;
1533 try buffer.writer(a).print("x: {}\ny: {}\n", .{ x, y });
1534
1535 try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.items);
1536 }
1537 {
1538 var list: ArrayListAlignedUnmanaged(u8, 2) = .{};
1539 defer list.deinit(a);
1540
1541 const w = list.writer(a);
1542 try w.writeAll("a");
1543 try w.writeAll("bc");
1544 try w.writeAll("d");
1545 try w.writeAll("efg");
1546
1547 try testing.expectEqualSlices(u8, list.items, "abcdefg");
1548 }
1549 }
1550
9401551 /// Same as `append` except it returns the number of bytes written,
9411552 /// which is always the same as `m.len`. The purpose of this function
9421553 /// existing is to match `std.io.Writer` API.
......@@ -975,6 +1586,19 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
9751586 @memset(self.items[old_len..self.items.len], value);
9761587 }
9771588
1589 test appendNTimes {
1590 const a = testing.allocator;
1591
1592 var list = ArrayListUnmanaged(i32){};
1593 defer list.deinit(a);
1594
1595 try list.appendNTimes(a, 2, 10);
1596 try testing.expectEqual(@as(usize, 10), list.items.len);
1597 for (list.items) |element| {
1598 try testing.expectEqual(@as(i32, 2), element);
1599 }
1600 }
1601
9781602 /// Append a value to the list `n` times.
9791603 /// Never invalidates element pointers.
9801604 /// The function is inline so that a comptime-known `value` parameter will
......@@ -1027,6 +1651,25 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
10271651 self.capacity = new_memory.len;
10281652 }
10291653
1654 test shrinkAndFree {
1655 var failing_allocator = testing.FailingAllocator.init(testing.allocator, .{});
1656 const a = failing_allocator.allocator();
1657
1658 var list: ArrayListUnmanaged(i32) = .{};
1659 defer list.deinit(a);
1660
1661 try list.append(a, 1);
1662 try list.append(a, 2);
1663 try list.append(a, 3);
1664
1665 // Even though our allocator fails to resize in place here, the
1666 // shrinkAndFree operation succeeds by moving the allocation.
1667 failing_allocator.resize_fail_index = failing_allocator.resize_index;
1668 list.shrinkAndFree(a, 1);
1669 try testing.expect(list.items.len == 1);
1670 try testing.expect(list.capacity == 1);
1671 }
1672
10301673 /// Reduce length to `new_len`.
10311674 /// Invalidates pointers to elements `items[new_len..]`.
10321675 /// Keeps capacity the same.
......@@ -1132,6 +1775,19 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
11321775 return self.items[prev_len..][0..n];
11331776 }
11341777
1778 test addManyAsArray {
1779 const a = testing.allocator;
1780
1781 var list: ArrayListUnmanaged(u8) = .{};
1782 defer list.deinit(a);
1783
1784 (try list.addManyAsArray(a, 4)).* = "aoeu".*;
1785 try list.ensureTotalCapacity(a, 8);
1786 list.addManyAsArrayAssumeCapacity(4).* = "asdf".*;
1787
1788 try testing.expectEqualSlices(u8, list.items, "aoeuasdf");
1789 }
1790
11351791 /// Resize the array, adding `n` new elements, which have `undefined` values.
11361792 /// The return value is an array pointing to the newly allocated elements.
11371793 /// Never invalidates element pointers.
......@@ -1183,6 +1839,23 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
11831839 return self.pop();
11841840 }
11851841
1842 test popOrNull {
1843 const gpa = testing.allocator;
1844
1845 var list: ArrayListUnmanaged(?u32) = .{};
1846 defer list.deinit(gpa);
1847
1848 try list.append(gpa, null);
1849 try list.append(gpa, 1);
1850 try list.append(gpa, 2);
1851 try testing.expectEqual(list.items.len, 3);
1852
1853 try testing.expect(list.popOrNull().? == @as(u32, 2));
1854 try testing.expect(list.popOrNull().? == @as(u32, 1));
1855 try testing.expect(list.popOrNull().? == null);
1856 try testing.expect(list.popOrNull() == null);
1857 }
1858
11861859 /// Returns a slice of all the items plus the extra capacity, whose memory
11871860 /// contents are `undefined`.
11881861 pub fn allocatedSlice(self: Self) Slice {
......@@ -1204,12 +1877,36 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
12041877 return val;
12051878 }
12061879
1880 test getLast {
1881 const gpa = testing.allocator;
1882
1883 var list: ArrayListUnmanaged(u32) = .{};
1884 defer list.deinit(gpa);
1885
1886 try list.append(gpa, 2);
1887 const const_list = list;
1888 try testing.expectEqual(const_list.getLast(), 2);
1889 }
1890
12071891 /// Return the last element from the list, or
12081892 /// return `null` if list is empty.
12091893 pub fn getLastOrNull(self: Self) ?T {
12101894 if (self.items.len == 0) return null;
12111895 return self.getLast();
12121896 }
1897
1898 test getLastOrNull {
1899 const a = testing.allocator;
1900
1901 var list: ArrayListUnmanaged(u32) = .{};
1902 defer list.deinit(a);
1903
1904 try testing.expectEqual(list.getLastOrNull(), null);
1905
1906 try list.append(a, 2);
1907 const const_list = list;
1908 try testing.expectEqual(const_list.getLastOrNull().?, 2);
1909 }
12131910 };
12141911}
12151912
......@@ -1231,206 +1928,108 @@ fn addOrOom(a: usize, b: usize) error{OutOfMemory}!usize {
12311928 return result;
12321929}
12331930
1234test "init" {
1235 {
1236 var list = ArrayList(i32).init(testing.allocator);
1237 defer list.deinit();
1238
1239 try testing.expect(list.items.len == 0);
1240 try testing.expect(list.capacity == 0);
1241 }
1931test ArrayList {
1932 var list = ArrayList(i32).init(testing.allocator);
1933 defer list.deinit();
12421934
12431935 {
1244 const list = ArrayListUnmanaged(i32){};
1245
1246 try testing.expect(list.items.len == 0);
1247 try testing.expect(list.capacity == 0);
1936 var i: usize = 0;
1937 while (i < 10) : (i += 1) {
1938 try list.append(@as(i32, @intCast(i + 1)));
1939 }
12481940 }
1249}
12501941
1251test "initCapacity" {
1252 const a = testing.allocator;
12531942 {
1254 var list = try ArrayList(i8).initCapacity(a, 200);
1255 defer list.deinit();
1256 try testing.expect(list.items.len == 0);
1257 try testing.expect(list.capacity >= 200);
1258 }
1259 {
1260 var list = try ArrayListUnmanaged(i8).initCapacity(a, 200);
1261 defer list.deinit(a);
1262 try testing.expect(list.items.len == 0);
1263 try testing.expect(list.capacity >= 200);
1943 var i: usize = 0;
1944 while (i < 10) : (i += 1) {
1945 try testing.expect(list.items[i] == @as(i32, @intCast(i + 1)));
1946 }
12641947 }
1265}
12661948
1267test "clone" {
1268 const a = testing.allocator;
1269 {
1270 var array = ArrayList(i32).init(a);
1271 try array.append(-1);
1272 try array.append(3);
1273 try array.append(5);
1274
1275 const cloned = try array.clone();
1276 defer cloned.deinit();
1277
1278 try testing.expectEqualSlices(i32, array.items, cloned.items);
1279 try testing.expectEqual(array.allocator, cloned.allocator);
1280 try testing.expect(cloned.capacity >= array.capacity);
1281
1282 array.deinit();
1283
1284 try testing.expectEqual(@as(i32, -1), cloned.items[0]);
1285 try testing.expectEqual(@as(i32, 3), cloned.items[1]);
1286 try testing.expectEqual(@as(i32, 5), cloned.items[2]);
1949 for (list.items, 0..) |v, i| {
1950 try testing.expect(v == @as(i32, @intCast(i + 1)));
12871951 }
1288 {
1289 var array = ArrayListUnmanaged(i32){};
1290 try array.append(a, -1);
1291 try array.append(a, 3);
1292 try array.append(a, 5);
1293
1294 var cloned = try array.clone(a);
1295 defer cloned.deinit(a);
1296
1297 try testing.expectEqualSlices(i32, array.items, cloned.items);
1298 try testing.expect(cloned.capacity >= array.capacity);
12991952
1300 array.deinit(a);
1301
1302 try testing.expectEqual(@as(i32, -1), cloned.items[0]);
1303 try testing.expectEqual(@as(i32, 3), cloned.items[1]);
1304 try testing.expectEqual(@as(i32, 5), cloned.items[2]);
1305 }
1953 try testing.expect(list.pop() == 10);
1954 try testing.expect(list.items.len == 9);
1955
1956 try list.appendSlice(&[_]i32{ 1, 2, 3 });
1957 try testing.expect(list.items.len == 12);
1958 try testing.expect(list.pop() == 3);
1959 try testing.expect(list.pop() == 2);
1960 try testing.expect(list.pop() == 1);
1961 try testing.expect(list.items.len == 9);
1962
1963 var unaligned: [3]i32 align(1) = [_]i32{ 4, 5, 6 };
1964 try list.appendUnalignedSlice(&unaligned);
1965 try testing.expect(list.items.len == 12);
1966 try testing.expect(list.pop() == 6);
1967 try testing.expect(list.pop() == 5);
1968 try testing.expect(list.pop() == 4);
1969 try testing.expect(list.items.len == 9);
1970
1971 try list.appendSlice(&[_]i32{});
1972 try testing.expect(list.items.len == 9);
1973
1974 // can only set on indices < self.items.len
1975 list.items[7] = 33;
1976 list.items[8] = 42;
1977
1978 try testing.expect(list.pop() == 42);
1979 try testing.expect(list.pop() == 33);
13061980}
13071981
1308test "basic" {
1982test ArrayListUnmanaged {
13091983 const a = testing.allocator;
1310 {
1311 var list = ArrayList(i32).init(a);
1312 defer list.deinit();
1313
1314 {
1315 var i: usize = 0;
1316 while (i < 10) : (i += 1) {
1317 list.append(@as(i32, @intCast(i + 1))) catch unreachable;
1318 }
1319 }
1320
1321 {
1322 var i: usize = 0;
1323 while (i < 10) : (i += 1) {
1324 try testing.expect(list.items[i] == @as(i32, @intCast(i + 1)));
1325 }
1326 }
1327
1328 for (list.items, 0..) |v, i| {
1329 try testing.expect(v == @as(i32, @intCast(i + 1)));
1330 }
1331
1332 try testing.expect(list.pop() == 10);
1333 try testing.expect(list.items.len == 9);
13341984
1335 list.appendSlice(&[_]i32{ 1, 2, 3 }) catch unreachable;
1336 try testing.expect(list.items.len == 12);
1337 try testing.expect(list.pop() == 3);
1338 try testing.expect(list.pop() == 2);
1339 try testing.expect(list.pop() == 1);
1340 try testing.expect(list.items.len == 9);
1985 var list: ArrayListUnmanaged(i32) = .{};
1986 defer list.deinit(a);
13411987
1342 var unaligned: [3]i32 align(1) = [_]i32{ 4, 5, 6 };
1343 list.appendUnalignedSlice(&unaligned) catch unreachable;
1344 try testing.expect(list.items.len == 12);
1345 try testing.expect(list.pop() == 6);
1346 try testing.expect(list.pop() == 5);
1347 try testing.expect(list.pop() == 4);
1348 try testing.expect(list.items.len == 9);
1349
1350 list.appendSlice(&[_]i32{}) catch unreachable;
1351 try testing.expect(list.items.len == 9);
1352
1353 // can only set on indices < self.items.len
1354 list.items[7] = 33;
1355 list.items[8] = 42;
1356
1357 try testing.expect(list.pop() == 42);
1358 try testing.expect(list.pop() == 33);
1359 }
13601988 {
1361 var list = ArrayListUnmanaged(i32){};
1362 defer list.deinit(a);
1363
1364 {
1365 var i: usize = 0;
1366 while (i < 10) : (i += 1) {
1367 list.append(a, @as(i32, @intCast(i + 1))) catch unreachable;
1368 }
1989 var i: usize = 0;
1990 while (i < 10) : (i += 1) {
1991 try list.append(a, @as(i32, @intCast(i + 1)));
13691992 }
1370
1371 {
1372 var i: usize = 0;
1373 while (i < 10) : (i += 1) {
1374 try testing.expect(list.items[i] == @as(i32, @intCast(i + 1)));
1375 }
1376 }
1377
1378 for (list.items, 0..) |v, i| {
1379 try testing.expect(v == @as(i32, @intCast(i + 1)));
1380 }
1381
1382 try testing.expect(list.pop() == 10);
1383 try testing.expect(list.items.len == 9);
1384
1385 list.appendSlice(a, &[_]i32{ 1, 2, 3 }) catch unreachable;
1386 try testing.expect(list.items.len == 12);
1387 try testing.expect(list.pop() == 3);
1388 try testing.expect(list.pop() == 2);
1389 try testing.expect(list.pop() == 1);
1390 try testing.expect(list.items.len == 9);
1391
1392 var unaligned: [3]i32 align(1) = [_]i32{ 4, 5, 6 };
1393 list.appendUnalignedSlice(a, &unaligned) catch unreachable;
1394 try testing.expect(list.items.len == 12);
1395 try testing.expect(list.pop() == 6);
1396 try testing.expect(list.pop() == 5);
1397 try testing.expect(list.pop() == 4);
1398 try testing.expect(list.items.len == 9);
1399
1400 list.appendSlice(a, &[_]i32{}) catch unreachable;
1401 try testing.expect(list.items.len == 9);
1402
1403 // can only set on indices < self.items.len
1404 list.items[7] = 33;
1405 list.items[8] = 42;
1406
1407 try testing.expect(list.pop() == 42);
1408 try testing.expect(list.pop() == 33);
14091993 }
1410}
14111994
1412test "appendNTimes" {
1413 const a = testing.allocator;
14141995 {
1415 var list = ArrayList(i32).init(a);
1416 defer list.deinit();
1417
1418 try list.appendNTimes(2, 10);
1419 try testing.expectEqual(@as(usize, 10), list.items.len);
1420 for (list.items) |element| {
1421 try testing.expectEqual(@as(i32, 2), element);
1996 var i: usize = 0;
1997 while (i < 10) : (i += 1) {
1998 try testing.expect(list.items[i] == @as(i32, @intCast(i + 1)));
14221999 }
14232000 }
1424 {
1425 var list = ArrayListUnmanaged(i32){};
1426 defer list.deinit(a);
14272001
1428 try list.appendNTimes(a, 2, 10);
1429 try testing.expectEqual(@as(usize, 10), list.items.len);
1430 for (list.items) |element| {
1431 try testing.expectEqual(@as(i32, 2), element);
1432 }
2002 for (list.items, 0..) |v, i| {
2003 try testing.expect(v == @as(i32, @intCast(i + 1)));
14332004 }
2005
2006 try testing.expect(list.pop() == 10);
2007 try testing.expect(list.items.len == 9);
2008
2009 try list.appendSlice(a, &[_]i32{ 1, 2, 3 });
2010 try testing.expect(list.items.len == 12);
2011 try testing.expect(list.pop() == 3);
2012 try testing.expect(list.pop() == 2);
2013 try testing.expect(list.pop() == 1);
2014 try testing.expect(list.items.len == 9);
2015
2016 var unaligned: [3]i32 align(1) = [_]i32{ 4, 5, 6 };
2017 try list.appendUnalignedSlice(a, &unaligned);
2018 try testing.expect(list.items.len == 12);
2019 try testing.expect(list.pop() == 6);
2020 try testing.expect(list.pop() == 5);
2021 try testing.expect(list.pop() == 4);
2022 try testing.expect(list.items.len == 9);
2023
2024 try list.appendSlice(a, &[_]i32{});
2025 try testing.expect(list.items.len == 9);
2026
2027 // can only set on indices < self.items.len
2028 list.items[7] = 33;
2029 list.items[8] = 42;
2030
2031 try testing.expect(list.pop() == 42);
2032 try testing.expect(list.pop() == 33);
14342033}
14352034
14362035test "appendNTimes with failing allocator" {
......@@ -1447,322 +2046,6 @@ test "appendNTimes with failing allocator" {
14472046 }
14482047}
14492048
1450test "orderedRemove" {
1451 const a = testing.allocator;
1452 {
1453 var list = ArrayList(i32).init(a);
1454 defer list.deinit();
1455
1456 try list.append(1);
1457 try list.append(2);
1458 try list.append(3);
1459 try list.append(4);
1460 try list.append(5);
1461 try list.append(6);
1462 try list.append(7);
1463
1464 //remove from middle
1465 try testing.expectEqual(@as(i32, 4), list.orderedRemove(3));
1466 try testing.expectEqual(@as(i32, 5), list.items[3]);
1467 try testing.expectEqual(@as(usize, 6), list.items.len);
1468
1469 //remove from end
1470 try testing.expectEqual(@as(i32, 7), list.orderedRemove(5));
1471 try testing.expectEqual(@as(usize, 5), list.items.len);
1472
1473 //remove from front
1474 try testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
1475 try testing.expectEqual(@as(i32, 2), list.items[0]);
1476 try testing.expectEqual(@as(usize, 4), list.items.len);
1477 }
1478 {
1479 var list = ArrayListUnmanaged(i32){};
1480 defer list.deinit(a);
1481
1482 try list.append(a, 1);
1483 try list.append(a, 2);
1484 try list.append(a, 3);
1485 try list.append(a, 4);
1486 try list.append(a, 5);
1487 try list.append(a, 6);
1488 try list.append(a, 7);
1489
1490 //remove from middle
1491 try testing.expectEqual(@as(i32, 4), list.orderedRemove(3));
1492 try testing.expectEqual(@as(i32, 5), list.items[3]);
1493 try testing.expectEqual(@as(usize, 6), list.items.len);
1494
1495 //remove from end
1496 try testing.expectEqual(@as(i32, 7), list.orderedRemove(5));
1497 try testing.expectEqual(@as(usize, 5), list.items.len);
1498
1499 //remove from front
1500 try testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
1501 try testing.expectEqual(@as(i32, 2), list.items[0]);
1502 try testing.expectEqual(@as(usize, 4), list.items.len);
1503 }
1504 {
1505 // remove last item
1506 var list = ArrayList(i32).init(a);
1507 defer list.deinit();
1508 try list.append(1);
1509 try testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
1510 try testing.expectEqual(@as(usize, 0), list.items.len);
1511 }
1512 {
1513 // remove last item
1514 var list = ArrayListUnmanaged(i32){};
1515 defer list.deinit(a);
1516 try list.append(a, 1);
1517 try testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
1518 try testing.expectEqual(@as(usize, 0), list.items.len);
1519 }
1520}
1521
1522test "swapRemove" {
1523 const a = testing.allocator;
1524 {
1525 var list = ArrayList(i32).init(a);
1526 defer list.deinit();
1527
1528 try list.append(1);
1529 try list.append(2);
1530 try list.append(3);
1531 try list.append(4);
1532 try list.append(5);
1533 try list.append(6);
1534 try list.append(7);
1535
1536 //remove from middle
1537 try testing.expect(list.swapRemove(3) == 4);
1538 try testing.expect(list.items[3] == 7);
1539 try testing.expect(list.items.len == 6);
1540
1541 //remove from end
1542 try testing.expect(list.swapRemove(5) == 6);
1543 try testing.expect(list.items.len == 5);
1544
1545 //remove from front
1546 try testing.expect(list.swapRemove(0) == 1);
1547 try testing.expect(list.items[0] == 5);
1548 try testing.expect(list.items.len == 4);
1549 }
1550 {
1551 var list = ArrayListUnmanaged(i32){};
1552 defer list.deinit(a);
1553
1554 try list.append(a, 1);
1555 try list.append(a, 2);
1556 try list.append(a, 3);
1557 try list.append(a, 4);
1558 try list.append(a, 5);
1559 try list.append(a, 6);
1560 try list.append(a, 7);
1561
1562 //remove from middle
1563 try testing.expect(list.swapRemove(3) == 4);
1564 try testing.expect(list.items[3] == 7);
1565 try testing.expect(list.items.len == 6);
1566
1567 //remove from end
1568 try testing.expect(list.swapRemove(5) == 6);
1569 try testing.expect(list.items.len == 5);
1570
1571 //remove from front
1572 try testing.expect(list.swapRemove(0) == 1);
1573 try testing.expect(list.items[0] == 5);
1574 try testing.expect(list.items.len == 4);
1575 }
1576}
1577
1578test "insert" {
1579 const a = testing.allocator;
1580 {
1581 var list = ArrayList(i32).init(a);
1582 defer list.deinit();
1583
1584 try list.insert(0, 1);
1585 try list.append(2);
1586 try list.insert(2, 3);
1587 try list.insert(0, 5);
1588 try testing.expect(list.items[0] == 5);
1589 try testing.expect(list.items[1] == 1);
1590 try testing.expect(list.items[2] == 2);
1591 try testing.expect(list.items[3] == 3);
1592 }
1593 {
1594 var list = ArrayListUnmanaged(i32){};
1595 defer list.deinit(a);
1596
1597 try list.insert(a, 0, 1);
1598 try list.append(a, 2);
1599 try list.insert(a, 2, 3);
1600 try list.insert(a, 0, 5);
1601 try testing.expect(list.items[0] == 5);
1602 try testing.expect(list.items[1] == 1);
1603 try testing.expect(list.items[2] == 2);
1604 try testing.expect(list.items[3] == 3);
1605 }
1606}
1607
1608test "insertSlice" {
1609 const a = testing.allocator;
1610 {
1611 var list = ArrayList(i32).init(a);
1612 defer list.deinit();
1613
1614 try list.append(1);
1615 try list.append(2);
1616 try list.append(3);
1617 try list.append(4);
1618 try list.insertSlice(1, &[_]i32{ 9, 8 });
1619 try testing.expect(list.items[0] == 1);
1620 try testing.expect(list.items[1] == 9);
1621 try testing.expect(list.items[2] == 8);
1622 try testing.expect(list.items[3] == 2);
1623 try testing.expect(list.items[4] == 3);
1624 try testing.expect(list.items[5] == 4);
1625
1626 const items = [_]i32{1};
1627 try list.insertSlice(0, items[0..0]);
1628 try testing.expect(list.items.len == 6);
1629 try testing.expect(list.items[0] == 1);
1630 }
1631 {
1632 var list = ArrayListUnmanaged(i32){};
1633 defer list.deinit(a);
1634
1635 try list.append(a, 1);
1636 try list.append(a, 2);
1637 try list.append(a, 3);
1638 try list.append(a, 4);
1639 try list.insertSlice(a, 1, &[_]i32{ 9, 8 });
1640 try testing.expect(list.items[0] == 1);
1641 try testing.expect(list.items[1] == 9);
1642 try testing.expect(list.items[2] == 8);
1643 try testing.expect(list.items[3] == 2);
1644 try testing.expect(list.items[4] == 3);
1645 try testing.expect(list.items[5] == 4);
1646
1647 const items = [_]i32{1};
1648 try list.insertSlice(a, 0, items[0..0]);
1649 try testing.expect(list.items.len == 6);
1650 try testing.expect(list.items[0] == 1);
1651 }
1652}
1653
1654test "replaceRange" {
1655 var arena = std.heap.ArenaAllocator.init(testing.allocator);
1656 defer arena.deinit();
1657 const a = arena.allocator();
1658
1659 const init = [_]i32{ 1, 2, 3, 4, 5 };
1660 const new = [_]i32{ 0, 0, 0 };
1661
1662 const result_zero = [_]i32{ 1, 0, 0, 0, 2, 3, 4, 5 };
1663 const result_eq = [_]i32{ 1, 0, 0, 0, 5 };
1664 const result_le = [_]i32{ 1, 0, 0, 0, 4, 5 };
1665 const result_gt = [_]i32{ 1, 0, 0, 0 };
1666
1667 {
1668 var list_zero = ArrayList(i32).init(a);
1669 var list_eq = ArrayList(i32).init(a);
1670 var list_lt = ArrayList(i32).init(a);
1671 var list_gt = ArrayList(i32).init(a);
1672
1673 try list_zero.appendSlice(&init);
1674 try list_eq.appendSlice(&init);
1675 try list_lt.appendSlice(&init);
1676 try list_gt.appendSlice(&init);
1677
1678 try list_zero.replaceRange(1, 0, &new);
1679 try list_eq.replaceRange(1, 3, &new);
1680 try list_lt.replaceRange(1, 2, &new);
1681
1682 // after_range > new_items.len in function body
1683 try testing.expect(1 + 4 > new.len);
1684 try list_gt.replaceRange(1, 4, &new);
1685
1686 try testing.expectEqualSlices(i32, list_zero.items, &result_zero);
1687 try testing.expectEqualSlices(i32, list_eq.items, &result_eq);
1688 try testing.expectEqualSlices(i32, list_lt.items, &result_le);
1689 try testing.expectEqualSlices(i32, list_gt.items, &result_gt);
1690 }
1691 {
1692 var list_zero = ArrayListUnmanaged(i32){};
1693 var list_eq = ArrayListUnmanaged(i32){};
1694 var list_lt = ArrayListUnmanaged(i32){};
1695 var list_gt = ArrayListUnmanaged(i32){};
1696
1697 try list_zero.appendSlice(a, &init);
1698 try list_eq.appendSlice(a, &init);
1699 try list_lt.appendSlice(a, &init);
1700 try list_gt.appendSlice(a, &init);
1701
1702 try list_zero.replaceRange(a, 1, 0, &new);
1703 try list_eq.replaceRange(a, 1, 3, &new);
1704 try list_lt.replaceRange(a, 1, 2, &new);
1705
1706 // after_range > new_items.len in function body
1707 try testing.expect(1 + 4 > new.len);
1708 try list_gt.replaceRange(a, 1, 4, &new);
1709
1710 try testing.expectEqualSlices(i32, list_zero.items, &result_zero);
1711 try testing.expectEqualSlices(i32, list_eq.items, &result_eq);
1712 try testing.expectEqualSlices(i32, list_lt.items, &result_le);
1713 try testing.expectEqualSlices(i32, list_gt.items, &result_gt);
1714 }
1715
1716 {
1717 var list_zero = ArrayList(i32).init(a);
1718 var list_eq = ArrayList(i32).init(a);
1719 var list_lt = ArrayList(i32).init(a);
1720 var list_gt = ArrayList(i32).init(a);
1721
1722 try list_zero.appendSlice(&init);
1723 try list_eq.appendSlice(&init);
1724 try list_lt.appendSlice(&init);
1725 try list_gt.appendSlice(&init);
1726
1727 list_zero.replaceRangeAssumeCapacity(1, 0, &new);
1728 list_eq.replaceRangeAssumeCapacity(1, 3, &new);
1729 list_lt.replaceRangeAssumeCapacity(1, 2, &new);
1730
1731 // after_range > new_items.len in function body
1732 try testing.expect(1 + 4 > new.len);
1733 list_gt.replaceRangeAssumeCapacity(1, 4, &new);
1734
1735 try testing.expectEqualSlices(i32, list_zero.items, &result_zero);
1736 try testing.expectEqualSlices(i32, list_eq.items, &result_eq);
1737 try testing.expectEqualSlices(i32, list_lt.items, &result_le);
1738 try testing.expectEqualSlices(i32, list_gt.items, &result_gt);
1739 }
1740 {
1741 var list_zero = ArrayListUnmanaged(i32){};
1742 var list_eq = ArrayListUnmanaged(i32){};
1743 var list_lt = ArrayListUnmanaged(i32){};
1744 var list_gt = ArrayListUnmanaged(i32){};
1745
1746 try list_zero.appendSlice(a, &init);
1747 try list_eq.appendSlice(a, &init);
1748 try list_lt.appendSlice(a, &init);
1749 try list_gt.appendSlice(a, &init);
1750
1751 list_zero.replaceRangeAssumeCapacity(1, 0, &new);
1752 list_eq.replaceRangeAssumeCapacity(1, 3, &new);
1753 list_lt.replaceRangeAssumeCapacity(1, 2, &new);
1754
1755 // after_range > new_items.len in function body
1756 try testing.expect(1 + 4 > new.len);
1757 list_gt.replaceRangeAssumeCapacity(1, 4, &new);
1758
1759 try testing.expectEqualSlices(i32, list_zero.items, &result_zero);
1760 try testing.expectEqualSlices(i32, list_eq.items, &result_eq);
1761 try testing.expectEqualSlices(i32, list_lt.items, &result_le);
1762 try testing.expectEqualSlices(i32, list_gt.items, &result_gt);
1763 }
1764}
1765
17662049const Item = struct {
17672050 integer: i32,
17682051 sub_items: ArrayList(Item),
......@@ -1774,7 +2057,7 @@ const ItemUnmanaged = struct {
17742057};
17752058
17762059test "ArrayList(T) of struct T" {
1777 const a = std.testing.allocator;
2060 const a = testing.allocator;
17782061 {
17792062 var root = Item{ .integer = 1, .sub_items = ArrayList(Item).init(a) };
17802063 defer root.sub_items.deinit();
......@@ -1789,76 +2072,27 @@ test "ArrayList(T) of struct T" {
17892072 }
17902073}
17912074
1792test "ArrayList(u8) implements writer" {
1793 const a = testing.allocator;
1794
1795 {
1796 var buffer = ArrayList(u8).init(a);
1797 defer buffer.deinit();
1798
1799 const x: i32 = 42;
1800 const y: i32 = 1234;
1801 try buffer.writer().print("x: {}\ny: {}\n", .{ x, y });
1802
1803 try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.items);
1804 }
1805 {
1806 var list = ArrayListAligned(u8, 2).init(a);
1807 defer list.deinit();
1808
1809 const writer = list.writer();
1810 try writer.writeAll("a");
1811 try writer.writeAll("bc");
1812 try writer.writeAll("d");
1813 try writer.writeAll("efg");
1814
1815 try testing.expectEqualSlices(u8, list.items, "abcdefg");
1816 }
1817}
1818
1819test "ArrayListUnmanaged(u8) implements writer" {
1820 const a = testing.allocator;
1821
1822 {
1823 var buffer: ArrayListUnmanaged(u8) = .{};
1824 defer buffer.deinit(a);
1825
1826 const x: i32 = 42;
1827 const y: i32 = 1234;
1828 try buffer.writer(a).print("x: {}\ny: {}\n", .{ x, y });
1829
1830 try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.items);
1831 }
2075test "shrink still sets length when both resizing and new allocation fails" {
18322076 {
1833 var list: ArrayListAlignedUnmanaged(u8, 2) = .{};
1834 defer list.deinit(a);
1835
1836 const writer = list.writer(a);
1837 try writer.writeAll("a");
1838 try writer.writeAll("bc");
1839 try writer.writeAll("d");
1840 try writer.writeAll("efg");
1841
1842 try testing.expectEqualSlices(u8, list.items, "abcdefg");
1843 }
1844}
1845
1846test "shrink still sets length when resizing is disabled" {
1847 var failing_allocator = testing.FailingAllocator.init(testing.allocator, .{ .resize_fail_index = 0 });
1848 const a = failing_allocator.allocator();
2077 var failing_allocator = testing.FailingAllocator.init(testing.allocator, .{});
18492078
1850 {
1851 var list = ArrayList(i32).init(a);
2079 var list = ArrayList(i32).init(failing_allocator.allocator());
18522080 defer list.deinit();
18532081
18542082 try list.append(1);
18552083 try list.append(2);
18562084 try list.append(3);
18572085
2086 failing_allocator.resize_fail_index = failing_allocator.resize_index;
2087 failing_allocator.fail_index = failing_allocator.alloc_index;
18582088 list.shrinkAndFree(1);
18592089 try testing.expect(list.items.len == 1);
2090 try testing.expect(list.capacity >= 3);
18602091 }
18612092 {
2093 var failing_allocator = testing.FailingAllocator.init(testing.allocator, .{});
2094 const a = failing_allocator.allocator();
2095
18622096 var list = ArrayListUnmanaged(i32){};
18632097 defer list.deinit(a);
18642098
......@@ -1866,8 +2100,11 @@ test "shrink still sets length when resizing is disabled" {
18662100 try list.append(a, 2);
18672101 try list.append(a, 3);
18682102
2103 failing_allocator.resize_fail_index = failing_allocator.resize_index;
2104 failing_allocator.fail_index = failing_allocator.alloc_index;
18692105 list.shrinkAndFree(a, 1);
18702106 try testing.expect(list.items.len == 1);
2107 try testing.expect(list.capacity >= 3);
18712108 }
18722109}
18732110
......@@ -1883,34 +2120,10 @@ test "shrinkAndFree with a copy" {
18832120 try testing.expect(mem.eql(i32, list.items, &.{ 3, 3, 3, 3 }));
18842121}
18852122
1886test "addManyAsArray" {
1887 const a = std.testing.allocator;
1888 {
1889 var list = ArrayList(u8).init(a);
1890 defer list.deinit();
1891
1892 (try list.addManyAsArray(4)).* = "aoeu".*;
1893 try list.ensureTotalCapacity(8);
1894 list.addManyAsArrayAssumeCapacity(4).* = "asdf".*;
1895
1896 try testing.expectEqualSlices(u8, list.items, "aoeuasdf");
1897 }
1898 {
1899 var list = ArrayListUnmanaged(u8){};
1900 defer list.deinit(a);
1901
1902 (try list.addManyAsArray(a, 4)).* = "aoeu".*;
1903 try list.ensureTotalCapacity(a, 8);
1904 list.addManyAsArrayAssumeCapacity(4).* = "asdf".*;
1905
1906 try testing.expectEqualSlices(u8, list.items, "aoeuasdf");
1907 }
1908}
1909
19102123test "growing memory preserves contents" {
19112124 // Shrink the list after every insertion to ensure that a memory growth
19122125 // will be triggered in the next operation.
1913 const a = std.testing.allocator;
2126 const a = testing.allocator;
19142127 {
19152128 var list = ArrayList(u8).init(a);
19162129 defer list.deinit();
......@@ -1941,78 +2154,6 @@ test "growing memory preserves contents" {
19412154 }
19422155}
19432156
1944test "fromOwnedSlice" {
1945 const a = testing.allocator;
1946 {
1947 var orig_list = ArrayList(u8).init(a);
1948 defer orig_list.deinit();
1949 try orig_list.appendSlice("foobar");
1950
1951 const slice = try orig_list.toOwnedSlice();
1952 var list = ArrayList(u8).fromOwnedSlice(a, slice);
1953 defer list.deinit();
1954 try testing.expectEqualStrings(list.items, "foobar");
1955 }
1956 {
1957 var list = ArrayList(u8).init(a);
1958 defer list.deinit();
1959 try list.appendSlice("foobar");
1960
1961 const slice = try list.toOwnedSlice();
1962 var unmanaged = ArrayListUnmanaged(u8).fromOwnedSlice(slice);
1963 defer unmanaged.deinit(a);
1964 try testing.expectEqualStrings(unmanaged.items, "foobar");
1965 }
1966}
1967
1968test "fromOwnedSliceSentinel" {
1969 const a = testing.allocator;
1970 {
1971 var orig_list = ArrayList(u8).init(a);
1972 defer orig_list.deinit();
1973 try orig_list.appendSlice("foobar");
1974
1975 const sentinel_slice = try orig_list.toOwnedSliceSentinel(0);
1976 var list = ArrayList(u8).fromOwnedSliceSentinel(a, 0, sentinel_slice);
1977 defer list.deinit();
1978 try testing.expectEqualStrings(list.items, "foobar");
1979 }
1980 {
1981 var list = ArrayList(u8).init(a);
1982 defer list.deinit();
1983 try list.appendSlice("foobar");
1984
1985 const sentinel_slice = try list.toOwnedSliceSentinel(0);
1986 var unmanaged = ArrayListUnmanaged(u8).fromOwnedSliceSentinel(0, sentinel_slice);
1987 defer unmanaged.deinit(a);
1988 try testing.expectEqualStrings(unmanaged.items, "foobar");
1989 }
1990}
1991
1992test "toOwnedSliceSentinel" {
1993 const a = testing.allocator;
1994 {
1995 var list = ArrayList(u8).init(a);
1996 defer list.deinit();
1997
1998 try list.appendSlice("foobar");
1999
2000 const result = try list.toOwnedSliceSentinel(0);
2001 defer a.free(result);
2002 try testing.expectEqualStrings(result, mem.sliceTo(result.ptr, 0));
2003 }
2004 {
2005 var list = ArrayListUnmanaged(u8){};
2006 defer list.deinit(a);
2007
2008 try list.appendSlice(a, "foobar");
2009
2010 const result = try list.toOwnedSliceSentinel(a, 0);
2011 defer a.free(result);
2012 try testing.expectEqualStrings(result, mem.sliceTo(result.ptr, 0));
2013 }
2014}
2015
20162157test "accepts unaligned slices" {
20172158 const a = testing.allocator;
20182159 {
......@@ -2037,8 +2178,7 @@ test "accepts unaligned slices" {
20372178 }
20382179}
20392180
2040test "ArrayList(u0)" {
2041 // An ArrayList on zero-sized types should not need to allocate
2181test "zero-sized types" {
20422182 const a = testing.failing_allocator;
20432183
20442184 var list = ArrayList(u0).init(a);
......@@ -2057,47 +2197,6 @@ test "ArrayList(u0)" {
20572197 try testing.expectEqual(count, 3);
20582198}
20592199
2060test "ArrayList(?u32).popOrNull()" {
2061 const a = testing.allocator;
2062
2063 var list = ArrayList(?u32).init(a);
2064 defer list.deinit();
2065
2066 try list.append(null);
2067 try list.append(1);
2068 try list.append(2);
2069 try testing.expectEqual(list.items.len, 3);
2070
2071 try testing.expect(list.popOrNull().? == @as(u32, 2));
2072 try testing.expect(list.popOrNull().? == @as(u32, 1));
2073 try testing.expect(list.popOrNull().? == null);
2074 try testing.expect(list.popOrNull() == null);
2075}
2076
2077test "ArrayList(u32).getLast()" {
2078 const a = testing.allocator;
2079
2080 var list = ArrayList(u32).init(a);
2081 defer list.deinit();
2082
2083 try list.append(2);
2084 const const_list = list;
2085 try testing.expectEqual(const_list.getLast(), 2);
2086}
2087
2088test "ArrayList(u32).getLastOrNull()" {
2089 const a = testing.allocator;
2090
2091 var list = ArrayList(u32).init(a);
2092 defer list.deinit();
2093
2094 try testing.expectEqual(list.getLastOrNull(), null);
2095
2096 try list.append(2);
2097 const const_list = list;
2098 try testing.expectEqual(const_list.getLastOrNull().?, 2);
2099}
2100
21012200test "return OutOfMemory when capacity would exceed maximum usize integer value" {
21022201 const a = testing.allocator;
21032202 const new_item: u32 = 42;