Commit 19a04d8ebd
Changed files (1)
lib
lib/std/segmented_list.zig
@@ -213,6 +213,34 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
self.len = new_len;
}
+ pub fn writeToSlice(self: *Self, dest: []T, start: usize) void {
+ const end = start + dest.len;
+ assert(end <= self.len);
+
+ var i = start;
+ if (end <= prealloc_item_count) {
+ std.mem.copy(T, dest[i - start ..], self.prealloc_segment[i..end]);
+ return;
+ } else if (i < prealloc_item_count) {
+ std.mem.copy(T, dest[i - start ..], self.prealloc_segment[i..]);
+ i = prealloc_item_count;
+ }
+
+ while (i < end) {
+ const shelf_index = shelfIndex(i);
+ const copy_start = boxIndex(i, shelf_index);
+ const copy_end = std.math.min(shelfSize(shelf_index), copy_start + end - i);
+
+ std.mem.copy(
+ T,
+ dest[i - start ..],
+ self.dynamic_segments[shelf_index][copy_start..copy_end],
+ );
+
+ i += (copy_end - copy_start);
+ }
+ }
+
pub fn uncheckedAt(self: var, index: usize) AtType(@TypeOf(self)) {
if (index < prealloc_item_count) {
return &self.prealloc_segment[index];
@@ -395,10 +423,31 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void {
try list.pushMany(&[_]i32{});
testing.expect(list.len == 99);
- var i: i32 = 99;
- while (list.pop()) |item| : (i -= 1) {
- testing.expect(item == i);
- list.shrinkCapacity(list.len);
+ {
+ var i: i32 = 99;
+ while (list.pop()) |item| : (i -= 1) {
+ testing.expect(item == i);
+ list.shrinkCapacity(list.len);
+ }
+ }
+
+ {
+ var control: [100]i32 = undefined;
+ var dest: [100]i32 = undefined;
+
+ var i: i32 = 0;
+ while (i < 100) : (i += 1) {
+ try list.push(i + 1);
+ control[@intCast(usize, i)] = i + 1;
+ }
+
+ std.mem.set(i32, dest[0..], 0);
+ list.writeToSlice(dest[0..], 0);
+ testing.expect(std.mem.eql(i32, control[0..], dest[0..]));
+
+ std.mem.set(i32, dest[0..], 0);
+ list.writeToSlice(dest[50..], 50);
+ testing.expect(std.mem.eql(i32, control[50..], dest[50..]));
}
try list.setCapacity(0);