@@ -65,16 +65,23 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
65
65
pub fn initCapacity (allocator : * Allocator , num : usize ) ! Self {
66
66
var self = Self .init (allocator );
67
67
68
- const new_memory = try self .allocator .allocAdvanced (T , alignment , num , .at_least );
69
- self .items .ptr = new_memory .ptr ;
70
- self .capacity = new_memory .len ;
68
+ if (@sizeOf (T ) > 0 ) {
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 ;
72
+ } else {
73
+ // If `T` is a zero-sized type, then we do not need to allocate memory.
74
+ self .capacity = std .math .maxInt (usize );
75
+ }
71
76
72
77
return self ;
73
78
}
74
79
75
80
/// Release all allocated memory.
76
81
pub fn deinit (self : Self ) void {
77
- self .allocator .free (self .allocatedSlice ());
82
+ if (@sizeOf (T ) > 0 ) {
83
+ self .allocator .free (self .allocatedSlice ());
84
+ }
78
85
}
79
86
80
87
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`.
@@ -313,18 +324,22 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
313
324
/// Modify the array so that it can hold at least `new_capacity` items.
314
325
/// Invalidates pointers if additional memory is needed.
315
326
pub fn ensureTotalCapacity (self : * Self , new_capacity : usize ) ! void {
316
- var better_capacity = self .capacity ;
317
- if (better_capacity >= new_capacity ) return ;
327
+ if (@sizeOf (T ) > 0 ) {
328
+ var better_capacity = self .capacity ;
329
+ if (better_capacity >= new_capacity ) return ;
318
330
319
- while (true ) {
320
- better_capacity += better_capacity / 2 + 8 ;
321
- if (better_capacity >= new_capacity ) break ;
322
- }
331
+ while (true ) {
332
+ better_capacity += better_capacity / 2 + 8 ;
333
+ if (better_capacity >= new_capacity ) break ;
334
+ }
323
335
324
- // TODO This can be optimized to avoid needlessly copying undefined memory.
325
- const new_memory = try self .allocator .reallocAtLeast (self .allocatedSlice (), better_capacity );
326
- self .items .ptr = new_memory .ptr ;
327
- self .capacity = new_memory .len ;
336
+ // TODO This can be optimized to avoid needlessly copying undefined memory.
337
+ const new_memory = try self .allocator .reallocAtLeast (self .allocatedSlice (), better_capacity );
338
+ self .items .ptr = new_memory .ptr ;
339
+ self .capacity = new_memory .len ;
340
+ } else {
341
+ self .capacity = std .math .maxInt (usize );
342
+ }
328
343
}
329
344
330
345
/// Modify the array so that it can hold at least `additional_count` **more** items.
@@ -1299,3 +1314,23 @@ test "ArrayListAligned/ArrayListAlignedUnmanaged accepts unaligned slices" {
1299
1314
try testing .expectEqualSlices (u8 , list .items , &.{ 0 , 8 , 9 , 6 , 7 , 2 , 3 });
1300
1315
}
1301
1316
}
1317
+
1318
+ test "std.ArrayList(u0)" {
1319
+ // An ArrayList on zero-sized types should not need to allocate
1320
+ const a = & testing .FailingAllocator .init (testing .allocator , 0 ).allocator ;
1321
+
1322
+ var list = ArrayList (u0 ).init (a );
1323
+ defer list .deinit ();
1324
+
1325
+ try list .append (0 );
1326
+ try list .append (0 );
1327
+ try list .append (0 );
1328
+ try testing .expectEqual (list .items .len , 3 );
1329
+
1330
+ var count : usize = 0 ;
1331
+ for (list .items ) | x | {
1332
+ try testing .expectEqual (x , 0 );
1333
+ count += 1 ;
1334
+ }
1335
+ try testing .expectEqual (count , 3 );
1336
+ }
0 commit comments