authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-03 22:31:15-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-04-03 22:31:15-04:00
loge89c42655cf9851cdf02065bc75cda0e27884966
treeb25e26e53ceda1ac03e65de5d483491ee46e7c0e
parent1568470c44eafb59425c070ea9884b78cc2516b2
parent7a28c644aa8eb3d27dee113338af8278f8f6334f
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4868 from xackus/new-arraylist-api

new ArrayList API

21 files changed, 185 insertions(+), 161 deletions(-)

lib/std/array_list.zig+114-89
...@@ -20,11 +20,9 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -20,11 +20,9 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
20 return struct {20 return struct {
21 const Self = @This();21 const Self = @This();
2222
23 /// Use `span` instead of slicing this directly, because if you don't23 /// Content of the ArrayList
24 /// specify the end position of the slice, this will potentially give
25 /// you uninitialized memory.
26 items: Slice,24 items: Slice,
27 len: usize,25 capacity: usize,
28 allocator: *Allocator,26 allocator: *Allocator,
2927
30 pub const Slice = if (alignment) |a| ([]align(a) T) else []T;28 pub const Slice = if (alignment) |a| ([]align(a) T) else []T;
...@@ -34,7 +32,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -34,7 +32,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
34 pub fn init(allocator: *Allocator) Self {32 pub fn init(allocator: *Allocator) Self {
35 return Self{33 return Self{
36 .items = &[_]T{},34 .items = &[_]T{},
37 .len = 0,35 .capacity = 0,
38 .allocator = allocator,36 .allocator = allocator,
39 };37 };
40 }38 }
...@@ -49,60 +47,55 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -49,60 +47,55 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
4947
50 /// Release all allocated memory.48 /// Release all allocated memory.
51 pub fn deinit(self: Self) void {49 pub fn deinit(self: Self) void {
52 self.allocator.free(self.items);50 self.allocator.free(self.allocatedSlice());
53 }51 }
5452
53 /// Deprecated: use `items` field directly.
55 /// Return contents as a slice. Only valid while the list54 /// Return contents as a slice. Only valid while the list
56 /// doesn't change size.55 /// doesn't change size.
57 pub fn span(self: var) @TypeOf(self.items[0..self.len]) {56 pub fn span(self: var) @TypeOf(self.items) {
58 return self.items[0..self.len];57 return self.items;
59 }58 }
6059
61 /// Deprecated: use `span`.60 /// Deprecated: use `items` field directly.
62 pub fn toSlice(self: Self) Slice {61 pub fn toSlice(self: Self) Slice {
63 return self.span();62 return self.items;
64 }63 }
6564
66 /// Deprecated: use `span`.65 /// Deprecated: use `items` field directly.
67 pub fn toSliceConst(self: Self) SliceConst {66 pub fn toSliceConst(self: Self) SliceConst {
68 return self.span();67 return self.items;
69 }68 }
7069
71 /// Deprecated: use `span()[i]`.70 /// Deprecated: use `list.items[i]`.
72 pub fn at(self: Self, i: usize) T {71 pub fn at(self: Self, i: usize) T {
73 return self.span()[i];72 return self.items[i];
74 }73 }
7574
76 /// Deprecated: use `&span()[i]`.75 /// Deprecated: use `&list.items[i]`.
77 pub fn ptrAt(self: Self, i: usize) *T {76 pub fn ptrAt(self: Self, i: usize) *T {
78 return &self.span()[i];77 return &self.items[i];
79 }78 }
8079
81 /// Deprecated: use `if (i >= list.len) return error.OutOfBounds else span()[i] = item`.80 /// Deprecated: use `if (i >= list.items.len) return error.OutOfBounds else list.items[i] = item`.
82 pub fn setOrError(self: Self, i: usize, item: T) !void {81 pub fn setOrError(self: Self, i: usize, item: T) !void {
83 if (i >= self.len) return error.OutOfBounds;82 if (i >= self.items.len) return error.OutOfBounds;
84 self.items[i] = item;83 self.items[i] = item;
85 }84 }
8685
87 /// Deprecated: use `list.span()[i] = item`.86 /// Deprecated: use `list.items[i] = item`.
88 pub fn set(self: *Self, i: usize, item: T) void {87 pub fn set(self: *Self, i: usize, item: T) void {
89 assert(i < self.len);88 assert(i < self.items.len);
90 self.items[i] = item;89 self.items[i] = item;
91 }90 }
9291
93 /// Return the maximum number of items the list can hold
94 /// without allocating more memory.
95 pub fn capacity(self: Self) usize {
96 return self.items.len;
97 }
98
99 /// ArrayList takes ownership of the passed in slice. The slice must have been92 /// ArrayList takes ownership of the passed in slice. The slice must have been
100 /// allocated with `allocator`.93 /// allocated with `allocator`.
101 /// Deinitialize with `deinit` or use `toOwnedSlice`.94 /// Deinitialize with `deinit` or use `toOwnedSlice`.
102 pub fn fromOwnedSlice(allocator: *Allocator, slice: Slice) Self {95 pub fn fromOwnedSlice(allocator: *Allocator, slice: Slice) Self {
103 return Self{96 return Self{
104 .items = slice,97 .items = slice,
105 .len = slice.len,98 .capacity = slice.len,
106 .allocator = allocator,99 .allocator = allocator,
107 };100 };
108 }101 }
...@@ -110,7 +103,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -110,7 +103,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
110 /// The caller owns the returned memory. ArrayList becomes empty.103 /// The caller owns the returned memory. ArrayList becomes empty.
111 pub fn toOwnedSlice(self: *Self) Slice {104 pub fn toOwnedSlice(self: *Self) Slice {
112 const allocator = self.allocator;105 const allocator = self.allocator;
113 const result = allocator.shrink(self.items, self.len);106 const result = allocator.shrink(self.allocatedSlice(), self.items.len);
114 self.* = init(allocator);107 self.* = init(allocator);
115 return result;108 return result;
116 }109 }
...@@ -118,10 +111,10 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -118,10 +111,10 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
118 /// Insert `item` at index `n`. Moves `list[n .. list.len]`111 /// Insert `item` at index `n`. Moves `list[n .. list.len]`
119 /// to make room.112 /// to make room.
120 pub fn insert(self: *Self, n: usize, item: T) !void {113 pub fn insert(self: *Self, n: usize, item: T) !void {
121 try self.ensureCapacity(self.len + 1);114 try self.ensureCapacity(self.items.len + 1);
122 self.len += 1;115 self.items.len += 1;
123116
124 mem.copyBackwards(T, self.items[n + 1 .. self.len], self.items[n .. self.len - 1]);117 mem.copyBackwards(T, self.items[n + 1 .. self.items.len], self.items[n .. self.items.len - 1]);
125 self.items[n] = item;118 self.items[n] = item;
126 }119 }
127120
...@@ -129,10 +122,10 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -129,10 +122,10 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
129 /// `list[i .. list.len]` to make room.122 /// `list[i .. list.len]` to make room.
130 /// This operation is O(N).123 /// This operation is O(N).
131 pub fn insertSlice(self: *Self, i: usize, items: SliceConst) !void {124 pub fn insertSlice(self: *Self, i: usize, items: SliceConst) !void {
132 try self.ensureCapacity(self.len + items.len);125 try self.ensureCapacity(self.items.len + items.len);
133 self.len += items.len;126 self.items.len += items.len;
134127
135 mem.copyBackwards(T, self.items[i + items.len .. self.len], self.items[i .. self.len - items.len]);128 mem.copyBackwards(T, self.items[i + items.len .. self.items.len], self.items[i .. self.items.len - items.len]);
136 mem.copy(T, self.items[i .. i + items.len], items);129 mem.copy(T, self.items[i .. i + items.len], items);
137 }130 }
138131
...@@ -153,13 +146,13 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -153,13 +146,13 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
153 /// Asserts the array has at least one item.146 /// Asserts the array has at least one item.
154 /// This operation is O(N).147 /// This operation is O(N).
155 pub fn orderedRemove(self: *Self, i: usize) T {148 pub fn orderedRemove(self: *Self, i: usize) T {
156 const newlen = self.len - 1;149 const newlen = self.items.len - 1;
157 if (newlen == i) return self.pop();150 if (newlen == i) return self.pop();
158151
159 const old_item = self.at(i);152 const old_item = self.items[i];
160 for (self.items[i..newlen]) |*b, j| b.* = self.items[i + 1 + j];153 for (self.items[i..newlen]) |*b, j| b.* = self.items[i + 1 + j];
161 self.items[newlen] = undefined;154 self.items[newlen] = undefined;
162 self.len = newlen;155 self.items.len = newlen;
163 return old_item;156 return old_item;
164 }157 }
165158
...@@ -167,26 +160,28 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -167,26 +160,28 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
167 /// The empty slot is filled from the end of the list.160 /// The empty slot is filled from the end of the list.
168 /// This operation is O(1).161 /// This operation is O(1).
169 pub fn swapRemove(self: *Self, i: usize) T {162 pub fn swapRemove(self: *Self, i: usize) T {
170 if (self.len - 1 == i) return self.pop();163 if (self.items.len - 1 == i) return self.pop();
171164
172 const slice = self.span();165 const old_item = self.items[i];
173 const old_item = slice[i];166 self.items[i] = self.pop();
174 slice[i] = self.pop();
175 return old_item;167 return old_item;
176 }168 }
177169
178 /// Deprecated: use `if (i >= list.len) return error.OutOfBounds else list.swapRemove(i)`.170 /// Deprecated: use `if (i >= list.items.len) return error.OutOfBounds else list.swapRemove(i)`.
179 pub fn swapRemoveOrError(self: *Self, i: usize) !T {171 pub fn swapRemoveOrError(self: *Self, i: usize) !T {
180 if (i >= self.len) return error.OutOfBounds;172 if (i >= self.items.len) return error.OutOfBounds;
181 return self.swapRemove(i);173 return self.swapRemove(i);
182 }174 }
183175
184 /// Append the slice of items to the list. Allocates more176 /// Append the slice of items to the list. Allocates more
185 /// memory as necessary.177 /// memory as necessary.
186 pub fn appendSlice(self: *Self, items: SliceConst) !void {178 pub fn appendSlice(self: *Self, items: SliceConst) !void {
187 try self.ensureCapacity(self.len + items.len);179 const oldlen = self.items.len;
188 mem.copy(T, self.items[self.len..], items);180 const newlen = self.items.len + items.len;
189 self.len += items.len;181
182 try self.ensureCapacity(newlen);
183 self.items.len = newlen;
184 mem.copy(T, self.items[oldlen..], items);
190 }185 }
191186
192 /// Same as `append` except it returns the number of bytes written, which is always the same187 /// Same as `append` except it returns the number of bytes written, which is always the same
...@@ -206,50 +201,58 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -206,50 +201,58 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
206 /// Append a value to the list `n` times.201 /// Append a value to the list `n` times.
207 /// Allocates more memory as necessary.202 /// Allocates more memory as necessary.
208 pub fn appendNTimes(self: *Self, value: T, n: usize) !void {203 pub fn appendNTimes(self: *Self, value: T, n: usize) !void {
209 const old_len = self.len;204 const old_len = self.items.len;
210 try self.resize(self.len + n);205 try self.resize(self.items.len + n);
211 mem.set(T, self.items[old_len..self.len], value);206 mem.set(T, self.items[old_len..self.items.len], value);
212 }207 }
213208
214 /// Adjust the list's length to `new_len`.209 /// Adjust the list's length to `new_len`.
215 /// Does not initialize added items if any.210 /// Does not initialize added items if any.
216 pub fn resize(self: *Self, new_len: usize) !void {211 pub fn resize(self: *Self, new_len: usize) !void {
217 try self.ensureCapacity(new_len);212 try self.ensureCapacity(new_len);
218 self.len = new_len;213 self.items.len = new_len;
219 }214 }
220215
221 /// Reduce allocated capacity to `new_len`.216 /// Reduce allocated capacity to `new_len`.
222 /// Invalidates element pointers.217 /// Invalidates element pointers.
223 pub fn shrink(self: *Self, new_len: usize) void {218 pub fn shrink(self: *Self, new_len: usize) void {
224 assert(new_len <= self.len);219 assert(new_len <= self.items.len);
225 self.len = new_len;220
226 self.items = self.allocator.realloc(self.items, new_len) catch |e| switch (e) {221 self.items = self.allocator.realloc(self.allocatedSlice(), new_len) catch |e| switch (e) {
227 error.OutOfMemory => return, // no problem, capacity is still correct then.222 error.OutOfMemory => { // no problem, capacity is still correct then.
223 self.items.len = new_len;
224 return;
225 },
228 };226 };
227 self.capacity = new_len;
229 }228 }
230229
231 pub fn ensureCapacity(self: *Self, new_capacity: usize) !void {230 pub fn ensureCapacity(self: *Self, new_capacity: usize) !void {
232 var better_capacity = self.capacity();231 var better_capacity = self.capacity;
233 if (better_capacity >= new_capacity) return;232 if (better_capacity >= new_capacity) return;
233
234 while (true) {234 while (true) {
235 better_capacity += better_capacity / 2 + 8;235 better_capacity += better_capacity / 2 + 8;
236 if (better_capacity >= new_capacity) break;236 if (better_capacity >= new_capacity) break;
237 }237 }
238 self.items = try self.allocator.realloc(self.items, better_capacity);238
239 const new_memory = try self.allocator.realloc(self.allocatedSlice(), better_capacity);
240 self.items.ptr = new_memory.ptr;
241 self.capacity = new_memory.len;
239 }242 }
240243
241 /// Increases the array's length to match the full capacity that is already allocated.244 /// Increases the array's length to match the full capacity that is already allocated.
242 /// The new elements have `undefined` values. This operation does not invalidate any245 /// The new elements have `undefined` values. This operation does not invalidate any
243 /// element pointers.246 /// element pointers.
244 pub fn expandToCapacity(self: *Self) void {247 pub fn expandToCapacity(self: *Self) void {
245 self.len = self.items.len;248 self.items.len = self.capacity;
246 }249 }
247250
248 /// Increase length by 1, returning pointer to the new item.251 /// Increase length by 1, returning pointer to the new item.
249 /// The returned pointer becomes invalid when the list is resized.252 /// The returned pointer becomes invalid when the list is resized.
250 pub fn addOne(self: *Self) !*T {253 pub fn addOne(self: *Self) !*T {
251 const new_length = self.len + 1;254 const newlen = self.items.len + 1;
252 try self.ensureCapacity(new_length);255 try self.ensureCapacity(newlen);
253 return self.addOneAssumeCapacity();256 return self.addOneAssumeCapacity();
254 }257 }
255258
...@@ -257,25 +260,32 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -257,25 +260,32 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
257 /// Asserts that there is already space for the new item without allocating more.260 /// Asserts that there is already space for the new item without allocating more.
258 /// The returned pointer becomes invalid when the list is resized.261 /// The returned pointer becomes invalid when the list is resized.
259 pub fn addOneAssumeCapacity(self: *Self) *T {262 pub fn addOneAssumeCapacity(self: *Self) *T {
260 assert(self.len < self.capacity());263 assert(self.items.len < self.capacity);
261 const result = &self.items[self.len];264
262 self.len += 1;265 self.items.len += 1;
263 return result;266 return &self.items[self.items.len - 1];
264 }267 }
265268
266 /// Remove and return the last element from the list.269 /// Remove and return the last element from the list.
267 /// Asserts the list has at least one item.270 /// Asserts the list has at least one item.
268 pub fn pop(self: *Self) T {271 pub fn pop(self: *Self) T {
269 self.len -= 1;272 const val = self.items[self.items.len - 1];
270 return self.items[self.len];273 self.items.len -= 1;
274 return val;
271 }275 }
272276
273 /// Remove and return the last element from the list.277 /// Remove and return the last element from the list.
274 /// If the list is empty, returns `null`.278 /// If the list is empty, returns `null`.
275 pub fn popOrNull(self: *Self) ?T {279 pub fn popOrNull(self: *Self) ?T {
276 if (self.len == 0) return null;280 if (self.items.len == 0) return null;
277 return self.pop();281 return self.pop();
278 }282 }
283
284 // For a nicer API, `items.len` is the length, not the capacity.
285 // This requires "unsafe" slicing.
286 fn allocatedSlice(self: Self) Slice {
287 return self.items.ptr[0..self.capacity];
288 }
279 };289 };
280}290}
281291
...@@ -283,15 +293,15 @@ test "std.ArrayList.init" {...@@ -283,15 +293,15 @@ test "std.ArrayList.init" {
283 var list = ArrayList(i32).init(testing.allocator);293 var list = ArrayList(i32).init(testing.allocator);
284 defer list.deinit();294 defer list.deinit();
285295
286 testing.expect(list.len == 0);296 testing.expect(list.items.len == 0);
287 testing.expect(list.capacity() == 0);297 testing.expect(list.capacity == 0);
288}298}
289299
290test "std.ArrayList.initCapacity" {300test "std.ArrayList.initCapacity" {
291 var list = try ArrayList(i8).initCapacity(testing.allocator, 200);301 var list = try ArrayList(i8).initCapacity(testing.allocator, 200);
292 defer list.deinit();302 defer list.deinit();
293 testing.expect(list.len == 0);303 testing.expect(list.items.len == 0);
294 testing.expect(list.capacity() >= 200);304 testing.expect(list.capacity >= 200);
295}305}
296306
297test "std.ArrayList.basic" {307test "std.ArrayList.basic" {
...@@ -315,7 +325,7 @@ test "std.ArrayList.basic" {...@@ -315,7 +325,7 @@ test "std.ArrayList.basic" {
315 }325 }
316 }326 }
317327
318 for (list.span()) |v, i| {328 for (list.items) |v, i| {
319 testing.expect(v == @intCast(i32, i + 1));329 testing.expect(v == @intCast(i32, i + 1));
320 }330 }
321331
...@@ -324,19 +334,19 @@ test "std.ArrayList.basic" {...@@ -324,19 +334,19 @@ test "std.ArrayList.basic" {
324 }334 }
325335
326 testing.expect(list.pop() == 10);336 testing.expect(list.pop() == 10);
327 testing.expect(list.len == 9);337 testing.expect(list.items.len == 9);
328338
329 list.appendSlice(&[_]i32{ 1, 2, 3 }) catch unreachable;339 list.appendSlice(&[_]i32{ 1, 2, 3 }) catch unreachable;
330 testing.expect(list.len == 12);340 testing.expect(list.items.len == 12);
331 testing.expect(list.pop() == 3);341 testing.expect(list.pop() == 3);
332 testing.expect(list.pop() == 2);342 testing.expect(list.pop() == 2);
333 testing.expect(list.pop() == 1);343 testing.expect(list.pop() == 1);
334 testing.expect(list.len == 9);344 testing.expect(list.items.len == 9);
335345
336 list.appendSlice(&[_]i32{}) catch unreachable;346 list.appendSlice(&[_]i32{}) catch unreachable;
337 testing.expect(list.len == 9);347 testing.expect(list.items.len == 9);
338348
339 // can only set on indices < self.len349 // can only set on indices < self.items.len
340 list.set(7, 33);350 list.set(7, 33);
341 list.set(8, 42);351 list.set(8, 42);
342352
...@@ -352,8 +362,8 @@ test "std.ArrayList.appendNTimes" {...@@ -352,8 +362,8 @@ test "std.ArrayList.appendNTimes" {
352 defer list.deinit();362 defer list.deinit();
353363
354 try list.appendNTimes(2, 10);364 try list.appendNTimes(2, 10);
355 testing.expectEqual(@as(usize, 10), list.len);365 testing.expectEqual(@as(usize, 10), list.items.len);
356 for (list.span()) |element| {366 for (list.items) |element| {
357 testing.expectEqual(@as(i32, 2), element);367 testing.expectEqual(@as(i32, 2), element);
358 }368 }
359}369}
...@@ -378,17 +388,17 @@ test "std.ArrayList.orderedRemove" {...@@ -378,17 +388,17 @@ test "std.ArrayList.orderedRemove" {
378388
379 //remove from middle389 //remove from middle
380 testing.expectEqual(@as(i32, 4), list.orderedRemove(3));390 testing.expectEqual(@as(i32, 4), list.orderedRemove(3));
381 testing.expectEqual(@as(i32, 5), list.at(3));391 testing.expectEqual(@as(i32, 5), list.items[3]);
382 testing.expectEqual(@as(usize, 6), list.len);392 testing.expectEqual(@as(usize, 6), list.items.len);
383393
384 //remove from end394 //remove from end
385 testing.expectEqual(@as(i32, 7), list.orderedRemove(5));395 testing.expectEqual(@as(i32, 7), list.orderedRemove(5));
386 testing.expectEqual(@as(usize, 5), list.len);396 testing.expectEqual(@as(usize, 5), list.items.len);
387397
388 //remove from front398 //remove from front
389 testing.expectEqual(@as(i32, 1), list.orderedRemove(0));399 testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
390 testing.expectEqual(@as(i32, 2), list.at(0));400 testing.expectEqual(@as(i32, 2), list.items[0]);
391 testing.expectEqual(@as(usize, 4), list.len);401 testing.expectEqual(@as(usize, 4), list.items.len);
392}402}
393403
394test "std.ArrayList.swapRemove" {404test "std.ArrayList.swapRemove" {
...@@ -405,17 +415,17 @@ test "std.ArrayList.swapRemove" {...@@ -405,17 +415,17 @@ test "std.ArrayList.swapRemove" {
405415
406 //remove from middle416 //remove from middle
407 testing.expect(list.swapRemove(3) == 4);417 testing.expect(list.swapRemove(3) == 4);
408 testing.expect(list.at(3) == 7);418 testing.expect(list.items[3] == 7);
409 testing.expect(list.len == 6);419 testing.expect(list.items.len == 6);
410420
411 //remove from end421 //remove from end
412 testing.expect(list.swapRemove(5) == 6);422 testing.expect(list.swapRemove(5) == 6);
413 testing.expect(list.len == 5);423 testing.expect(list.items.len == 5);
414424
415 //remove from front425 //remove from front
416 testing.expect(list.swapRemove(0) == 1);426 testing.expect(list.swapRemove(0) == 1);
417 testing.expect(list.at(0) == 5);427 testing.expect(list.items[0] == 5);
418 testing.expect(list.len == 4);428 testing.expect(list.items.len == 4);
419}429}
420430
421test "std.ArrayList.swapRemoveOrError" {431test "std.ArrayList.swapRemoveOrError" {
...@@ -478,7 +488,7 @@ test "std.ArrayList.insertSlice" {...@@ -478,7 +488,7 @@ test "std.ArrayList.insertSlice" {
478488
479 const items = [_]i32{1};489 const items = [_]i32{1};
480 try list.insertSlice(0, items[0..0]);490 try list.insertSlice(0, items[0..0]);
481 testing.expect(list.len == 6);491 testing.expect(list.items.len == 6);
482 testing.expect(list.items[0] == 1);492 testing.expect(list.items[0] == 1);
483}493}
484494
...@@ -504,3 +514,18 @@ test "std.ArrayList(u8) implements outStream" {...@@ -504,3 +514,18 @@ test "std.ArrayList(u8) implements outStream" {
504514
505 testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.span());515 testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.span());
506}516}
517
518test "std.ArrayList.shrink still sets length on error.OutOfMemory" {
519 // use an arena allocator to make sure realloc returns error.OutOfMemory
520 var arena = std.heap.ArenaAllocator.init(testing.allocator);
521 defer arena.deinit();
522
523 var list = ArrayList(i32).init(&arena.allocator);
524
525 try list.append(1);
526 try list.append(2);
527 try list.append(3);
528
529 list.shrink(1);
530 testing.expect(list.items.len == 1);
531}
lib/std/array_list_sentineled.zig+8-8
...@@ -82,8 +82,8 @@ pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {...@@ -82,8 +82,8 @@ pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {
82 self.list.deinit();82 self.list.deinit();
83 }83 }
8484
85 pub fn span(self: var) @TypeOf(self.list.items[0 .. self.list.len - 1 :sentinel]) {85 pub fn span(self: var) @TypeOf(self.list.items[0..:sentinel]) {
86 return self.list.span()[0..self.len() :sentinel];86 return self.list.items[0..self.len() :sentinel];
87 }87 }
8888
89 pub fn shrink(self: *Self, new_len: usize) void {89 pub fn shrink(self: *Self, new_len: usize) void {
...@@ -98,16 +98,16 @@ pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {...@@ -98,16 +98,16 @@ pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {
98 }98 }
9999
100 pub fn isNull(self: Self) bool {100 pub fn isNull(self: Self) bool {
101 return self.list.len == 0;101 return self.list.items.len == 0;
102 }102 }
103103
104 pub fn len(self: Self) usize {104 pub fn len(self: Self) usize {
105 return self.list.len - 1;105 return self.list.items.len - 1;
106 }106 }
107107
108 pub fn capacity(self: Self) usize {108 pub fn capacity(self: Self) usize {
109 return if (self.list.items.len > 0)109 return if (self.list.capacity > 0)
110 self.list.items.len - 1110 self.list.capacity - 1
111 else111 else
112 0;112 0;
113 }113 }
...@@ -115,13 +115,13 @@ pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {...@@ -115,13 +115,13 @@ pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {
115 pub fn appendSlice(self: *Self, m: []const T) !void {115 pub fn appendSlice(self: *Self, m: []const T) !void {
116 const old_len = self.len();116 const old_len = self.len();
117 try self.resize(old_len + m.len);117 try self.resize(old_len + m.len);
118 mem.copy(T, self.list.span()[old_len..], m);118 mem.copy(T, self.list.items[old_len..], m);
119 }119 }
120120
121 pub fn append(self: *Self, byte: T) !void {121 pub fn append(self: *Self, byte: T) !void {
122 const old_len = self.len();122 const old_len = self.len();
123 try self.resize(old_len + 1);123 try self.resize(old_len + 1);
124 self.list.span()[old_len] = byte;124 self.list.items[old_len] = byte;
125 }125 }
126126
127 pub fn eql(self: Self, m: []const T) bool {127 pub fn eql(self: Self, m: []const T) bool {
lib/std/build.zig+2-2
...@@ -1779,7 +1779,7 @@ pub const LibExeObjStep = struct {...@@ -1779,7 +1779,7 @@ pub const LibExeObjStep = struct {
1779 const self = @fieldParentPtr(LibExeObjStep, "step", step);1779 const self = @fieldParentPtr(LibExeObjStep, "step", step);
1780 const builder = self.builder;1780 const builder = self.builder;
17811781
1782 if (self.root_src == null and self.link_objects.len == 0) {1782 if (self.root_src == null and self.link_objects.items.len == 0) {
1783 warn("{}: linker needs 1 or more objects to link\n", .{self.step.name});1783 warn("{}: linker needs 1 or more objects to link\n", .{self.step.name});
1784 return error.NeedAnObject;1784 return error.NeedAnObject;
1785 }1785 }
...@@ -1847,7 +1847,7 @@ pub const LibExeObjStep = struct {...@@ -1847,7 +1847,7 @@ pub const LibExeObjStep = struct {
1847 }1847 }
1848 }1848 }
18491849
1850 if (self.build_options_contents.len > 0) {1850 if (self.build_options_contents.items.len > 0) {
1851 const build_options_file = try fs.path.join(1851 const build_options_file = try fs.path.join(
1852 builder.allocator,1852 builder.allocator,
1853 &[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) },1853 &[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) },
lib/std/build/emit_raw.zig+1-1
...@@ -94,7 +94,7 @@ const BinaryElfOutput = struct {...@@ -94,7 +94,7 @@ const BinaryElfOutput = struct {
9494
95 sort.sort(*BinaryElfSegment, self.segments.span(), segmentSortCompare);95 sort.sort(*BinaryElfSegment, self.segments.span(), segmentSortCompare);
9696
97 if (self.segments.len > 0) {97 if (self.segments.items.len > 0) {
98 const firstSegment = self.segments.at(0);98 const firstSegment = self.segments.at(0);
99 if (firstSegment.firstSection) |firstSection| {99 if (firstSegment.firstSection) |firstSection| {
100 const diff = firstSection.elfOffset - firstSegment.elfOffset;100 const diff = firstSection.elfOffset - firstSegment.elfOffset;
lib/std/coff.zig+1-1
...@@ -181,7 +181,7 @@ pub const Coff = struct {...@@ -181,7 +181,7 @@ pub const Coff = struct {
181 }181 }
182182
183 pub fn loadSections(self: *Coff) !void {183 pub fn loadSections(self: *Coff) !void {
184 if (self.sections.len == self.coff_header.number_of_sections)184 if (self.sections.items.len == self.coff_header.number_of_sections)
185 return;185 return;
186186
187 try self.sections.ensureCapacity(self.coff_header.number_of_sections);187 try self.sections.ensureCapacity(self.coff_header.number_of_sections);
lib/std/debug.zig+1-1
...@@ -1478,7 +1478,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {...@@ -1478,7 +1478,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
14781478
1479 var coff_section: *coff.Section = undefined;1479 var coff_section: *coff.Section = undefined;
1480 const mod_index = for (self.sect_contribs) |sect_contrib| {1480 const mod_index = for (self.sect_contribs) |sect_contrib| {
1481 if (sect_contrib.Section > self.coff.sections.len) continue;1481 if (sect_contrib.Section > self.coff.sections.items.len) continue;
1482 // Remember that SectionContribEntry.Section is 1-based.1482 // Remember that SectionContribEntry.Section is 1-based.
1483 coff_section = &self.coff.sections.span()[sect_contrib.Section - 1];1483 coff_section = &self.coff.sections.span()[sect_contrib.Section - 1];
14841484
lib/std/dwarf.zig+4-4
...@@ -206,7 +206,7 @@ const LineNumberProgram = struct {...@@ -206,7 +206,7 @@ const LineNumberProgram = struct {
206 if (self.target_address >= self.prev_address and self.target_address < self.address) {206 if (self.target_address >= self.prev_address and self.target_address < self.address) {
207 const file_entry = if (self.prev_file == 0) {207 const file_entry = if (self.prev_file == 0) {
208 return error.MissingDebugInfo;208 return error.MissingDebugInfo;
209 } else if (self.prev_file - 1 >= self.file_entries.len) {209 } else if (self.prev_file - 1 >= self.file_entries.items.len) {
210 return error.InvalidDebugInfo;210 return error.InvalidDebugInfo;
211 } else211 } else
212 &self.file_entries.items[self.prev_file - 1];212 &self.file_entries.items[self.prev_file - 1];
...@@ -645,7 +645,7 @@ pub const DwarfInfo = struct {...@@ -645,7 +645,7 @@ pub const DwarfInfo = struct {
645 .offset = abbrev_offset,645 .offset = abbrev_offset,
646 .table = try di.parseAbbrevTable(abbrev_offset),646 .table = try di.parseAbbrevTable(abbrev_offset),
647 });647 });
648 return &di.abbrev_table_list.items[di.abbrev_table_list.len - 1].table;648 return &di.abbrev_table_list.items[di.abbrev_table_list.items.len - 1].table;
649 }649 }
650650
651 fn parseAbbrevTable(di: *DwarfInfo, offset: u64) !AbbrevTable {651 fn parseAbbrevTable(di: *DwarfInfo, offset: u64) !AbbrevTable {
...@@ -665,7 +665,7 @@ pub const DwarfInfo = struct {...@@ -665,7 +665,7 @@ pub const DwarfInfo = struct {
665 .has_children = (try in.readByte()) == CHILDREN_yes,665 .has_children = (try in.readByte()) == CHILDREN_yes,
666 .attrs = ArrayList(AbbrevAttr).init(di.allocator()),666 .attrs = ArrayList(AbbrevAttr).init(di.allocator()),
667 });667 });
668 const attrs = &result.items[result.len - 1].attrs;668 const attrs = &result.items[result.items.len - 1].attrs;
669669
670 while (true) {670 while (true) {
671 const attr_id = try leb.readULEB128(u64, in);671 const attr_id = try leb.readULEB128(u64, in);
...@@ -689,7 +689,7 @@ pub const DwarfInfo = struct {...@@ -689,7 +689,7 @@ pub const DwarfInfo = struct {
689 .has_children = table_entry.has_children,689 .has_children = table_entry.has_children,
690 .attrs = ArrayList(Die.Attr).init(di.allocator()),690 .attrs = ArrayList(Die.Attr).init(di.allocator()),
691 };691 };
692 try result.attrs.resize(table_entry.attrs.len);692 try result.attrs.resize(table_entry.attrs.items.len);
693 for (table_entry.attrs.span()) |attr, i| {693 for (table_entry.attrs.span()) |attr, i| {
694 result.attrs.items[i] = Die.Attr{694 result.attrs.items[i] = Die.Attr{
695 .id = attr.attr_id,695 .id = attr.attr_id,
lib/std/fs.zig+3-3
...@@ -1440,9 +1440,9 @@ pub const Walker = struct {...@@ -1440,9 +1440,9 @@ pub const Walker = struct {
1440 /// a reference to the path.1440 /// a reference to the path.
1441 pub fn next(self: *Walker) !?Entry {1441 pub fn next(self: *Walker) !?Entry {
1442 while (true) {1442 while (true) {
1443 if (self.stack.len == 0) return null;1443 if (self.stack.items.len == 0) return null;
1444 // `top` becomes invalid after appending to `self.stack`.1444 // `top` becomes invalid after appending to `self.stack`.
1445 const top = &self.stack.span()[self.stack.len - 1];1445 const top = &self.stack.span()[self.stack.items.len - 1];
1446 const dirname_len = top.dirname_len;1446 const dirname_len = top.dirname_len;
1447 if (try top.dir_it.next()) |base| {1447 if (try top.dir_it.next()) |base| {
1448 self.name_buffer.shrink(dirname_len);1448 self.name_buffer.shrink(dirname_len);
...@@ -1457,7 +1457,7 @@ pub const Walker = struct {...@@ -1457,7 +1457,7 @@ pub const Walker = struct {
1457 errdefer new_dir.close();1457 errdefer new_dir.close();
1458 try self.stack.append(StackItem{1458 try self.stack.append(StackItem{
1459 .dir_it = new_dir.iterate(),1459 .dir_it = new_dir.iterate(),
1460 .dirname_len = self.name_buffer.len,1460 .dirname_len = self.name_buffer.items.len,
1461 });1461 });
1462 }1462 }
1463 }1463 }
lib/std/http/headers.zig+12-12
...@@ -139,7 +139,7 @@ pub const Headers = struct {...@@ -139,7 +139,7 @@ pub const Headers = struct {
139 pub fn clone(self: Self, allocator: *Allocator) !Self {139 pub fn clone(self: Self, allocator: *Allocator) !Self {
140 var other = Headers.init(allocator);140 var other = Headers.init(allocator);
141 errdefer other.deinit();141 errdefer other.deinit();
142 try other.data.ensureCapacity(self.data.len);142 try other.data.ensureCapacity(self.data.items.len);
143 try other.index.initCapacity(self.index.entries.len);143 try other.index.initCapacity(self.index.entries.len);
144 for (self.data.span()) |entry| {144 for (self.data.span()) |entry| {
145 try other.append(entry.name, entry.value, entry.never_index);145 try other.append(entry.name, entry.value, entry.never_index);
...@@ -152,7 +152,7 @@ pub const Headers = struct {...@@ -152,7 +152,7 @@ pub const Headers = struct {
152 }152 }
153153
154 pub fn append(self: *Self, name: []const u8, value: []const u8, never_index: ?bool) !void {154 pub fn append(self: *Self, name: []const u8, value: []const u8, never_index: ?bool) !void {
155 const n = self.data.len + 1;155 const n = self.data.items.len + 1;
156 try self.data.ensureCapacity(n);156 try self.data.ensureCapacity(n);
157 var entry: HeaderEntry = undefined;157 var entry: HeaderEntry = undefined;
158 if (self.index.get(name)) |kv| {158 if (self.index.get(name)) |kv| {
...@@ -197,7 +197,7 @@ pub const Headers = struct {...@@ -197,7 +197,7 @@ pub const Headers = struct {
197 if (self.index.remove(name)) |kv| {197 if (self.index.remove(name)) |kv| {
198 var dex = &kv.value;198 var dex = &kv.value;
199 // iterate backwards199 // iterate backwards
200 var i = dex.len;200 var i = dex.items.len;
201 while (i > 0) {201 while (i > 0) {
202 i -= 1;202 i -= 1;
203 const data_index = dex.at(i);203 const data_index = dex.at(i);
...@@ -220,18 +220,18 @@ pub const Headers = struct {...@@ -220,18 +220,18 @@ pub const Headers = struct {
220 const removed = self.data.orderedRemove(i);220 const removed = self.data.orderedRemove(i);
221 const kv = self.index.get(removed.name).?;221 const kv = self.index.get(removed.name).?;
222 var dex = &kv.value;222 var dex = &kv.value;
223 if (dex.len == 1) {223 if (dex.items.len == 1) {
224 // was last item; delete the index224 // was last item; delete the index
225 _ = self.index.remove(kv.key);225 _ = self.index.remove(kv.key);
226 dex.deinit();226 dex.deinit();
227 removed.deinit();227 removed.deinit();
228 self.allocator.free(kv.key);228 self.allocator.free(kv.key);
229 } else {229 } else {
230 dex.shrink(dex.len - 1);230 dex.shrink(dex.items.len - 1);
231 removed.deinit();231 removed.deinit();
232 }232 }
233 // if it was the last item; no need to rebuild index233 // if it was the last item; no need to rebuild index
234 if (i != self.data.len) {234 if (i != self.data.items.len) {
235 self.rebuild_index();235 self.rebuild_index();
236 }236 }
237 }237 }
...@@ -242,18 +242,18 @@ pub const Headers = struct {...@@ -242,18 +242,18 @@ pub const Headers = struct {
242 const removed = self.data.swapRemove(i);242 const removed = self.data.swapRemove(i);
243 const kv = self.index.get(removed.name).?;243 const kv = self.index.get(removed.name).?;
244 var dex = &kv.value;244 var dex = &kv.value;
245 if (dex.len == 1) {245 if (dex.items.len == 1) {
246 // was last item; delete the index246 // was last item; delete the index
247 _ = self.index.remove(kv.key);247 _ = self.index.remove(kv.key);
248 dex.deinit();248 dex.deinit();
249 removed.deinit();249 removed.deinit();
250 self.allocator.free(kv.key);250 self.allocator.free(kv.key);
251 } else {251 } else {
252 dex.shrink(dex.len - 1);252 dex.shrink(dex.items.len - 1);
253 removed.deinit();253 removed.deinit();
254 }254 }
255 // if it was the last item; no need to rebuild index255 // if it was the last item; no need to rebuild index
256 if (i != self.data.len) {256 if (i != self.data.items.len) {
257 self.rebuild_index();257 self.rebuild_index();
258 }258 }
259 }259 }
...@@ -277,7 +277,7 @@ pub const Headers = struct {...@@ -277,7 +277,7 @@ pub const Headers = struct {
277 pub fn get(self: Self, allocator: *Allocator, name: []const u8) !?[]const HeaderEntry {277 pub fn get(self: Self, allocator: *Allocator, name: []const u8) !?[]const HeaderEntry {
278 const dex = self.getIndices(name) orelse return null;278 const dex = self.getIndices(name) orelse return null;
279279
280 const buf = try allocator.alloc(HeaderEntry, dex.len);280 const buf = try allocator.alloc(HeaderEntry, dex.items.len);
281 var n: usize = 0;281 var n: usize = 0;
282 for (dex.span()) |idx| {282 for (dex.span()) |idx| {
283 buf[n] = self.data.at(idx);283 buf[n] = self.data.at(idx);
...@@ -301,7 +301,7 @@ pub const Headers = struct {...@@ -301,7 +301,7 @@ pub const Headers = struct {
301301
302 // adapted from mem.join302 // adapted from mem.join
303 const total_len = blk: {303 const total_len = blk: {
304 var sum: usize = dex.len - 1; // space for separator(s)304 var sum: usize = dex.items.len - 1; // space for separator(s)
305 for (dex.span()) |idx|305 for (dex.span()) |idx|
306 sum += self.data.at(idx).value.len;306 sum += self.data.at(idx).value.len;
307 break :blk sum;307 break :blk sum;
...@@ -330,7 +330,7 @@ pub const Headers = struct {...@@ -330,7 +330,7 @@ pub const Headers = struct {
330 var it = self.index.iterator();330 var it = self.index.iterator();
331 while (it.next()) |kv| {331 while (it.next()) |kv| {
332 var dex = &kv.value;332 var dex = &kv.value;
333 dex.len = 0; // keeps capacity available333 dex.items.len = 0; // keeps capacity available
334 }334 }
335 }335 }
336 { // fill up indexes again; we know capacity is fine from before336 { // fill up indexes again; we know capacity is fine from before
lib/std/io/in_stream.zig+2-2
...@@ -54,7 +54,7 @@ pub fn InStream(...@@ -54,7 +54,7 @@ pub fn InStream(
54 /// and the `std.ArrayList` has exactly `max_append_size` bytes appended.54 /// and the `std.ArrayList` has exactly `max_append_size` bytes appended.
55 pub fn readAllArrayList(self: Self, array_list: *std.ArrayList(u8), max_append_size: usize) !void {55 pub fn readAllArrayList(self: Self, array_list: *std.ArrayList(u8), max_append_size: usize) !void {
56 try array_list.ensureCapacity(math.min(max_append_size, 4096));56 try array_list.ensureCapacity(math.min(max_append_size, 4096));
57 const original_len = array_list.len;57 const original_len = array_list.items.len;
58 var start_index: usize = original_len;58 var start_index: usize = original_len;
59 while (true) {59 while (true) {
60 array_list.expandToCapacity();60 array_list.expandToCapacity();
...@@ -106,7 +106,7 @@ pub fn InStream(...@@ -106,7 +106,7 @@ pub fn InStream(
106 return;106 return;
107 }107 }
108108
109 if (array_list.len == max_size) {109 if (array_list.items.len == max_size) {
110 return error.StreamTooLong;110 return error.StreamTooLong;
111 }111 }
112112
lib/std/json.zig+10-10
...@@ -1556,7 +1556,7 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options:...@@ -1556,7 +1556,7 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options:
1556 else => {},1556 else => {},
1557 }1557 }
15581558
1559 try arraylist.ensureCapacity(arraylist.len + 1);1559 try arraylist.ensureCapacity(arraylist.items.len + 1);
1560 const v = try parseInternal(ptrInfo.child, tok, tokens, options);1560 const v = try parseInternal(ptrInfo.child, tok, tokens, options);
1561 arraylist.appendAssumeCapacity(v);1561 arraylist.appendAssumeCapacity(v);
1562 }1562 }
...@@ -1874,7 +1874,7 @@ pub const Parser = struct {...@@ -1874,7 +1874,7 @@ pub const Parser = struct {
1874 try p.transition(&arena.allocator, input, s.i - 1, token);1874 try p.transition(&arena.allocator, input, s.i - 1, token);
1875 }1875 }
18761876
1877 debug.assert(p.stack.len == 1);1877 debug.assert(p.stack.items.len == 1);
18781878
1879 return ValueTree{1879 return ValueTree{
1880 .arena = arena,1880 .arena = arena,
...@@ -1888,7 +1888,7 @@ pub const Parser = struct {...@@ -1888,7 +1888,7 @@ pub const Parser = struct {
1888 switch (p.state) {1888 switch (p.state) {
1889 .ObjectKey => switch (token) {1889 .ObjectKey => switch (token) {
1890 .ObjectEnd => {1890 .ObjectEnd => {
1891 if (p.stack.len == 1) {1891 if (p.stack.items.len == 1) {
1892 return;1892 return;
1893 }1893 }
18941894
...@@ -1907,8 +1907,8 @@ pub const Parser = struct {...@@ -1907,8 +1907,8 @@ pub const Parser = struct {
1907 },1907 },
1908 },1908 },
1909 .ObjectValue => {1909 .ObjectValue => {
1910 var object = &p.stack.items[p.stack.len - 2].Object;1910 var object = &p.stack.items[p.stack.items.len - 2].Object;
1911 var key = p.stack.items[p.stack.len - 1].String;1911 var key = p.stack.items[p.stack.items.len - 1].String;
19121912
1913 switch (token) {1913 switch (token) {
1914 .ObjectBegin => {1914 .ObjectBegin => {
...@@ -1950,11 +1950,11 @@ pub const Parser = struct {...@@ -1950,11 +1950,11 @@ pub const Parser = struct {
1950 }1950 }
1951 },1951 },
1952 .ArrayValue => {1952 .ArrayValue => {
1953 var array = &p.stack.items[p.stack.len - 1].Array;1953 var array = &p.stack.items[p.stack.items.len - 1].Array;
19541954
1955 switch (token) {1955 switch (token) {
1956 .ArrayEnd => {1956 .ArrayEnd => {
1957 if (p.stack.len == 1) {1957 if (p.stack.items.len == 1) {
1958 return;1958 return;
1959 }1959 }
19601960
...@@ -2021,12 +2021,12 @@ pub const Parser = struct {...@@ -2021,12 +2021,12 @@ pub const Parser = struct {
2021 }2021 }
20222022
2023 fn pushToParent(p: *Parser, value: *const Value) !void {2023 fn pushToParent(p: *Parser, value: *const Value) !void {
2024 switch (p.stack.span()[p.stack.len - 1]) {2024 switch (p.stack.span()[p.stack.items.len - 1]) {
2025 // Object Parent -> [ ..., object, <key>, value ]2025 // Object Parent -> [ ..., object, <key>, value ]
2026 Value.String => |key| {2026 Value.String => |key| {
2027 _ = p.stack.pop();2027 _ = p.stack.pop();
20282028
2029 var object = &p.stack.items[p.stack.len - 1].Object;2029 var object = &p.stack.items[p.stack.items.len - 1].Object;
2030 _ = try object.put(key, value.*);2030 _ = try object.put(key, value.*);
2031 p.state = .ObjectKey;2031 p.state = .ObjectKey;
2032 },2032 },
...@@ -2165,7 +2165,7 @@ test "json.parser.dynamic" {...@@ -2165,7 +2165,7 @@ test "json.parser.dynamic" {
2165 testing.expect(animated.Bool == false);2165 testing.expect(animated.Bool == false);
21662166
2167 const array_of_object = image.Object.get("ArrayOfObject").?.value;2167 const array_of_object = image.Object.get("ArrayOfObject").?.value;
2168 testing.expect(array_of_object.Array.len == 1);2168 testing.expect(array_of_object.Array.items.len == 1);
21692169
2170 const obj0 = array_of_object.Array.at(0).Object.get("n").?.value;2170 const obj0 = array_of_object.Array.at(0).Object.get("n").?.value;
2171 testing.expect(mem.eql(u8, obj0.String, "m"));2171 testing.expect(mem.eql(u8, obj0.String, "m"));
lib/std/math/big/rational.zig-1
...@@ -4,7 +4,6 @@ const math = std.math;...@@ -4,7 +4,6 @@ const math = std.math;
4const mem = std.mem;4const mem = std.mem;
5const testing = std.testing;5const testing = std.testing;
6const Allocator = mem.Allocator;6const Allocator = mem.Allocator;
7const ArrayList = std.ArrayList;
87
9const bn = @import("int.zig");8const bn = @import("int.zig");
10const Limb = bn.Limb;9const Limb = bn.Limb;
lib/std/net.zig+8-8
...@@ -509,7 +509,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*...@@ -509,7 +509,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
509509
510 try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);510 try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);
511511
512 result.addrs = try arena.alloc(Address, lookup_addrs.len);512 result.addrs = try arena.alloc(Address, lookup_addrs.items.len);
513 if (!canon.isNull()) {513 if (!canon.isNull()) {
514 result.canon_name = canon.toOwnedSlice();514 result.canon_name = canon.toOwnedSlice();
515 }515 }
...@@ -554,7 +554,7 @@ fn linuxLookupName(...@@ -554,7 +554,7 @@ fn linuxLookupName(
554 return name_err;554 return name_err;
555 } else {555 } else {
556 try linuxLookupNameFromHosts(addrs, canon, name, family, port);556 try linuxLookupNameFromHosts(addrs, canon, name, family, port);
557 if (addrs.len == 0) {557 if (addrs.items.len == 0) {
558 try linuxLookupNameFromDnsSearch(addrs, canon, name, family, port);558 try linuxLookupNameFromDnsSearch(addrs, canon, name, family, port);
559 }559 }
560 }560 }
...@@ -562,11 +562,11 @@ fn linuxLookupName(...@@ -562,11 +562,11 @@ fn linuxLookupName(
562 try canon.resize(0);562 try canon.resize(0);
563 try linuxLookupNameFromNull(addrs, family, flags, port);563 try linuxLookupNameFromNull(addrs, family, flags, port);
564 }564 }
565 if (addrs.len == 0) return error.UnknownHostName;565 if (addrs.items.len == 0) return error.UnknownHostName;
566566
567 // No further processing is needed if there are fewer than 2567 // No further processing is needed if there are fewer than 2
568 // results or if there are only IPv4 results.568 // results or if there are only IPv4 results.
569 if (addrs.len == 1 or family == os.AF_INET) return;569 if (addrs.items.len == 1 or family == os.AF_INET) return;
570 const all_ip4 = for (addrs.span()) |addr| {570 const all_ip4 = for (addrs.span()) |addr| {
571 if (addr.addr.any.family != os.AF_INET) break false;571 if (addr.addr.any.family != os.AF_INET) break false;
572 } else true;572 } else true;
...@@ -908,7 +908,7 @@ fn linuxLookupNameFromDnsSearch(...@@ -908,7 +908,7 @@ fn linuxLookupNameFromDnsSearch(
908 canon.shrink(canon_name.len + 1);908 canon.shrink(canon_name.len + 1);
909 try canon.appendSlice(tok);909 try canon.appendSlice(tok);
910 try linuxLookupNameFromDns(addrs, canon, canon.span(), family, rc, port);910 try linuxLookupNameFromDns(addrs, canon, canon.span(), family, rc, port);
911 if (addrs.len != 0) return;911 if (addrs.items.len != 0) return;
912 }912 }
913913
914 canon.shrink(canon_name.len);914 canon.shrink(canon_name.len);
...@@ -967,7 +967,7 @@ fn linuxLookupNameFromDns(...@@ -967,7 +967,7 @@ fn linuxLookupNameFromDns(
967 dnsParse(ap[i], ctx, dnsParseCallback) catch {};967 dnsParse(ap[i], ctx, dnsParseCallback) catch {};
968 }968 }
969969
970 if (addrs.len != 0) return;970 if (addrs.items.len != 0) return;
971 if (ap[0].len < 4 or (ap[0][3] & 15) == 2) return error.TemporaryNameServerFailure;971 if (ap[0].len < 4 or (ap[0][3] & 15) == 2) return error.TemporaryNameServerFailure;
972 if ((ap[0][3] & 15) == 0) return error.UnknownHostName;972 if ((ap[0][3] & 15) == 0) return error.UnknownHostName;
973 if ((ap[0][3] & 15) == 3) return;973 if ((ap[0][3] & 15) == 3) return;
...@@ -1049,7 +1049,7 @@ fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {...@@ -1049,7 +1049,7 @@ fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {
1049 }1049 }
1050 }1050 }
10511051
1052 if (rc.ns.len == 0) {1052 if (rc.ns.items.len == 0) {
1053 return linuxLookupNameFromNumericUnspec(&rc.ns, "127.0.0.1", 53);1053 return linuxLookupNameFromNumericUnspec(&rc.ns, "127.0.0.1", 53);
1054 }1054 }
1055}1055}
...@@ -1078,7 +1078,7 @@ fn resMSendRc(...@@ -1078,7 +1078,7 @@ fn resMSendRc(
1078 var ns_list = std.ArrayList(Address).init(rc.ns.allocator);1078 var ns_list = std.ArrayList(Address).init(rc.ns.allocator);
1079 defer ns_list.deinit();1079 defer ns_list.deinit();
10801080
1081 try ns_list.resize(rc.ns.len);1081 try ns_list.resize(rc.ns.items.len);
1082 const ns = ns_list.span();1082 const ns = ns_list.span();
10831083
1084 for (rc.ns.span()) |iplit, i| {1084 for (rc.ns.span()) |iplit, i| {
lib/std/special/build_runner.zig+1-1
...@@ -171,7 +171,7 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {...@@ -171,7 +171,7 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {
171 \\171 \\
172 );172 );
173173
174 if (builder.available_options_list.len == 0) {174 if (builder.available_options_list.items.len == 0) {
175 try out_stream.print(" (none)\n", .{});175 try out_stream.print(" (none)\n", .{});
176 } else {176 } else {
177 for (builder.available_options_list.span()) |option| {177 for (builder.available_options_list.span()) |option| {
lib/std/unicode.zig+2-2
...@@ -475,7 +475,7 @@ pub fn utf16leToUtf8Alloc(allocator: *mem.Allocator, utf16le: []const u16) ![]u8...@@ -475,7 +475,7 @@ pub fn utf16leToUtf8Alloc(allocator: *mem.Allocator, utf16le: []const u16) ![]u8
475 var it = Utf16LeIterator.init(utf16le);475 var it = Utf16LeIterator.init(utf16le);
476 while (try it.nextCodepoint()) |codepoint| {476 while (try it.nextCodepoint()) |codepoint| {
477 const utf8_len = utf8CodepointSequenceLength(codepoint) catch unreachable;477 const utf8_len = utf8CodepointSequenceLength(codepoint) catch unreachable;
478 try result.resize(result.len + utf8_len);478 try result.resize(result.items.len + utf8_len);
479 assert((utf8Encode(codepoint, result.items[out_index..]) catch unreachable) == utf8_len);479 assert((utf8Encode(codepoint, result.items[out_index..]) catch unreachable) == utf8_len);
480 out_index += utf8_len;480 out_index += utf8_len;
481 }481 }
...@@ -571,7 +571,7 @@ pub fn utf8ToUtf16LeWithNull(allocator: *mem.Allocator, utf8: []const u8) ![:0]u...@@ -571,7 +571,7 @@ pub fn utf8ToUtf16LeWithNull(allocator: *mem.Allocator, utf8: []const u8) ![:0]u
571 }571 }
572 }572 }
573573
574 const len = result.len;574 const len = result.items.len;
575 try result.append(0);575 try result.append(0);
576 return result.toOwnedSlice()[0..len :0];576 return result.toOwnedSlice()[0..len :0];
577}577}
src-self-hosted/libc_installation.zig+3-3
...@@ -268,7 +268,7 @@ pub const LibCInstallation = struct {...@@ -268,7 +268,7 @@ pub const LibCInstallation = struct {
268 try search_paths.append(line);268 try search_paths.append(line);
269 }269 }
270 }270 }
271 if (search_paths.len == 0) {271 if (search_paths.items.len == 0) {
272 return error.CCompilerCannotFindHeaders;272 return error.CCompilerCannotFindHeaders;
273 }273 }
274274
...@@ -276,9 +276,9 @@ pub const LibCInstallation = struct {...@@ -276,9 +276,9 @@ pub const LibCInstallation = struct {
276 const sys_include_dir_example_file = if (is_windows) "sys\\types.h" else "sys/errno.h";276 const sys_include_dir_example_file = if (is_windows) "sys\\types.h" else "sys/errno.h";
277277
278 var path_i: usize = 0;278 var path_i: usize = 0;
279 while (path_i < search_paths.len) : (path_i += 1) {279 while (path_i < search_paths.items.len) : (path_i += 1) {
280 // search in reverse order280 // search in reverse order
281 const search_path_untrimmed = search_paths.at(search_paths.len - path_i - 1);281 const search_path_untrimmed = search_paths.at(search_paths.items.len - path_i - 1);
282 const search_path = std.mem.trimLeft(u8, search_path_untrimmed, " ");282 const search_path = std.mem.trimLeft(u8, search_path_untrimmed, " ");
283 var search_dir = fs.cwd().openDir(search_path, .{}) catch |err| switch (err) {283 var search_dir = fs.cwd().openDir(search_path, .{}) catch |err| switch (err) {
284 error.FileNotFound,284 error.FileNotFound,
src-self-hosted/stage2.zig+2-2
...@@ -239,7 +239,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {...@@ -239,7 +239,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
239 }239 }
240240
241 if (stdin_flag) {241 if (stdin_flag) {
242 if (input_files.len != 0) {242 if (input_files.items.len != 0) {
243 try stderr.writeAll("cannot use --stdin with positional arguments\n");243 try stderr.writeAll("cannot use --stdin with positional arguments\n");
244 process.exit(1);244 process.exit(1);
245 }245 }
...@@ -273,7 +273,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {...@@ -273,7 +273,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
273 return;273 return;
274 }274 }
275275
276 if (input_files.len == 0) {276 if (input_files.items.len == 0) {
277 try stderr.writeAll("expected at least one source file argument\n");277 try stderr.writeAll("expected at least one source file argument\n");
278 process.exit(1);278 process.exit(1);
279 }279 }
src-self-hosted/translate_c.zig+3-3
...@@ -4309,7 +4309,7 @@ fn makeRestorePoint(c: *Context) RestorePoint {...@@ -4309,7 +4309,7 @@ fn makeRestorePoint(c: *Context) RestorePoint {
4309 return RestorePoint{4309 return RestorePoint{
4310 .c = c,4310 .c = c,
4311 .token_index = c.tree.tokens.len,4311 .token_index = c.tree.tokens.len,
4312 .src_buf_index = c.source_buffer.len,4312 .src_buf_index = c.source_buffer.items.len,
4313 };4313 };
4314}4314}
43154315
...@@ -4771,11 +4771,11 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd...@@ -4771,11 +4771,11 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd
47714771
4772fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {4772fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {
4773 assert(token_id != .Invalid);4773 assert(token_id != .Invalid);
4774 const start_index = c.source_buffer.len;4774 const start_index = c.source_buffer.items.len;
4775 errdefer c.source_buffer.shrink(start_index);4775 errdefer c.source_buffer.shrink(start_index);
47764776
4777 try c.source_buffer.outStream().print(format, args);4777 try c.source_buffer.outStream().print(format, args);
4778 const end_index = c.source_buffer.len;4778 const end_index = c.source_buffer.items.len;
4779 const token_index = c.tree.tokens.len;4779 const token_index = c.tree.tokens.len;
4780 const new_token = try c.tree.tokens.addOne();4780 const new_token = try c.tree.tokens.addOne();
4781 errdefer c.tree.tokens.shrink(token_index);4781 errdefer c.tree.tokens.shrink(token_index);
test/standalone/brace_expansion/main.zig+2-2
...@@ -113,7 +113,7 @@ fn parse(tokens: *const ArrayList(Token), token_index: *usize) ParseError!Node {...@@ -113,7 +113,7 @@ fn parse(tokens: *const ArrayList(Token), token_index: *usize) ParseError!Node {
113113
114fn expandString(input: []const u8, output: *ArrayListSentineled(u8, 0)) !void {114fn expandString(input: []const u8, output: *ArrayListSentineled(u8, 0)) !void {
115 const tokens = try tokenize(input);115 const tokens = try tokenize(input);
116 if (tokens.len == 1) {116 if (tokens.items.len == 1) {
117 return output.resize(0);117 return output.resize(0);
118 }118 }
119119
...@@ -142,7 +142,7 @@ fn expandString(input: []const u8, output: *ArrayListSentineled(u8, 0)) !void {...@@ -142,7 +142,7 @@ fn expandString(input: []const u8, output: *ArrayListSentineled(u8, 0)) !void {
142const ExpandNodeError = error{OutOfMemory};142const ExpandNodeError = error{OutOfMemory};
143143
144fn expandNode(node: Node, output: *ArrayList(ArrayListSentineled(u8, 0))) ExpandNodeError!void {144fn expandNode(node: Node, output: *ArrayList(ArrayListSentineled(u8, 0))) ExpandNodeError!void {
145 assert(output.len == 0);145 assert(output.items.len == 0);
146 switch (node) {146 switch (node) {
147 Node.Scalar => |scalar| {147 Node.Scalar => |scalar| {
148 try output.append(try ArrayListSentineled(u8, 0).init(global_allocator, scalar));148 try output.append(try ArrayListSentineled(u8, 0).init(global_allocator, scalar));
test/tests.zig+2-2
...@@ -879,13 +879,13 @@ pub const CompileErrorContext = struct {...@@ -879,13 +879,13 @@ pub const CompileErrorContext = struct {
879 var err_iter = ErrLineIter.init(stderr);879 var err_iter = ErrLineIter.init(stderr);
880 var i: usize = 0;880 var i: usize = 0;
881 ok = while (err_iter.next()) |line| : (i += 1) {881 ok = while (err_iter.next()) |line| : (i += 1) {
882 if (i >= self.case.expected_errors.len) break false;882 if (i >= self.case.expected_errors.items.len) break false;
883 const expected = self.case.expected_errors.at(i);883 const expected = self.case.expected_errors.at(i);
884 if (mem.indexOf(u8, line, expected) == null) break false;884 if (mem.indexOf(u8, line, expected) == null) break false;
885 continue;885 continue;
886 } else true;886 } else true;
887887
888 ok = ok and i == self.case.expected_errors.len;888 ok = ok and i == self.case.expected_errors.items.len;
889889
890 if (!ok) {890 if (!ok) {
891 warn("\n======== Expected these compile errors: ========\n", .{});891 warn("\n======== Expected these compile errors: ========\n", .{});
tools/merge_anal_dumps.zig+4-4
...@@ -194,7 +194,7 @@ const Dump = struct {...@@ -194,7 +194,7 @@ const Dump = struct {
194 for (other_files) |other_file, i| {194 for (other_files) |other_file, i| {
195 const gop = try self.file_map.getOrPut(other_file.String);195 const gop = try self.file_map.getOrPut(other_file.String);
196 if (!gop.found_existing) {196 if (!gop.found_existing) {
197 gop.kv.value = self.file_list.len;197 gop.kv.value = self.file_list.items.len;
198 try self.file_list.append(other_file.String);198 try self.file_list.append(other_file.String);
199 }199 }
200 try other_file_to_mine.putNoClobber(i, gop.kv.value);200 try other_file_to_mine.putNoClobber(i, gop.kv.value);
...@@ -213,7 +213,7 @@ const Dump = struct {...@@ -213,7 +213,7 @@ const Dump = struct {
213 };213 };
214 const gop = try self.node_map.getOrPut(other_node);214 const gop = try self.node_map.getOrPut(other_node);
215 if (!gop.found_existing) {215 if (!gop.found_existing) {
216 gop.kv.value = self.node_list.len;216 gop.kv.value = self.node_list.items.len;
217 try self.node_list.append(other_node);217 try self.node_list.append(other_node);
218 }218 }
219 try other_ast_node_to_mine.putNoClobber(i, gop.kv.value);219 try other_ast_node_to_mine.putNoClobber(i, gop.kv.value);
...@@ -243,7 +243,7 @@ const Dump = struct {...@@ -243,7 +243,7 @@ const Dump = struct {
243 };243 };
244 const gop = try self.error_map.getOrPut(other_error);244 const gop = try self.error_map.getOrPut(other_error);
245 if (!gop.found_existing) {245 if (!gop.found_existing) {
246 gop.kv.value = self.error_list.len;246 gop.kv.value = self.error_list.items.len;
247 try self.error_list.append(other_error);247 try self.error_list.append(other_error);
248 }248 }
249 try other_error_to_mine.putNoClobber(i, gop.kv.value);249 try other_error_to_mine.putNoClobber(i, gop.kv.value);
...@@ -304,7 +304,7 @@ const Dump = struct {...@@ -304,7 +304,7 @@ const Dump = struct {
304 ) !void {304 ) !void {
305 const gop = try self.type_map.getOrPut(other_type);305 const gop = try self.type_map.getOrPut(other_type);
306 if (!gop.found_existing) {306 if (!gop.found_existing) {
307 gop.kv.value = self.type_list.len;307 gop.kv.value = self.type_list.items.len;
308 try self.type_list.append(other_type);308 try self.type_list.append(other_type);
309 }309 }
310 try other_types_to_mine.putNoClobber(other_type_index, gop.kv.value);310 try other_types_to_mine.putNoClobber(other_type_index, gop.kv.value);