Skip to content

Commit

Permalink
fix std.fmt to handle std.SegmentedList
Browse files Browse the repository at this point in the history
- add guards for use of prealloc_exp in SegmentedList
- define prealloc_exp even when invalid because std.fmt comptime
  triggers lazy-init
- fix std.fmt to print arrays of length 0 as style "[0]<typename>"
  because "<typename>@address" is n/a without address
  • Loading branch information
mikdusan authored and andrewrk committed Jul 29, 2019
1 parent 8736a5b commit bc982e6
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
3 changes: 3 additions & 0 deletions std/fmt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,9 @@ pub fn formatType(
if (info.child == u8) {
return formatText(value, fmt, options, context, Errors, output);
}
if (value.len == 0) {
return format(context, Errors, output, "[0]{}", @typeName(T.Child));
}
return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value));
},
.Fn => {
Expand Down
29 changes: 18 additions & 11 deletions std/segmented_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,19 @@ const Allocator = std.mem.Allocator;
pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type {
return struct {
const Self = @This();
const prealloc_exp = blk: {
// we don't use the prealloc_exp constant when prealloc_item_count is 0.
assert(prealloc_item_count != 0);
assert(std.math.isPowerOfTwo(prealloc_item_count));
const ShelfIndex = std.math.Log2Int(usize);

const value = std.math.log2_int(usize, prealloc_item_count);
break :blk @typeOf(1)(value);
const prealloc_exp: ShelfIndex = blk: {
// we don't use the prealloc_exp constant when prealloc_item_count is 0
// but lazy-init may still be triggered by other code so supply a value
if (prealloc_item_count == 0) {
break :blk 0;
} else {
assert(std.math.isPowerOfTwo(prealloc_item_count));
const value = std.math.log2_int(usize, prealloc_item_count);
break :blk value;
}
};
const ShelfIndex = std.math.Log2Int(usize);

prealloc_segment: [prealloc_item_count]T,
dynamic_segments: [][*]T,
Expand Down Expand Up @@ -157,11 +161,12 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type

/// Grows or shrinks capacity to match usage.
pub fn setCapacity(self: *Self, new_capacity: usize) !void {
if (new_capacity <= usize(1) << (prealloc_exp + self.dynamic_segments.len)) {
return self.shrinkCapacity(new_capacity);
} else {
return self.growCapacity(new_capacity);
if (prealloc_item_count != 0) {
if (new_capacity <= usize(1) << (prealloc_exp + @intCast(ShelfIndex, self.dynamic_segments.len))) {
return self.shrinkCapacity(new_capacity);
}
}
return self.growCapacity(new_capacity);
}

/// Only grows capacity, or retains current capacity
Expand Down Expand Up @@ -399,4 +404,6 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void {
testing.expect(item == i);
list.shrinkCapacity(list.len);
}

try list.setCapacity(0);
}

0 comments on commit bc982e6

Please sign in to comment.