| ... | ... | @@ -12,10 +12,20 @@ const Allocator = mem.Allocator; |
| 12 | 12 | |
| 13 | 13 | /// A contiguous, growable list of items in memory. |
| 14 | 14 | /// This is a wrapper around an array of T values. Initialize with `init`. |
| 15 | /// |
| 16 | /// This struct internally stores a `std.mem.Allocator` for memory management. |
| 17 | /// To manually specify an allocator with each method call see `ArrayListUnmanaged`. |
| 15 | 18 | pub fn ArrayList(comptime T: type) type { |
| 16 | 19 | return ArrayListAligned(T, null); |
| 17 | 20 | } |
| 18 | 21 | |
| 22 | /// A contiguous, growable list of arbitrarily aligned items in memory. |
| 23 | /// This is a wrapper around an array of T values aligned to `alignment`-byte |
| 24 | /// addresses. If the specified alignment is `null`, then `@alignOf(T)` is used. |
| 25 | /// Initialize with `init`. |
| 26 | /// |
| 27 | /// This struct internally stores a `std.mem.Allocator` for memory management. |
| 28 | /// To manually specify an allocator with each method call see `ArrayListAlignedUnmanaged`. |
| 19 | 29 | pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 20 | 30 | if (alignment) |a| { |
| 21 | 31 | if (a == @alignOf(T)) { |
| ... | ... | @@ -24,9 +34,18 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 24 | 34 | } |
| 25 | 35 | return struct { |
| 26 | 36 | const Self = @This(); |
| 27 | | |
| 28 | | /// Content of the ArrayList |
| 37 | /// Contents of the list. Pointers to elements in this slice are |
| 38 | /// **invalid after resizing operations** on the ArrayList, unless the |
| 39 | /// operation explicitly either: (1) states otherwise or (2) lists the |
| 40 | /// invalidated pointers. |
| 41 | /// |
| 42 | /// The allocator used determines how element pointers are |
| 43 | /// invalidated, so the behavior may vary between lists. To avoid |
| 44 | /// illegal behavior, take into account the above paragraph plus the |
| 45 | /// explicit statements given in each method. |
| 29 | 46 | items: Slice, |
| 47 | /// How many T values this list can hold without allocating |
| 48 | /// additional memory. |
| 30 | 49 | capacity: usize, |
| 31 | 50 | allocator: *Allocator, |
| 32 | 51 | |
| ... | ... | @@ -42,7 +61,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 42 | 61 | }; |
| 43 | 62 | } |
| 44 | 63 | |
| 45 | | /// Initialize with capacity to hold at least num elements. |
| 64 | /// Initialize with capacity to hold at least `num` elements. |
| 46 | 65 | /// Deinitialize with `deinit` or use `toOwnedSlice`. |
| 47 | 66 | pub fn initCapacity(allocator: *Allocator, num: usize) !Self { |
| 48 | 67 | var self = Self.init(allocator); |
| ... | ... | @@ -79,11 +98,13 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 79 | 98 | }; |
| 80 | 99 | } |
| 81 | 100 | |
| 101 | /// Initializes an ArrayListUnmanaged with the `items` and `capacity` fields |
| 102 | /// of this ArrayList. This ArrayList retains ownership of underlying memory. |
| 82 | 103 | pub fn toUnmanaged(self: Self) ArrayListAlignedUnmanaged(T, alignment) { |
| 83 | 104 | return .{ .items = self.items, .capacity = self.capacity }; |
| 84 | 105 | } |
| 85 | 106 | |
| 86 | | /// The caller owns the returned memory. ArrayList becomes empty. |
| 107 | /// The caller owns the returned memory. Empties this ArrayList. |
| 87 | 108 | pub fn toOwnedSlice(self: *Self) Slice { |
| 88 | 109 | const allocator = self.allocator; |
| 89 | 110 | const result = allocator.shrink(self.allocatedSlice(), self.items.len); |
| ... | ... | @@ -91,7 +112,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 91 | 112 | return result; |
| 92 | 113 | } |
| 93 | 114 | |
| 94 | | /// The caller owns the returned memory. ArrayList becomes empty. |
| 115 | /// The caller owns the returned memory. Empties this ArrayList. |
| 95 | 116 | pub fn toOwnedSliceSentinel(self: *Self, comptime sentinel: T) ![:sentinel]T { |
| 96 | 117 | try self.append(sentinel); |
| 97 | 118 | const result = self.toOwnedSlice(); |
| ... | ... | @@ -118,9 +139,10 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 118 | 139 | mem.copy(T, self.items[i .. i + items.len], items); |
| 119 | 140 | } |
| 120 | 141 | |
| 121 | | /// Replace range of elements `list[start..start+len]` with `new_items` |
| 122 | | /// grows list if `len < new_items.len`. may allocate |
| 123 | | /// shrinks list if `len > new_items.len` |
| 142 | /// Replace range of elements `list[start..start+len]` with `new_items`. |
| 143 | /// Grows list if `len < new_items.len`. |
| 144 | /// Shrinks list if `len > new_items.len`. |
| 145 | /// Invalidates pointers if this ArrayList is resized. |
| 124 | 146 | pub fn replaceRange(self: *Self, start: usize, len: usize, new_items: SliceConst) !void { |
| 125 | 147 | const after_range = start + len; |
| 126 | 148 | const range = self.items[start..after_range]; |
| ... | ... | @@ -151,15 +173,18 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 151 | 173 | new_item_ptr.* = item; |
| 152 | 174 | } |
| 153 | 175 | |
| 154 | | /// Extend the list by 1 element, but asserting `self.capacity` |
| 155 | | /// is sufficient to hold an additional item. |
| 176 | /// Extend the list by 1 element, but assert `self.capacity` |
| 177 | /// is sufficient to hold an additional item. **Does not** |
| 178 | /// invalidate pointers. |
| 156 | 179 | pub fn appendAssumeCapacity(self: *Self, item: T) void { |
| 157 | 180 | const new_item_ptr = self.addOneAssumeCapacity(); |
| 158 | 181 | new_item_ptr.* = item; |
| 159 | 182 | } |
| 160 | 183 | |
| 161 | | /// Remove the element at index `i` from the list and return its value. |
| 184 | /// Remove the element at index `i`, shift elements after index |
| 185 | /// `i` forward, and return the removed element. |
| 162 | 186 | /// Asserts the array has at least one item. |
| 187 | /// Invalidates pointers to end of list. |
| 163 | 188 | /// This operation is O(N). |
| 164 | 189 | pub fn orderedRemove(self: *Self, i: usize) T { |
| 165 | 190 | const newlen = self.items.len - 1; |
| ... | ... | @@ -191,7 +216,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 191 | 216 | } |
| 192 | 217 | |
| 193 | 218 | /// Append the slice of items to the list, asserting the capacity is already |
| 194 | | /// enough to store the new items. |
| 219 | /// enough to store the new items. **Does not** invalidate pointers. |
| 195 | 220 | pub fn appendSliceAssumeCapacity(self: *Self, items: SliceConst) void { |
| 196 | 221 | const oldlen = self.items.len; |
| 197 | 222 | const newlen = self.items.len + items.len; |
| ... | ... | @@ -227,7 +252,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 227 | 252 | } |
| 228 | 253 | |
| 229 | 254 | /// Append a value to the list `n` times. |
| 230 | | /// Asserts the capacity is enough. |
| 255 | /// Asserts the capacity is enough. **Does not** invalidate pointers. |
| 231 | 256 | pub fn appendNTimesAssumeCapacity(self: *Self, value: T, n: usize) void { |
| 232 | 257 | const new_len = self.items.len + n; |
| 233 | 258 | assert(new_len <= self.capacity); |
| ... | ... | @@ -243,7 +268,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 243 | 268 | } |
| 244 | 269 | |
| 245 | 270 | /// Reduce allocated capacity to `new_len`. |
| 246 | | /// Invalidates element pointers. |
| 271 | /// May invalidate element pointers. |
| 247 | 272 | pub fn shrink(self: *Self, new_len: usize) void { |
| 248 | 273 | assert(new_len <= self.items.len); |
| 249 | 274 | |
| ... | ... | @@ -257,13 +282,14 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 257 | 282 | } |
| 258 | 283 | |
| 259 | 284 | /// Reduce length to `new_len`. |
| 260 | | /// Invalidates element pointers. |
| 261 | | /// Keeps capacity the same. |
| 285 | /// Invalidates pointers for the elements `items[new_len..]`. |
| 262 | 286 | pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void { |
| 263 | 287 | assert(new_len <= self.items.len); |
| 264 | 288 | self.items.len = new_len; |
| 265 | 289 | } |
| 266 | 290 | |
| 291 | /// Modify the array so that it can hold at least `new_capacity` items. |
| 292 | /// Invalidates pointers if additional memory is needed. |
| 267 | 293 | pub fn ensureCapacity(self: *Self, new_capacity: usize) !void { |
| 268 | 294 | var better_capacity = self.capacity; |
| 269 | 295 | if (better_capacity >= new_capacity) return; |
| ... | ... | @@ -280,14 +306,13 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 280 | 306 | } |
| 281 | 307 | |
| 282 | 308 | /// Increases the array's length to match the full capacity that is already allocated. |
| 283 | | /// The new elements have `undefined` values. This operation does not invalidate any |
| 284 | | /// element pointers. |
| 309 | /// The new elements have `undefined` values. **Does not** invalidate pointers. |
| 285 | 310 | pub fn expandToCapacity(self: *Self) void { |
| 286 | 311 | self.items.len = self.capacity; |
| 287 | 312 | } |
| 288 | 313 | |
| 289 | 314 | /// Increase length by 1, returning pointer to the new item. |
| 290 | | /// The returned pointer becomes invalid when the list is resized. |
| 315 | /// The returned pointer becomes invalid when the list resized. |
| 291 | 316 | pub fn addOne(self: *Self) !*T { |
| 292 | 317 | const newlen = self.items.len + 1; |
| 293 | 318 | try self.ensureCapacity(newlen); |
| ... | ... | @@ -297,6 +322,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 297 | 322 | /// Increase length by 1, returning pointer to the new item. |
| 298 | 323 | /// Asserts that there is already space for the new item without allocating more. |
| 299 | 324 | /// The returned pointer becomes invalid when the list is resized. |
| 325 | /// **Does not** invalidate element pointers. |
| 300 | 326 | pub fn addOneAssumeCapacity(self: *Self) *T { |
| 301 | 327 | assert(self.items.len < self.capacity); |
| 302 | 328 | |
| ... | ... | @@ -306,6 +332,8 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 306 | 332 | |
| 307 | 333 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 308 | 334 | /// The return value is an array pointing to the newly allocated elements. |
| 335 | /// The returned pointer becomes invalid when the list is resized. |
| 336 | /// Resizes list if `self.capacity` is not large enough. |
| 309 | 337 | pub fn addManyAsArray(self: *Self, comptime n: usize) !*[n]T { |
| 310 | 338 | const prev_len = self.items.len; |
| 311 | 339 | try self.resize(self.items.len + n); |
| ... | ... | @@ -315,6 +343,8 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 315 | 343 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 316 | 344 | /// The return value is an array pointing to the newly allocated elements. |
| 317 | 345 | /// Asserts that there is already space for the new item without allocating more. |
| 346 | /// **Does not** invalidate element pointers. |
| 347 | /// The returned pointer becomes invalid when the list is resized. |
| 318 | 348 | pub fn addManyAsArrayAssumeCapacity(self: *Self, comptime n: usize) *[n]T { |
| 319 | 349 | assert(self.items.len + n <= self.capacity); |
| 320 | 350 | const prev_len = self.items.len; |
| ... | ... | @@ -324,21 +354,23 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 324 | 354 | |
| 325 | 355 | /// Remove and return the last element from the list. |
| 326 | 356 | /// Asserts the list has at least one item. |
| 357 | /// Invalidates pointers to the removed element. |
| 327 | 358 | pub fn pop(self: *Self) T { |
| 328 | 359 | const val = self.items[self.items.len - 1]; |
| 329 | 360 | self.items.len -= 1; |
| 330 | 361 | return val; |
| 331 | 362 | } |
| 332 | 363 | |
| 333 | | /// Remove and return the last element from the list. |
| 334 | | /// If the list is empty, returns `null`. |
| 364 | /// Remove and return the last element from the list, or |
| 365 | /// return `null` if list is empty. |
| 366 | /// Invalidates pointers to the removed element, if any. |
| 335 | 367 | pub fn popOrNull(self: *Self) ?T { |
| 336 | 368 | if (self.items.len == 0) return null; |
| 337 | 369 | return self.pop(); |
| 338 | 370 | } |
| 339 | 371 | |
| 340 | 372 | /// Returns a slice of all the items plus the extra capacity, whose memory |
| 341 | | /// contents are undefined. |
| 373 | /// contents are `undefined`. |
| 342 | 374 | pub fn allocatedSlice(self: Self) Slice { |
| 343 | 375 | // For a nicer API, `items.len` is the length, not the capacity. |
| 344 | 376 | // This requires "unsafe" slicing. |
| ... | ... | @@ -346,7 +378,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 346 | 378 | } |
| 347 | 379 | |
| 348 | 380 | /// Returns a slice of only the extra capacity after items. |
| 349 | | /// This can be useful for writing directly into an `ArrayList`. |
| 381 | /// This can be useful for writing directly into an ArrayList. |
| 350 | 382 | /// Note that such an operation must be followed up with a direct |
| 351 | 383 | /// modification of `self.items.len`. |
| 352 | 384 | pub fn unusedCapacitySlice(self: Self) Slice { |
| ... | ... | @@ -355,12 +387,18 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 355 | 387 | }; |
| 356 | 388 | } |
| 357 | 389 | |
| 358 | | /// Bring-your-own allocator with every function call. |
| 359 | | /// Initialize directly and deinitialize with `deinit` or use `toOwnedSlice`. |
| 390 | /// An ArrayList, but the allocator is passed as a parameter to the relevant functions |
| 391 | /// rather than stored in the struct itself. The same allocator **must** be used throughout |
| 392 | /// the entire lifetime of an ArrayListUnmanaged. Initialize directly or with |
| 393 | /// `initCapacity`, and deinitialize with `deinit` or use `toOwnedSlice`. |
| 360 | 394 | pub fn ArrayListUnmanaged(comptime T: type) type { |
| 361 | 395 | return ArrayListAlignedUnmanaged(T, null); |
| 362 | 396 | } |
| 363 | 397 | |
| 398 | /// An ArrayListAligned, but the allocator is passed as a parameter to the relevant |
| 399 | /// functions rather than stored in the struct itself. The same allocator **must** |
| 400 | /// be used throughout the entire lifetime of an ArrayListAlignedUnmanaged. |
| 401 | /// Initialize directly or with `initCapacity`, and deinitialize with `deinit` or use `toOwnedSlice`. |
| 364 | 402 | pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) type { |
| 365 | 403 | if (alignment) |a| { |
| 366 | 404 | if (a == @alignOf(T)) { |
| ... | ... | @@ -369,9 +407,18 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 369 | 407 | } |
| 370 | 408 | return struct { |
| 371 | 409 | const Self = @This(); |
| 372 | | |
| 373 | | /// Content of the ArrayList. |
| 410 | /// Contents of the list. Pointers to elements in this slice are |
| 411 | /// **invalid after resizing operations** on the ArrayList, unless the |
| 412 | /// operation explicitly either: (1) states otherwise or (2) lists the |
| 413 | /// invalidated pointers. |
| 414 | /// |
| 415 | /// The allocator used determines how element pointers are |
| 416 | /// invalidated, so the behavior may vary between lists. To avoid |
| 417 | /// illegal behavior, take into account the above paragraph plus the |
| 418 | /// explicit statements given in each method. |
| 374 | 419 | items: Slice = &[_]T{}, |
| 420 | /// How many T values this list can hold without allocating |
| 421 | /// additional memory. |
| 375 | 422 | capacity: usize = 0, |
| 376 | 423 | |
| 377 | 424 | pub const Slice = if (alignment) |a| ([]align(a) T) else []T; |
| ... | ... | @@ -395,6 +442,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 395 | 442 | self.* = undefined; |
| 396 | 443 | } |
| 397 | 444 | |
| 445 | /// Convert this list into an analogous memory-managed one. |
| 446 | /// The returned list has ownership of the underlying memory. |
| 398 | 447 | pub fn toManaged(self: *Self, allocator: *Allocator) ArrayListAligned(T, alignment) { |
| 399 | 448 | return .{ .items = self.items, .capacity = self.capacity, .allocator = allocator }; |
| 400 | 449 | } |
| ... | ... | @@ -414,7 +463,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 414 | 463 | } |
| 415 | 464 | |
| 416 | 465 | /// Insert `item` at index `n`. Moves `list[n .. list.len]` |
| 417 | | /// to make room. |
| 466 | /// to higher indices to make room. |
| 467 | /// This operation is O(N). |
| 418 | 468 | pub fn insert(self: *Self, allocator: *Allocator, n: usize, item: T) !void { |
| 419 | 469 | try self.ensureCapacity(allocator, self.items.len + 1); |
| 420 | 470 | self.items.len += 1; |
| ... | ... | @@ -423,8 +473,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 423 | 473 | self.items[n] = item; |
| 424 | 474 | } |
| 425 | 475 | |
| 426 | | /// Insert slice `items` at index `i`. Moves |
| 427 | | /// `list[i .. list.len]` to make room. |
| 476 | /// Insert slice `items` at index `i`. Moves `list[i .. list.len]` to |
| 477 | /// higher indicices make room. |
| 428 | 478 | /// This operation is O(N). |
| 429 | 479 | pub fn insertSlice(self: *Self, allocator: *Allocator, i: usize, items: SliceConst) !void { |
| 430 | 480 | try self.ensureCapacity(allocator, self.items.len + items.len); |
| ... | ... | @@ -435,8 +485,9 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 435 | 485 | } |
| 436 | 486 | |
| 437 | 487 | /// Replace range of elements `list[start..start+len]` with `new_items` |
| 438 | | /// grows list if `len < new_items.len`. may allocate |
| 439 | | /// shrinks list if `len > new_items.len` |
| 488 | /// Grows list if `len < new_items.len`. |
| 489 | /// Shrinks list if `len > new_items.len` |
| 490 | /// Invalidates pointers if this ArrayList is resized. |
| 440 | 491 | pub fn replaceRange(self: *Self, allocator: *Allocator, start: usize, len: usize, new_items: SliceConst) !void { |
| 441 | 492 | var managed = self.toManaged(allocator); |
| 442 | 493 | try managed.replaceRange(start, len, new_items); |
| ... | ... | @@ -457,7 +508,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 457 | 508 | } |
| 458 | 509 | |
| 459 | 510 | /// Remove the element at index `i` from the list and return its value. |
| 460 | | /// Asserts the array has at least one item. |
| 511 | /// Asserts the array has at least one item. Invalidates pointers to |
| 512 | /// last element. |
| 461 | 513 | /// This operation is O(N). |
| 462 | 514 | pub fn orderedRemove(self: *Self, i: usize) T { |
| 463 | 515 | const newlen = self.items.len - 1; |
| ... | ... | @@ -472,6 +524,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 472 | 524 | |
| 473 | 525 | /// Removes the element at the specified index and returns it. |
| 474 | 526 | /// The empty slot is filled from the end of the list. |
| 527 | /// Invalidates pointers to last element. |
| 475 | 528 | /// This operation is O(1). |
| 476 | 529 | pub fn swapRemove(self: *Self, i: usize) T { |
| 477 | 530 | if (self.items.len - 1 == i) return self.pop(); |
| ... | ... | @@ -515,6 +568,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 515 | 568 | } |
| 516 | 569 | |
| 517 | 570 | /// Append a value to the list `n` times. |
| 571 | /// **Does not** invalidate pointers. |
| 518 | 572 | /// Asserts the capacity is enough. |
| 519 | 573 | pub fn appendNTimesAssumeCapacity(self: *Self, value: T, n: usize) void { |
| 520 | 574 | const new_len = self.items.len + n; |
| ... | ... | @@ -524,14 +578,13 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 524 | 578 | } |
| 525 | 579 | |
| 526 | 580 | /// Adjust the list's length to `new_len`. |
| 527 | | /// Does not initialize added items if any. |
| 581 | /// Does not initialize added items, if any. |
| 528 | 582 | pub fn resize(self: *Self, allocator: *Allocator, new_len: usize) !void { |
| 529 | 583 | try self.ensureCapacity(allocator, new_len); |
| 530 | 584 | self.items.len = new_len; |
| 531 | 585 | } |
| 532 | 586 | |
| 533 | 587 | /// Reduce allocated capacity to `new_len`. |
| 534 | | /// Invalidates element pointers. |
| 535 | 588 | pub fn shrink(self: *Self, allocator: *Allocator, new_len: usize) void { |
| 536 | 589 | assert(new_len <= self.items.len); |
| 537 | 590 | |
| ... | ... | @@ -545,13 +598,15 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 545 | 598 | } |
| 546 | 599 | |
| 547 | 600 | /// Reduce length to `new_len`. |
| 548 | | /// Invalidates element pointers. |
| 601 | /// Invalidates pointers to elements `items[new_len..]`. |
| 549 | 602 | /// Keeps capacity the same. |
| 550 | 603 | pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void { |
| 551 | 604 | assert(new_len <= self.items.len); |
| 552 | 605 | self.items.len = new_len; |
| 553 | 606 | } |
| 554 | 607 | |
| 608 | /// Modify the array so that it can hold at least `new_capacity` items. |
| 609 | /// Invalidates pointers if additional memory is needed. |
| 555 | 610 | pub fn ensureCapacity(self: *Self, allocator: *Allocator, new_capacity: usize) !void { |
| 556 | 611 | var better_capacity = self.capacity; |
| 557 | 612 | if (better_capacity >= new_capacity) return; |
| ... | ... | @@ -568,13 +623,13 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 568 | 623 | |
| 569 | 624 | /// Increases the array's length to match the full capacity that is already allocated. |
| 570 | 625 | /// The new elements have `undefined` values. |
| 571 | | /// This operation does not invalidate any element pointers. |
| 626 | /// **Does not** invalidate pointers. |
| 572 | 627 | pub fn expandToCapacity(self: *Self) void { |
| 573 | 628 | self.items.len = self.capacity; |
| 574 | 629 | } |
| 575 | 630 | |
| 576 | 631 | /// Increase length by 1, returning pointer to the new item. |
| 577 | | /// The returned pointer becomes invalid when the list is resized. |
| 632 | /// The returned pointer becomes invalid when the list resized. |
| 578 | 633 | pub fn addOne(self: *Self, allocator: *Allocator) !*T { |
| 579 | 634 | const newlen = self.items.len + 1; |
| 580 | 635 | try self.ensureCapacity(allocator, newlen); |
| ... | ... | @@ -583,8 +638,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 583 | 638 | |
| 584 | 639 | /// Increase length by 1, returning pointer to the new item. |
| 585 | 640 | /// Asserts that there is already space for the new item without allocating more. |
| 586 | | /// The returned pointer becomes invalid when the list is resized. |
| 587 | | /// This operation does not invalidate any element pointers. |
| 641 | /// **Does not** invalidate pointers. |
| 642 | /// The returned pointer becomes invalid when the list resized. |
| 588 | 643 | pub fn addOneAssumeCapacity(self: *Self) *T { |
| 589 | 644 | assert(self.items.len < self.capacity); |
| 590 | 645 | |
| ... | ... | @@ -594,6 +649,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 594 | 649 | |
| 595 | 650 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 596 | 651 | /// The return value is an array pointing to the newly allocated elements. |
| 652 | /// The returned pointer becomes invalid when the list is resized. |
| 597 | 653 | pub fn addManyAsArray(self: *Self, allocator: *Allocator, comptime n: usize) !*[n]T { |
| 598 | 654 | const prev_len = self.items.len; |
| 599 | 655 | try self.resize(allocator, self.items.len + n); |
| ... | ... | @@ -603,6 +659,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 603 | 659 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 604 | 660 | /// The return value is an array pointing to the newly allocated elements. |
| 605 | 661 | /// Asserts that there is already space for the new item without allocating more. |
| 662 | /// **Does not** invalidate pointers. |
| 663 | /// The returned pointer becomes invalid when the list is resized. |
| 606 | 664 | pub fn addManyAsArrayAssumeCapacity(self: *Self, comptime n: usize) *[n]T { |
| 607 | 665 | assert(self.items.len + n <= self.capacity); |
| 608 | 666 | const prev_len = self.items.len; |
| ... | ... | @@ -612,7 +670,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 612 | 670 | |
| 613 | 671 | /// Remove and return the last element from the list. |
| 614 | 672 | /// Asserts the list has at least one item. |
| 615 | | /// This operation does not invalidate any element pointers. |
| 673 | /// Invalidates pointers to last element. |
| 616 | 674 | pub fn pop(self: *Self) T { |
| 617 | 675 | const val = self.items[self.items.len - 1]; |
| 618 | 676 | self.items.len -= 1; |
| ... | ... | @@ -621,7 +679,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 621 | 679 | |
| 622 | 680 | /// Remove and return the last element from the list. |
| 623 | 681 | /// If the list is empty, returns `null`. |
| 624 | | /// This operation does not invalidate any element pointers. |
| 682 | /// Invalidates pointers to last element. |
| 625 | 683 | pub fn popOrNull(self: *Self) ?T { |
| 626 | 684 | if (self.items.len == 0) return null; |
| 627 | 685 | return self.pop(); |