| ... | ... | @@ -86,10 +86,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type |
| 86 | 86 | }; |
| 87 | 87 | const ShelfIndex = std.math.Log2Int(usize); |
| 88 | 88 | |
| 89 | | allocator: &Allocator, |
| 90 | | len: usize, |
| 91 | 89 | prealloc_segment: [prealloc_item_count]T, |
| 92 | 90 | dynamic_segments: []&T, |
| 91 | allocator: &Allocator, |
| 92 | len: usize, |
| 93 | 93 | |
| 94 | 94 | /// Deinitialize with `deinit` |
| 95 | 95 | pub fn init(allocator: &Allocator) Self { |
| ... | ... | @@ -237,6 +237,54 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type |
| 237 | 237 | } |
| 238 | 238 | } |
| 239 | 239 | |
| 240 | pub const Iterator = struct { |
| 241 | list: &Self, |
| 242 | index: usize, |
| 243 | box_index: usize, |
| 244 | shelf_index: ShelfIndex, |
| 245 | shelf_size: usize, |
| 246 | |
| 247 | pub fn next(it: &Iterator) ?&T { |
| 248 | if (it.index >= it.list.len) |
| 249 | return null; |
| 250 | if (it.index < prealloc_item_count) { |
| 251 | const ptr = &it.list.prealloc_segment[it.index]; |
| 252 | it.index += 1; |
| 253 | if (it.index == prealloc_item_count) { |
| 254 | it.box_index = 0; |
| 255 | it.shelf_index = 0; |
| 256 | it.shelf_size = prealloc_item_count * 2; |
| 257 | } |
| 258 | return ptr; |
| 259 | } |
| 260 | |
| 261 | const ptr = &it.list.dynamic_segments[it.shelf_index][it.box_index]; |
| 262 | it.index += 1; |
| 263 | it.box_index += 1; |
| 264 | if (it.box_index == it.shelf_size) { |
| 265 | it.shelf_index += 1; |
| 266 | it.box_index = 0; |
| 267 | it.shelf_size *= 2; |
| 268 | } |
| 269 | return ptr; |
| 270 | } |
| 271 | }; |
| 272 | |
| 273 | pub fn iterator(self: &Self, start_index: usize) Iterator { |
| 274 | var it = Iterator { |
| 275 | .list = self, |
| 276 | .index = start_index, |
| 277 | .shelf_index = undefined, |
| 278 | .box_index = undefined, |
| 279 | .shelf_size = undefined, |
| 280 | }; |
| 281 | if (start_index >= prealloc_item_count) { |
| 282 | it.shelf_index = shelfIndex(start_index); |
| 283 | it.box_index = boxIndex(start_index, it.shelf_index); |
| 284 | it.shelf_size = shelfSize(it.shelf_index); |
| 285 | } |
| 286 | return it; |
| 287 | } |
| 240 | 288 | }; |
| 241 | 289 | } |
| 242 | 290 | |
| ... | ... | @@ -266,6 +314,14 @@ fn testSegmentedList(comptime prealloc: usize, allocator: &Allocator) !void { |
| 266 | 314 | assert(*list.at(i) == i32(i + 1)); |
| 267 | 315 | }} |
| 268 | 316 | |
| 317 | { |
| 318 | var it = list.iterator(0); |
| 319 | var x: i32 = 1; |
| 320 | while (it.next()) |item| : (x += 1) { |
| 321 | assert(*item == x); |
| 322 | } |
| 323 | } |
| 324 | |
| 269 | 325 | assert(??list.pop() == 100); |
| 270 | 326 | assert(list.len == 99); |
| 271 | 327 | |