@@ -66,16 +66,23 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
66
66
pub fn initCapacity (allocator : * Allocator , num : usize ) ! Self {
67
67
var self = Self .init (allocator );
68
68
69
- const new_memory = try self .allocator .allocAdvanced (T , alignment , num , .at_least );
70
- self .items .ptr = new_memory .ptr ;
71
- self .capacity = new_memory .len ;
69
+ if (@sizeOf (T ) > 0 ) {
70
+ const new_memory = try self .allocator .allocAdvanced (T , alignment , num , .at_least );
71
+ self .items .ptr = new_memory .ptr ;
72
+ self .capacity = new_memory .len ;
73
+ } else {
74
+ // If `T` is a zero-sized type, then we do not need to allocate memory.
75
+ self .capacity = std .math .maxInt (usize );
76
+ }
72
77
73
78
return self ;
74
79
}
75
80
76
81
/// Release all allocated memory.
77
82
pub fn deinit (self : Self ) void {
78
- self .allocator .free (self .allocatedSlice ());
83
+ if (@sizeOf (T ) > 0 ) {
84
+ self .allocator .free (self .allocatedSlice ());
85
+ }
79
86
}
80
87
81
88
pub const span = @compileError ("deprecated: use `items` field directly" );
@@ -279,13 +286,17 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
279
286
pub fn shrinkAndFree (self : * Self , new_len : usize ) void {
280
287
assert (new_len <= self .items .len );
281
288
282
- self .items = self .allocator .realloc (self .allocatedSlice (), new_len ) catch | e | switch (e ) {
283
- error .OutOfMemory = > { // no problem, capacity is still correct then.
284
- self .items .len = new_len ;
285
- return ;
286
- },
287
- };
288
- self .capacity = new_len ;
289
+ if (@sizeOf (T ) > 0 ) {
290
+ self .items = self .allocator .realloc (self .allocatedSlice (), new_len ) catch | e | switch (e ) {
291
+ error .OutOfMemory = > { // no problem, capacity is still correct then.
292
+ self .items .len = new_len ;
293
+ return ;
294
+ },
295
+ };
296
+ self .capacity = new_len ;
297
+ } else {
298
+ self .items .len = new_len ;
299
+ }
289
300
}
290
301
291
302
/// Reduce length to `new_len`.
@@ -298,18 +309,22 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
298
309
/// Modify the array so that it can hold at least `new_capacity` items.
299
310
/// Invalidates pointers if additional memory is needed.
300
311
pub fn ensureCapacity (self : * Self , new_capacity : usize ) ! void {
301
- var better_capacity = self .capacity ;
302
- if (better_capacity >= new_capacity ) return ;
312
+ if (@sizeOf (T ) > 0 ) {
313
+ var better_capacity = self .capacity ;
314
+ if (better_capacity >= new_capacity ) return ;
303
315
304
- while (true ) {
305
- better_capacity += better_capacity / 2 + 8 ;
306
- if (better_capacity >= new_capacity ) break ;
307
- }
316
+ while (true ) {
317
+ better_capacity += better_capacity / 2 + 8 ;
318
+ if (better_capacity >= new_capacity ) break ;
319
+ }
308
320
309
- // TODO This can be optimized to avoid needlessly copying undefined memory.
310
- const new_memory = try self .allocator .reallocAtLeast (self .allocatedSlice (), better_capacity );
311
- self .items .ptr = new_memory .ptr ;
312
- self .capacity = new_memory .len ;
321
+ // TODO This can be optimized to avoid needlessly copying undefined memory.
322
+ const new_memory = try self .allocator .reallocAtLeast (self .allocatedSlice (), better_capacity );
323
+ self .items .ptr = new_memory .ptr ;
324
+ self .capacity = new_memory .len ;
325
+ } else {
326
+ self .capacity = std .math .maxInt (usize );
327
+ }
313
328
}
314
329
315
330
/// Increases the array's length to match the full capacity that is already allocated.
@@ -1226,3 +1241,23 @@ test "std.ArrayList/ArrayListUnmanaged.toOwnedSliceSentinel" {
1226
1241
testing .expectEqualStrings (result , mem .spanZ (result .ptr ));
1227
1242
}
1228
1243
}
1244
+
1245
+ test "std.ArrayList(u0)" {
1246
+ // An ArrayList on zero-sized types should not need to allocate
1247
+ const a = & testing .FailingAllocator .init (testing .allocator , 0 ).allocator ;
1248
+
1249
+ var list = ArrayList (u0 ).init (a );
1250
+ defer list .deinit ();
1251
+
1252
+ try list .append (0 );
1253
+ try list .append (0 );
1254
+ try list .append (0 );
1255
+ testing .expectEqual (list .items .len , 3 );
1256
+
1257
+ var count : usize = 0 ;
1258
+ for (list .items ) | x | {
1259
+ testing .expectEqual (x , 0 );
1260
+ count += 1 ;
1261
+ }
1262
+ testing .expectEqual (count , 3 );
1263
+ }
0 commit comments