| ... | @@ -213,6 +213,34 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type | ... | @@ -213,6 +213,34 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type |
| 213 | self.len = new_len; | 213 | self.len = new_len; |
| 214 | } | 214 | } |
| 215 | | 215 | |
| | 216 | pub fn writeToSlice(self: *Self, dest: []T, start: usize) void { |
| | 217 | const end = start + dest.len; |
| | 218 | assert(end <= self.len); |
| | 219 | |
| | 220 | var i = start; |
| | 221 | if (end <= prealloc_item_count) { |
| | 222 | std.mem.copy(T, dest[i - start ..], self.prealloc_segment[i..end]); |
| | 223 | return; |
| | 224 | } else if (i < prealloc_item_count) { |
| | 225 | std.mem.copy(T, dest[i - start ..], self.prealloc_segment[i..]); |
| | 226 | i = prealloc_item_count; |
| | 227 | } |
| | 228 | |
| | 229 | while (i < end) { |
| | 230 | const shelf_index = shelfIndex(i); |
| | 231 | const copy_start = boxIndex(i, shelf_index); |
| | 232 | const copy_end = std.math.min(shelfSize(shelf_index), copy_start + end - i); |
| | 233 | |
| | 234 | std.mem.copy( |
| | 235 | T, |
| | 236 | dest[i - start ..], |
| | 237 | self.dynamic_segments[shelf_index][copy_start..copy_end], |
| | 238 | ); |
| | 239 | |
| | 240 | i += (copy_end - copy_start); |
| | 241 | } |
| | 242 | } |
| | 243 | |
| 216 | pub fn uncheckedAt(self: var, index: usize) AtType(@TypeOf(self)) { | 244 | pub fn uncheckedAt(self: var, index: usize) AtType(@TypeOf(self)) { |
| 217 | if (index < prealloc_item_count) { | 245 | if (index < prealloc_item_count) { |
| 218 | return &self.prealloc_segment[index]; | 246 | return &self.prealloc_segment[index]; |
| ... | @@ -395,10 +423,31 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void { | ... | @@ -395,10 +423,31 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void { |
| 395 | try list.pushMany(&[_]i32{}); | 423 | try list.pushMany(&[_]i32{}); |
| 396 | testing.expect(list.len == 99); | 424 | testing.expect(list.len == 99); |
| 397 | | 425 | |
| 398 | var i: i32 = 99; | 426 | { |
| 399 | while (list.pop()) |item| : (i -= 1) { | 427 | var i: i32 = 99; |
| 400 | testing.expect(item == i); | 428 | while (list.pop()) |item| : (i -= 1) { |
| 401 | list.shrinkCapacity(list.len); | 429 | testing.expect(item == i); |
| | 430 | list.shrinkCapacity(list.len); |
| | 431 | } |
| | 432 | } |
| | 433 | |
| | 434 | { |
| | 435 | var control: [100]i32 = undefined; |
| | 436 | var dest: [100]i32 = undefined; |
| | 437 | |
| | 438 | var i: i32 = 0; |
| | 439 | while (i < 100) : (i += 1) { |
| | 440 | try list.push(i + 1); |
| | 441 | control[@intCast(usize, i)] = i + 1; |
| | 442 | } |
| | 443 | |
| | 444 | std.mem.set(i32, dest[0..], 0); |
| | 445 | list.writeToSlice(dest[0..], 0); |
| | 446 | testing.expect(std.mem.eql(i32, control[0..], dest[0..])); |
| | 447 | |
| | 448 | std.mem.set(i32, dest[0..], 0); |
| | 449 | list.writeToSlice(dest[50..], 50); |
| | 450 | testing.expect(std.mem.eql(i32, control[50..], dest[50..])); |
| 402 | } | 451 | } |
| 403 | | 452 | |
| 404 | try list.setCapacity(0); | 453 | try list.setCapacity(0); |