| ... | ... | @@ -213,6 +213,34 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type |
| 213 | 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 | 244 | pub fn uncheckedAt(self: var, index: usize) AtType(@TypeOf(self)) { |
| 217 | 245 | if (index < prealloc_item_count) { |
| 218 | 246 | return &self.prealloc_segment[index]; |
| ... | ... | @@ -395,10 +423,31 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void { |
| 395 | 423 | try list.pushMany(&[_]i32{}); |
| 396 | 424 | testing.expect(list.len == 99); |
| 397 | 425 | |
| 398 | | var i: i32 = 99; |
| 399 | | while (list.pop()) |item| : (i -= 1) { |
| 400 | | testing.expect(item == i); |
| 401 | | list.shrinkCapacity(list.len); |
| 426 | { |
| 427 | var i: i32 = 99; |
| 428 | while (list.pop()) |item| : (i -= 1) { |
| 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 | 453 | try list.setCapacity(0); |