@@ -5,10 +5,8 @@ const testing = std.testing;
5
5
const mem = std .mem ;
6
6
const Allocator = mem .Allocator ;
7
7
8
- /// List of items.
9
- ///
10
- /// This is a wrapper around an array of T values. Initialize with
11
- /// `init`.
8
+ /// A contiguous, growable list of items in memory.
9
+ /// This is a wrapper around an array of T values. Initialize with `init`.
12
10
pub fn ArrayList (comptime T : type ) type {
13
11
return AlignedArrayList (T , null );
14
12
}
@@ -22,7 +20,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
22
20
return struct {
23
21
const Self = @This ();
24
22
25
- /// Use toSlice instead of slicing this directly, because if you don't
23
+ /// Use `span` instead of slicing this directly, because if you don't
26
24
/// specify the end position of the slice, this will potentially give
27
25
/// you uninitialized memory.
28
26
items : Slice ,
@@ -56,34 +54,37 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
56
54
57
55
/// Return contents as a slice. Only valid while the list
58
56
/// doesn't change size.
59
- pub fn toSlice (self : Self ) Slice {
57
+ pub fn span (self : var ) @TypeOf ( self . items [0 .. self . len ]) {
60
58
return self .items [0.. self .len ];
61
59
}
62
60
63
- /// Return list as const slice. Only valid while the list
64
- /// doesn't change size.
61
+ /// Deprecated: use `span`.
62
+ pub fn toSlice (self : Self ) Slice {
63
+ return self .span ();
64
+ }
65
+
66
+ /// Deprecated: use `span`.
65
67
pub fn toSliceConst (self : Self ) SliceConst {
66
- return self .items [0 .. self . len ] ;
68
+ return self .span () ;
67
69
}
68
70
69
- /// Safely access index i of the list .
71
+ /// Deprecated: use `span()[i]` .
70
72
pub fn at (self : Self , i : usize ) T {
71
- return self .toSliceConst ()[i ];
73
+ return self .span ()[i ];
72
74
}
73
75
74
- /// Safely access ptr to index i of the list .
76
+ /// Deprecated: use `&span()[i]` .
75
77
pub fn ptrAt (self : Self , i : usize ) * T {
76
- return & self .toSlice ()[i ];
78
+ return & self .span ()[i ];
77
79
}
78
80
79
- /// Sets the value at index `i`, or returns `error.OutOfBounds` if
80
- /// the index is not in range.
81
+ /// Deprecated: use `if (i >= list.len) return error.OutOfBounds else span()[i] = item`.
81
82
pub fn setOrError (self : Self , i : usize , item : T ) ! void {
82
83
if (i >= self .len ) return error .OutOfBounds ;
83
84
self .items [i ] = item ;
84
85
}
85
86
86
- /// Sets the value at index `i`, asserting that the value is in range .
87
+ /// Deprecated: use `list.span()[i] = item` .
87
88
pub fn set (self : * Self , i : usize , item : T ) void {
88
89
assert (i < self .len );
89
90
self .items [i ] = item ;
@@ -124,18 +125,18 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
124
125
self .items [n ] = item ;
125
126
}
126
127
127
- /// Insert slice `items` at index `n`. Moves
128
- /// `list[n .. list.len]` to make room.
129
- pub fn insertSlice (self : * Self , n : usize , items : SliceConst ) ! void {
128
+ /// Insert slice `items` at index `i`. Moves
129
+ /// `list[i .. list.len]` to make room.
130
+ /// This operation is O(N).
131
+ pub fn insertSlice (self : * Self , i : usize , items : SliceConst ) ! void {
130
132
try self .ensureCapacity (self .len + items .len );
131
133
self .len += items .len ;
132
134
133
- mem .copyBackwards (T , self .items [n + items .len .. self .len ], self .items [n .. self .len - items .len ]);
134
- mem .copy (T , self .items [n .. n + items .len ], items );
135
+ mem .copyBackwards (T , self .items [i + items .len .. self .len ], self .items [i .. self .len - items .len ]);
136
+ mem .copy (T , self .items [i .. i + items .len ], items );
135
137
}
136
138
137
- /// Extend the list by 1 element. Allocates more memory as
138
- /// necessary.
139
+ /// Extend the list by 1 element. Allocates more memory as necessary.
139
140
pub fn append (self : * Self , item : T ) ! void {
140
141
const new_item_ptr = try self .addOne ();
141
142
new_item_ptr .* = item ;
@@ -148,8 +149,9 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
148
149
new_item_ptr .* = item ;
149
150
}
150
151
151
- /// Remove the element at index `i` from the list and return
152
- /// its value. Asserts the array has at least one item.
152
+ /// Remove the element at index `i` from the list and return its value.
153
+ /// Asserts the array has at least one item.
154
+ /// This operation is O(N).
153
155
pub fn orderedRemove (self : * Self , i : usize ) T {
154
156
const newlen = self .len - 1 ;
155
157
if (newlen == i ) return self .pop ();
@@ -163,18 +165,17 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
163
165
164
166
/// Removes the element at the specified index and returns it.
165
167
/// The empty slot is filled from the end of the list.
168
+ /// This operation is O(1).
166
169
pub fn swapRemove (self : * Self , i : usize ) T {
167
170
if (self .len - 1 == i ) return self .pop ();
168
171
169
- const slice = self .toSlice ();
172
+ const slice = self .span ();
170
173
const old_item = slice [i ];
171
174
slice [i ] = self .pop ();
172
175
return old_item ;
173
176
}
174
177
175
- /// Removes the element at the specified index and returns it
176
- /// or an error.OutOfBounds is returned. If no error then
177
- /// the empty slot is filled from the end of the list.
178
+ /// Deprecated: use `if (i >= list.len) return error.OutOfBounds else list.swapRemove(i)`.
178
179
pub fn swapRemoveOrError (self : * Self , i : usize ) ! T {
179
180
if (i >= self .len ) return error .OutOfBounds ;
180
181
return self .swapRemove (i );
@@ -204,6 +205,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
204
205
}
205
206
206
207
/// Reduce allocated capacity to `new_len`.
208
+ /// Invalidates element pointers.
207
209
pub fn shrink (self : * Self , new_len : usize ) void {
208
210
assert (new_len <= self .len );
209
211
self .len = new_len ;
@@ -222,28 +224,40 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
222
224
self .items = try self .allocator .realloc (self .items , better_capacity );
223
225
}
224
226
227
+ /// Increases the array's length to match the full capacity that is already allocated.
228
+ /// The new elements have `undefined` values. This operation does not invalidate any
229
+ /// element pointers.
230
+ pub fn expandToCapacity (self : * Self ) void {
231
+ self .len = self .items .len ;
232
+ }
233
+
225
234
/// Increase length by 1, returning pointer to the new item.
235
+ /// The returned pointer becomes invalid when the list is resized.
226
236
pub fn addOne (self : * Self ) ! * T {
227
237
const new_length = self .len + 1 ;
228
238
try self .ensureCapacity (new_length );
229
239
return self .addOneAssumeCapacity ();
230
240
}
231
241
242
+ /// Increase length by 1, returning pointer to the new item.
243
+ /// Asserts that there is already space for the new item without allocating more.
244
+ /// The returned pointer becomes invalid when the list is resized.
232
245
pub fn addOneAssumeCapacity (self : * Self ) * T {
233
246
assert (self .len < self .capacity ());
234
247
const result = & self .items [self .len ];
235
248
self .len += 1 ;
236
249
return result ;
237
250
}
238
251
239
- /// Remove and return the last element from the list. Asserts
240
- /// the list has at least one item.
252
+ /// Remove and return the last element from the list.
253
+ /// Asserts the list has at least one item.
241
254
pub fn pop (self : * Self ) T {
242
255
self .len -= 1 ;
243
256
return self .items [self .len ];
244
257
}
245
258
246
- /// Like `pop` but returns `null` if empty.
259
+ /// Remove and return the last element from the list.
260
+ /// If the list is empty, returns `null`.
247
261
pub fn popOrNull (self : * Self ) ? T {
248
262
if (self .len == 0 ) return null ;
249
263
return self .pop ();
@@ -287,7 +301,7 @@ test "std.ArrayList.basic" {
287
301
}
288
302
}
289
303
290
- for (list .toSlice ()) | v , i | {
304
+ for (list .span ()) | v , i | {
291
305
testing .expect (v == @intCast (i32 , i + 1 ));
292
306
}
293
307
@@ -325,7 +339,7 @@ test "std.ArrayList.appendNTimes" {
325
339
326
340
try list .appendNTimes (2 , 10 );
327
341
testing .expectEqual (@as (usize , 10 ), list .len );
328
- for (list .toSlice ()) | element | {
342
+ for (list .span ()) | element | {
329
343
testing .expectEqual (@as (i32 , 2 ), element );
330
344
}
331
345
}
0 commit comments