From 19a04d8ebd4d671a7f461048555831a629243b49 Mon Sep 17 00:00:00 2001 From: Walter Mays Date: Tue, 26 May 2020 12:04:25 -0500 Subject: [PATCH] Add `writeToSlice` method to SegmentedList. (#5405) --- lib/std/segmented_list.zig | 57 +++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/lib/std/segmented_list.zig b/lib/std/segmented_list.zig index d7d137175c..d087e480f6 100644 --- a/lib/std/segmented_list.zig +++ b/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);