| ... | @@ -86,10 +86,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type | ... | @@ -86,10 +86,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type |
| 86 | }; | 86 | }; |
| 87 | const ShelfIndex = std.math.Log2Int(usize); | 87 | const ShelfIndex = std.math.Log2Int(usize); |
| 88 | | 88 | |
| 89 | allocator: &Allocator, | | |
| 90 | len: usize, | | |
| 91 | prealloc_segment: [prealloc_item_count]T, | 89 | prealloc_segment: [prealloc_item_count]T, |
| 92 | dynamic_segments: []&T, | 90 | dynamic_segments: []&T, |
| | 91 | allocator: &Allocator, |
| | 92 | len: usize, |
| 93 | | 93 | |
| 94 | /// Deinitialize with `deinit` | 94 | /// Deinitialize with `deinit` |
| 95 | pub fn init(allocator: &Allocator) Self { | 95 | pub fn init(allocator: &Allocator) Self { |
| ... | @@ -237,6 +237,54 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type | ... | @@ -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,6 +314,14 @@ fn testSegmentedList(comptime prealloc: usize, allocator: &Allocator) !void { |
| 266 | assert(*list.at(i) == i32(i + 1)); | 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 | assert(??list.pop() == 100); | 325 | assert(??list.pop() == 100); |
| 270 | assert(list.len == 99); | 326 | assert(list.len == 99); |
| 271 | | 327 | |