authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-19 16:21:42-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-19 16:40:00-07:00
log1eeb8fabe5ed49c2e334c82ece741818f5d37412
treec235059050f1ea30b79cd24eb4fc83ce7a287d31
parent4a38d783e8ebf2ab94f9f322de2584bfc8a133e3

std: delete SegmentedList again

The data structure was originally added in 41e1cd185b82a518c58c92544c45f0348c03ef74 and then removed in 50a336fff899ebd8a687c453ec6beb18a5a9baf9, but brought back in 711bf55eaa643c3d05640bebbf3e4315477b8ed8 for Decl in the compiler frontend, and then the last reference to it was eliminated in 548a087fafeda5b07d2237d5137906b8d07da699 which removed Decl in favor of Nav and Cau.

4 files changed, 0 insertions(+), 741 deletions(-)

lib/std/segmented_list.zig deleted-531
...@@ -1,531 +0,0 @@
1const std = @import("std.zig");
2const assert = std.debug.assert;
3const testing = std.testing;
4const mem = std.mem;
5const Allocator = std.mem.Allocator;
6
7// Imagine that `fn at(self: *Self, index: usize) &T` is a customer asking for a box
8// from a warehouse, based on a flat array, boxes ordered from 0 to N - 1.
9// But the warehouse actually stores boxes in shelves of increasing powers of 2 sizes.
10// So when the customer requests a box index, we have to translate it to shelf index
11// and box index within that shelf. Illustration:
12//
13// customer indexes:
14// shelf 0: 0
15// shelf 1: 1 2
16// shelf 2: 3 4 5 6
17// shelf 3: 7 8 9 10 11 12 13 14
18// shelf 4: 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
19// shelf 5: 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
20// ...
21//
22// warehouse indexes:
23// shelf 0: 0
24// shelf 1: 0 1
25// shelf 2: 0 1 2 3
26// shelf 3: 0 1 2 3 4 5 6 7
27// shelf 4: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
28// shelf 5: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
29// ...
30//
31// With this arrangement, here are the equations to get the shelf index and
32// box index based on customer box index:
33//
34// shelf_index = floor(log2(customer_index + 1))
35// shelf_count = ceil(log2(box_count + 1))
36// box_index = customer_index + 1 - 2 ** shelf
37// shelf_size = 2 ** shelf_index
38//
39// Now we complicate it a little bit further by adding a preallocated shelf, which must be
40// a power of 2:
41// prealloc=4
42//
43// customer indexes:
44// prealloc: 0 1 2 3
45// shelf 0: 4 5 6 7 8 9 10 11
46// shelf 1: 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
47// shelf 2: 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
48// ...
49//
50// warehouse indexes:
51// prealloc: 0 1 2 3
52// shelf 0: 0 1 2 3 4 5 6 7
53// shelf 1: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
54// shelf 2: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
55// ...
56//
57// Now the equations are:
58//
59// shelf_index = floor(log2(customer_index + prealloc)) - log2(prealloc) - 1
60// shelf_count = ceil(log2(box_count + prealloc)) - log2(prealloc) - 1
61// box_index = customer_index + prealloc - 2 ** (log2(prealloc) + 1 + shelf)
62// shelf_size = prealloc * 2 ** (shelf_index + 1)
63
64/// This is a stack data structure where pointers to indexes have the same lifetime as the data structure
65/// itself, unlike ArrayList where append() invalidates all existing element pointers.
66/// The tradeoff is that elements are not guaranteed to be contiguous. For that, use ArrayList.
67/// Note however that most elements are contiguous, making this data structure cache-friendly.
68///
69/// Because it never has to copy elements from an old location to a new location, it does not require
70/// its elements to be copyable, and it avoids wasting memory when backed by an ArenaAllocator.
71/// Note that the append() and pop() convenience methods perform a copy, but you can instead use
72/// addOne(), at(), setCapacity(), and shrinkCapacity() to avoid copying items.
73///
74/// This data structure has O(1) append and O(1) pop.
75///
76/// It supports preallocated elements, making it especially well suited when the expected maximum
77/// size is small. `prealloc_item_count` must be 0, or a power of 2.
78pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type {
79 return struct {
80 const Self = @This();
81 const ShelfIndex = std.math.Log2Int(usize);
82
83 const prealloc_exp: ShelfIndex = blk: {
84 // we don't use the prealloc_exp constant when prealloc_item_count is 0
85 // but lazy-init may still be triggered by other code so supply a value
86 if (prealloc_item_count == 0) {
87 break :blk 0;
88 } else {
89 assert(std.math.isPowerOfTwo(prealloc_item_count));
90 const value = std.math.log2_int(usize, prealloc_item_count);
91 break :blk value;
92 }
93 };
94
95 prealloc_segment: [prealloc_item_count]T = undefined,
96 dynamic_segments: [][*]T = &[_][*]T{},
97 len: usize = 0,
98
99 pub const prealloc_count = prealloc_item_count;
100
101 fn AtType(comptime SelfType: type) type {
102 if (@typeInfo(SelfType).pointer.is_const) {
103 return *const T;
104 } else {
105 return *T;
106 }
107 }
108
109 pub fn deinit(self: *Self, allocator: Allocator) void {
110 self.freeShelves(allocator, @as(ShelfIndex, @intCast(self.dynamic_segments.len)), 0);
111 allocator.free(self.dynamic_segments);
112 self.* = undefined;
113 }
114
115 pub fn at(self: anytype, i: usize) AtType(@TypeOf(self)) {
116 assert(i < self.len);
117 return self.uncheckedAt(i);
118 }
119
120 pub fn count(self: Self) usize {
121 return self.len;
122 }
123
124 pub fn append(self: *Self, allocator: Allocator, item: T) Allocator.Error!void {
125 const new_item_ptr = try self.addOne(allocator);
126 new_item_ptr.* = item;
127 }
128
129 pub fn appendSlice(self: *Self, allocator: Allocator, items: []const T) Allocator.Error!void {
130 for (items) |item| {
131 try self.append(allocator, item);
132 }
133 }
134
135 pub fn pop(self: *Self) ?T {
136 if (self.len == 0) return null;
137
138 const index = self.len - 1;
139 const result = uncheckedAt(self, index).*;
140 self.len = index;
141 return result;
142 }
143
144 pub fn addOne(self: *Self, allocator: Allocator) Allocator.Error!*T {
145 const new_length = self.len + 1;
146 try self.growCapacity(allocator, new_length);
147 const result = uncheckedAt(self, self.len);
148 self.len = new_length;
149 return result;
150 }
151
152 /// Reduce length to `new_len`.
153 /// Invalidates pointers for the elements at index new_len and beyond.
154 pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void {
155 assert(new_len <= self.len);
156 self.len = new_len;
157 }
158
159 /// Invalidates all element pointers.
160 pub fn clearRetainingCapacity(self: *Self) void {
161 self.len = 0;
162 }
163
164 /// Invalidates all element pointers.
165 pub fn clearAndFree(self: *Self, allocator: Allocator) void {
166 self.setCapacity(allocator, 0) catch unreachable;
167 self.len = 0;
168 }
169
170 /// Grows or shrinks capacity to match usage.
171 /// TODO update this and related methods to match the conventions set by ArrayList
172 pub fn setCapacity(self: *Self, allocator: Allocator, new_capacity: usize) Allocator.Error!void {
173 if (prealloc_item_count != 0) {
174 if (new_capacity <= @as(usize, 1) << (prealloc_exp + @as(ShelfIndex, @intCast(self.dynamic_segments.len)))) {
175 return self.shrinkCapacity(allocator, new_capacity);
176 }
177 }
178 return self.growCapacity(allocator, new_capacity);
179 }
180
181 /// Only grows capacity, or retains current capacity.
182 pub fn growCapacity(self: *Self, allocator: Allocator, new_capacity: usize) Allocator.Error!void {
183 const new_cap_shelf_count = shelfCount(new_capacity);
184 const old_shelf_count = @as(ShelfIndex, @intCast(self.dynamic_segments.len));
185 if (new_cap_shelf_count <= old_shelf_count) return;
186
187 const new_dynamic_segments = try allocator.alloc([*]T, new_cap_shelf_count);
188 errdefer allocator.free(new_dynamic_segments);
189
190 var i: ShelfIndex = 0;
191 while (i < old_shelf_count) : (i += 1) {
192 new_dynamic_segments[i] = self.dynamic_segments[i];
193 }
194 errdefer while (i > old_shelf_count) : (i -= 1) {
195 allocator.free(new_dynamic_segments[i][0..shelfSize(i)]);
196 };
197 while (i < new_cap_shelf_count) : (i += 1) {
198 new_dynamic_segments[i] = (try allocator.alloc(T, shelfSize(i))).ptr;
199 }
200
201 allocator.free(self.dynamic_segments);
202 self.dynamic_segments = new_dynamic_segments;
203 }
204
205 /// Only shrinks capacity or retains current capacity.
206 /// It may fail to reduce the capacity in which case the capacity will remain unchanged.
207 pub fn shrinkCapacity(self: *Self, allocator: Allocator, new_capacity: usize) void {
208 if (new_capacity <= prealloc_item_count) {
209 const len = @as(ShelfIndex, @intCast(self.dynamic_segments.len));
210 self.freeShelves(allocator, len, 0);
211 allocator.free(self.dynamic_segments);
212 self.dynamic_segments = &[_][*]T{};
213 return;
214 }
215
216 const new_cap_shelf_count = shelfCount(new_capacity);
217 const old_shelf_count = @as(ShelfIndex, @intCast(self.dynamic_segments.len));
218 assert(new_cap_shelf_count <= old_shelf_count);
219 if (new_cap_shelf_count == old_shelf_count) return;
220
221 // freeShelves() must be called before resizing the dynamic
222 // segments, but we don't know if resizing the dynamic segments
223 // will work until we try it. So we must allocate a fresh memory
224 // buffer in order to reduce capacity.
225 const new_dynamic_segments = allocator.alloc([*]T, new_cap_shelf_count) catch return;
226 self.freeShelves(allocator, old_shelf_count, new_cap_shelf_count);
227 if (allocator.resize(self.dynamic_segments, new_cap_shelf_count)) {
228 // We didn't need the new memory allocation after all.
229 self.dynamic_segments = self.dynamic_segments[0..new_cap_shelf_count];
230 allocator.free(new_dynamic_segments);
231 } else {
232 // Good thing we allocated that new memory slice.
233 @memcpy(new_dynamic_segments, self.dynamic_segments[0..new_cap_shelf_count]);
234 allocator.free(self.dynamic_segments);
235 self.dynamic_segments = new_dynamic_segments;
236 }
237 }
238
239 pub fn shrink(self: *Self, new_len: usize) void {
240 assert(new_len <= self.len);
241 // TODO take advantage of the new realloc semantics
242 self.len = new_len;
243 }
244
245 pub fn writeToSlice(self: *Self, dest: []T, start: usize) void {
246 const end = start + dest.len;
247 assert(end <= self.len);
248
249 var i = start;
250 if (end <= prealloc_item_count) {
251 const src = self.prealloc_segment[i..end];
252 @memcpy(dest[i - start ..][0..src.len], src);
253 return;
254 } else if (i < prealloc_item_count) {
255 const src = self.prealloc_segment[i..];
256 @memcpy(dest[i - start ..][0..src.len], src);
257 i = prealloc_item_count;
258 }
259
260 while (i < end) {
261 const shelf_index = shelfIndex(i);
262 const copy_start = boxIndex(i, shelf_index);
263 const copy_end = @min(shelfSize(shelf_index), copy_start + end - i);
264 const src = self.dynamic_segments[shelf_index][copy_start..copy_end];
265 @memcpy(dest[i - start ..][0..src.len], src);
266 i += (copy_end - copy_start);
267 }
268 }
269
270 pub fn uncheckedAt(self: anytype, index: usize) AtType(@TypeOf(self)) {
271 if (index < prealloc_item_count) {
272 return &self.prealloc_segment[index];
273 }
274 const shelf_index = shelfIndex(index);
275 const box_index = boxIndex(index, shelf_index);
276 return &self.dynamic_segments[shelf_index][box_index];
277 }
278
279 fn shelfCount(box_count: usize) ShelfIndex {
280 if (prealloc_item_count == 0) {
281 return log2_int_ceil(usize, box_count + 1);
282 }
283 return log2_int_ceil(usize, box_count + prealloc_item_count) - prealloc_exp - 1;
284 }
285
286 fn shelfSize(shelf_index: ShelfIndex) usize {
287 if (prealloc_item_count == 0) {
288 return @as(usize, 1) << shelf_index;
289 }
290 return @as(usize, 1) << (shelf_index + (prealloc_exp + 1));
291 }
292
293 fn shelfIndex(list_index: usize) ShelfIndex {
294 if (prealloc_item_count == 0) {
295 return std.math.log2_int(usize, list_index + 1);
296 }
297 return std.math.log2_int(usize, list_index + prealloc_item_count) - prealloc_exp - 1;
298 }
299
300 fn boxIndex(list_index: usize, shelf_index: ShelfIndex) usize {
301 if (prealloc_item_count == 0) {
302 return (list_index + 1) - (@as(usize, 1) << shelf_index);
303 }
304 return list_index + prealloc_item_count - (@as(usize, 1) << ((prealloc_exp + 1) + shelf_index));
305 }
306
307 fn freeShelves(self: *Self, allocator: Allocator, from_count: ShelfIndex, to_count: ShelfIndex) void {
308 var i = from_count;
309 while (i != to_count) {
310 i -= 1;
311 allocator.free(self.dynamic_segments[i][0..shelfSize(i)]);
312 }
313 }
314
315 pub const Iterator = BaseIterator(*Self, *T);
316 pub const ConstIterator = BaseIterator(*const Self, *const T);
317 fn BaseIterator(comptime SelfType: type, comptime ElementPtr: type) type {
318 return struct {
319 list: SelfType,
320 index: usize,
321 box_index: usize,
322 shelf_index: ShelfIndex,
323 shelf_size: usize,
324
325 pub fn next(it: *@This()) ?ElementPtr {
326 if (it.index >= it.list.len) return null;
327 if (it.index < prealloc_item_count) {
328 const ptr = &it.list.prealloc_segment[it.index];
329 it.index += 1;
330 if (it.index == prealloc_item_count) {
331 it.box_index = 0;
332 it.shelf_index = 0;
333 it.shelf_size = prealloc_item_count * 2;
334 }
335 return ptr;
336 }
337
338 const ptr = &it.list.dynamic_segments[it.shelf_index][it.box_index];
339 it.index += 1;
340 it.box_index += 1;
341 if (it.box_index == it.shelf_size) {
342 it.shelf_index += 1;
343 it.box_index = 0;
344 it.shelf_size *= 2;
345 }
346 return ptr;
347 }
348
349 pub fn prev(it: *@This()) ?ElementPtr {
350 if (it.index == 0) return null;
351
352 it.index -= 1;
353 if (it.index < prealloc_item_count) return &it.list.prealloc_segment[it.index];
354
355 if (it.box_index == 0) {
356 it.shelf_index -= 1;
357 it.shelf_size /= 2;
358 it.box_index = it.shelf_size - 1;
359 } else {
360 it.box_index -= 1;
361 }
362
363 return &it.list.dynamic_segments[it.shelf_index][it.box_index];
364 }
365
366 pub fn peek(it: *@This()) ?ElementPtr {
367 if (it.index >= it.list.len)
368 return null;
369 if (it.index < prealloc_item_count)
370 return &it.list.prealloc_segment[it.index];
371
372 return &it.list.dynamic_segments[it.shelf_index][it.box_index];
373 }
374
375 pub fn set(it: *@This(), index: usize) void {
376 it.index = index;
377 if (index < prealloc_item_count) return;
378 it.shelf_index = shelfIndex(index);
379 it.box_index = boxIndex(index, it.shelf_index);
380 it.shelf_size = shelfSize(it.shelf_index);
381 }
382 };
383 }
384
385 pub fn iterator(self: *Self, start_index: usize) Iterator {
386 var it = Iterator{
387 .list = self,
388 .index = undefined,
389 .shelf_index = undefined,
390 .box_index = undefined,
391 .shelf_size = undefined,
392 };
393 it.set(start_index);
394 return it;
395 }
396
397 pub fn constIterator(self: *const Self, start_index: usize) ConstIterator {
398 var it = ConstIterator{
399 .list = self,
400 .index = undefined,
401 .shelf_index = undefined,
402 .box_index = undefined,
403 .shelf_size = undefined,
404 };
405 it.set(start_index);
406 return it;
407 }
408 };
409}
410
411test "basic usage" {
412 try testSegmentedList(0);
413 try testSegmentedList(1);
414 try testSegmentedList(2);
415 try testSegmentedList(4);
416 try testSegmentedList(8);
417 try testSegmentedList(16);
418}
419
420fn testSegmentedList(comptime prealloc: usize) !void {
421 var list = SegmentedList(i32, prealloc){};
422 defer list.deinit(testing.allocator);
423
424 {
425 var i: usize = 0;
426 while (i < 100) : (i += 1) {
427 try list.append(testing.allocator, @as(i32, @intCast(i + 1)));
428 try testing.expect(list.len == i + 1);
429 }
430 }
431
432 {
433 var i: usize = 0;
434 while (i < 100) : (i += 1) {
435 try testing.expect(list.at(i).* == @as(i32, @intCast(i + 1)));
436 }
437 }
438
439 {
440 var it = list.iterator(0);
441 var x: i32 = 0;
442 while (it.next()) |item| {
443 x += 1;
444 try testing.expect(item.* == x);
445 }
446 try testing.expect(x == 100);
447 while (it.prev()) |item| : (x -= 1) {
448 try testing.expect(item.* == x);
449 }
450 try testing.expect(x == 0);
451 }
452
453 {
454 var it = list.constIterator(0);
455 var x: i32 = 0;
456 while (it.next()) |item| {
457 x += 1;
458 try testing.expect(item.* == x);
459 }
460 try testing.expect(x == 100);
461 while (it.prev()) |item| : (x -= 1) {
462 try testing.expect(item.* == x);
463 }
464 try testing.expect(x == 0);
465 }
466
467 try testing.expect(list.pop().? == 100);
468 try testing.expect(list.len == 99);
469
470 try list.appendSlice(testing.allocator, &[_]i32{ 1, 2, 3 });
471 try testing.expect(list.len == 102);
472 try testing.expect(list.pop().? == 3);
473 try testing.expect(list.pop().? == 2);
474 try testing.expect(list.pop().? == 1);
475 try testing.expect(list.len == 99);
476
477 try list.appendSlice(testing.allocator, &[_]i32{});
478 try testing.expect(list.len == 99);
479
480 {
481 var i: i32 = 99;
482 while (list.pop()) |item| : (i -= 1) {
483 try testing.expect(item == i);
484 list.shrinkCapacity(testing.allocator, list.len);
485 }
486 }
487
488 {
489 var control: [100]i32 = undefined;
490 var dest: [100]i32 = undefined;
491
492 var i: i32 = 0;
493 while (i < 100) : (i += 1) {
494 try list.append(testing.allocator, i + 1);
495 control[@as(usize, @intCast(i))] = i + 1;
496 }
497
498 @memset(dest[0..], 0);
499 list.writeToSlice(dest[0..], 0);
500 try testing.expect(mem.eql(i32, control[0..], dest[0..]));
501
502 @memset(dest[0..], 0);
503 list.writeToSlice(dest[50..], 50);
504 try testing.expect(mem.eql(i32, control[50..], dest[50..]));
505 }
506
507 try list.setCapacity(testing.allocator, 0);
508}
509
510test "clearRetainingCapacity" {
511 var list = SegmentedList(i32, 1){};
512 defer list.deinit(testing.allocator);
513
514 try list.appendSlice(testing.allocator, &[_]i32{ 4, 5 });
515 list.clearRetainingCapacity();
516 try list.append(testing.allocator, 6);
517 try testing.expect(list.at(0).* == 6);
518 try testing.expect(list.len == 1);
519 list.clearRetainingCapacity();
520 try testing.expect(list.len == 0);
521}
522
523/// TODO look into why this std.math function was changed in
524/// fc9430f56798a53f9393a697f4ccd6bf9981b970.
525fn log2_int_ceil(comptime T: type, x: T) std.math.Log2Int(T) {
526 assert(x != 0);
527 const log2_val = std.math.log2_int(T, x);
528 if (@as(T, 1) << log2_val == x)
529 return log2_val;
530 return log2_val + 1;
531}
lib/std/std.zig-1
...@@ -26,7 +26,6 @@ pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue;...@@ -26,7 +26,6 @@ pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue;
26pub const PriorityDequeue = @import("priority_dequeue.zig").PriorityDequeue;26pub const PriorityDequeue = @import("priority_dequeue.zig").PriorityDequeue;
27pub const Progress = @import("Progress.zig");27pub const Progress = @import("Progress.zig");
28pub const Random = @import("Random.zig");28pub const Random = @import("Random.zig");
29pub const SegmentedList = @import("segmented_list.zig").SegmentedList;
30pub const SemanticVersion = @import("SemanticVersion.zig");29pub const SemanticVersion = @import("SemanticVersion.zig");
31pub const SinglyLinkedList = @import("SinglyLinkedList.zig");30pub const SinglyLinkedList = @import("SinglyLinkedList.zig");
32pub const StaticBitSet = bit_set.StaticBitSet;31pub const StaticBitSet = bit_set.StaticBitSet;
test/src/Debugger.zig-181
...@@ -2188,187 +2188,6 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -2188,187 +2188,6 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
2188 \\1 breakpoints deleted; 0 breakpoint locations disabled.2188 \\1 breakpoints deleted; 0 breakpoint locations disabled.
2189 },2189 },
2190 );2190 );
2191 db.addLldbTest(
2192 "segmented_list",
2193 target,
2194 &.{
2195 .{
2196 .path = "main.zig",
2197 .source =
2198 \\const std = @import("std");
2199 \\fn testSegmentedList() void {}
2200 \\pub fn main() !void {
2201 \\ var list0: std.SegmentedList(usize, 0) = .{};
2202 \\ defer list0.deinit(std.heap.page_allocator);
2203 \\
2204 \\ var list1: std.SegmentedList(usize, 1) = .{};
2205 \\ defer list1.deinit(std.heap.page_allocator);
2206 \\
2207 \\ var list2: std.SegmentedList(usize, 2) = .{};
2208 \\ defer list2.deinit(std.heap.page_allocator);
2209 \\
2210 \\ var list4: std.SegmentedList(usize, 4) = .{};
2211 \\ defer list4.deinit(std.heap.page_allocator);
2212 \\
2213 \\ for (0..32) |i| {
2214 \\ try list0.append(std.heap.page_allocator, i);
2215 \\ try list1.append(std.heap.page_allocator, i);
2216 \\ try list2.append(std.heap.page_allocator, i);
2217 \\ try list4.append(std.heap.page_allocator, i);
2218 \\ }
2219 \\ testSegmentedList();
2220 \\}
2221 \\
2222 ,
2223 },
2224 },
2225 \\breakpoint set --file main.zig --source-pattern-regexp 'testSegmentedList\(\);'
2226 \\process launch
2227 \\frame variable -- list0 list1 list2 list4
2228 \\breakpoint delete --force 1
2229 ,
2230 &.{
2231 \\(lldb) frame variable -- list0 list1 list2 list4
2232 \\(std.segmented_list.SegmentedList(usize,0)) list0 = len=32 {
2233 \\ [0] = 0
2234 \\ [1] = 1
2235 \\ [2] = 2
2236 \\ [3] = 3
2237 \\ [4] = 4
2238 \\ [5] = 5
2239 \\ [6] = 6
2240 \\ [7] = 7
2241 \\ [8] = 8
2242 \\ [9] = 9
2243 \\ [10] = 10
2244 \\ [11] = 11
2245 \\ [12] = 12
2246 \\ [13] = 13
2247 \\ [14] = 14
2248 \\ [15] = 15
2249 \\ [16] = 16
2250 \\ [17] = 17
2251 \\ [18] = 18
2252 \\ [19] = 19
2253 \\ [20] = 20
2254 \\ [21] = 21
2255 \\ [22] = 22
2256 \\ [23] = 23
2257 \\ [24] = 24
2258 \\ [25] = 25
2259 \\ [26] = 26
2260 \\ [27] = 27
2261 \\ [28] = 28
2262 \\ [29] = 29
2263 \\ [30] = 30
2264 \\ [31] = 31
2265 \\}
2266 \\(std.segmented_list.SegmentedList(usize,1)) list1 = len=32 {
2267 \\ [0] = 0
2268 \\ [1] = 1
2269 \\ [2] = 2
2270 \\ [3] = 3
2271 \\ [4] = 4
2272 \\ [5] = 5
2273 \\ [6] = 6
2274 \\ [7] = 7
2275 \\ [8] = 8
2276 \\ [9] = 9
2277 \\ [10] = 10
2278 \\ [11] = 11
2279 \\ [12] = 12
2280 \\ [13] = 13
2281 \\ [14] = 14
2282 \\ [15] = 15
2283 \\ [16] = 16
2284 \\ [17] = 17
2285 \\ [18] = 18
2286 \\ [19] = 19
2287 \\ [20] = 20
2288 \\ [21] = 21
2289 \\ [22] = 22
2290 \\ [23] = 23
2291 \\ [24] = 24
2292 \\ [25] = 25
2293 \\ [26] = 26
2294 \\ [27] = 27
2295 \\ [28] = 28
2296 \\ [29] = 29
2297 \\ [30] = 30
2298 \\ [31] = 31
2299 \\}
2300 \\(std.segmented_list.SegmentedList(usize,2)) list2 = len=32 {
2301 \\ [0] = 0
2302 \\ [1] = 1
2303 \\ [2] = 2
2304 \\ [3] = 3
2305 \\ [4] = 4
2306 \\ [5] = 5
2307 \\ [6] = 6
2308 \\ [7] = 7
2309 \\ [8] = 8
2310 \\ [9] = 9
2311 \\ [10] = 10
2312 \\ [11] = 11
2313 \\ [12] = 12
2314 \\ [13] = 13
2315 \\ [14] = 14
2316 \\ [15] = 15
2317 \\ [16] = 16
2318 \\ [17] = 17
2319 \\ [18] = 18
2320 \\ [19] = 19
2321 \\ [20] = 20
2322 \\ [21] = 21
2323 \\ [22] = 22
2324 \\ [23] = 23
2325 \\ [24] = 24
2326 \\ [25] = 25
2327 \\ [26] = 26
2328 \\ [27] = 27
2329 \\ [28] = 28
2330 \\ [29] = 29
2331 \\ [30] = 30
2332 \\ [31] = 31
2333 \\}
2334 \\(std.segmented_list.SegmentedList(usize,4)) list4 = len=32 {
2335 \\ [0] = 0
2336 \\ [1] = 1
2337 \\ [2] = 2
2338 \\ [3] = 3
2339 \\ [4] = 4
2340 \\ [5] = 5
2341 \\ [6] = 6
2342 \\ [7] = 7
2343 \\ [8] = 8
2344 \\ [9] = 9
2345 \\ [10] = 10
2346 \\ [11] = 11
2347 \\ [12] = 12
2348 \\ [13] = 13
2349 \\ [14] = 14
2350 \\ [15] = 15
2351 \\ [16] = 16
2352 \\ [17] = 17
2353 \\ [18] = 18
2354 \\ [19] = 19
2355 \\ [20] = 20
2356 \\ [21] = 21
2357 \\ [22] = 22
2358 \\ [23] = 23
2359 \\ [24] = 24
2360 \\ [25] = 25
2361 \\ [26] = 26
2362 \\ [27] = 27
2363 \\ [28] = 28
2364 \\ [29] = 29
2365 \\ [30] = 30
2366 \\ [31] = 31
2367 \\}
2368 \\(lldb) breakpoint delete --force 1
2369 \\1 breakpoints deleted; 0 breakpoint locations disabled.
2370 },
2371 );
2372}2191}
23732192
2374const File = struct { import: ?[]const u8 = null, path: []const u8, source: []const u8 };2193const File = struct { import: ?[]const u8 = null, path: []const u8, source: []const u8 };
tools/lldb_pretty_printers.py-28
...@@ -206,33 +206,6 @@ class zig_TaggedUnion_SynthProvider:...@@ -206,33 +206,6 @@ class zig_TaggedUnion_SynthProvider:
206206
207# Define Zig Standard Library207# Define Zig Standard Library
208208
209class std_SegmentedList_SynthProvider:
210 def __init__(self, value, _=None): self.value = value
211 def update(self):
212 try:
213 self.prealloc_segment = self.value.GetChildMemberWithName('prealloc_segment')
214 self.dynamic_segments = zig_Slice_SynthProvider(self.value.GetChildMemberWithName('dynamic_segments'))
215 self.dynamic_segments.update()
216 self.len = self.value.GetChildMemberWithName('len').unsigned
217 except: pass
218 def has_children(self): return True
219 def num_children(self): return self.len
220 def get_child_index(self, name):
221 try: return int(name.removeprefix('[').removesuffix(']'))
222 except: return -1
223 def get_child_at_index(self, index):
224 try:
225 if index not in range(self.len): return None
226 prealloc_item_count = len(self.prealloc_segment)
227 if index < prealloc_item_count: return self.prealloc_segment.child[index]
228 prealloc_exp = prealloc_item_count.bit_length() - 1
229 shelf_index = log2_int(index + 1) if prealloc_item_count == 0 else log2_int(index + prealloc_item_count) - prealloc_exp - 1
230 shelf = self.dynamic_segments.get_child_at_index(shelf_index)
231 box_index = (index + 1) - (1 << shelf_index) if prealloc_item_count == 0 else index + prealloc_item_count - (1 << ((prealloc_exp + 1) + shelf_index))
232 elem_type = shelf.type.GetPointeeType()
233 return shelf.CreateChildAtOffset('[%d]' % index, box_index * elem_type.size, elem_type)
234 except: return None
235
236class std_MultiArrayList_SynthProvider:209class std_MultiArrayList_SynthProvider:
237 def __init__(self, value, _=None): self.value = value210 def __init__(self, value, _=None): self.value = value
238 def update(self):211 def update(self):
...@@ -936,7 +909,6 @@ def __lldb_init_module(debugger, _=None):...@@ -936,7 +909,6 @@ def __lldb_init_module(debugger, _=None):
936909
937 # Initialize Zig Standard Library910 # Initialize Zig Standard Library
938 add(debugger, category='zig.std', type='mem.Allocator', summary='${var.ptr}')911 add(debugger, category='zig.std', type='mem.Allocator', summary='${var.ptr}')
939 add(debugger, category='zig.std', regex=True, type='^segmented_list\\.SegmentedList\\(.*\\)$', identifier='std_SegmentedList', synth=True, expand=True, summary='len=${var.len}')
940 add(debugger, category='zig.std', regex=True, type='^multi_array_list\\.MultiArrayList\\(.*\\)$', identifier='std_MultiArrayList', synth=True, expand=True, summary='len=${var.len} capacity=${var.capacity}')912 add(debugger, category='zig.std', regex=True, type='^multi_array_list\\.MultiArrayList\\(.*\\)$', identifier='std_MultiArrayList', synth=True, expand=True, summary='len=${var.len} capacity=${var.capacity}')
941 add(debugger, category='zig.std', regex=True, type='^multi_array_list\\.MultiArrayList\\(.*\\)\\.Slice$', identifier='std_MultiArrayList_Slice', synth=True, expand=True, summary='len=${var.len} capacity=${var.capacity}')913 add(debugger, category='zig.std', regex=True, type='^multi_array_list\\.MultiArrayList\\(.*\\)\\.Slice$', identifier='std_MultiArrayList_Slice', synth=True, expand=True, summary='len=${var.len} capacity=${var.capacity}')
942 add(debugger, category='zig.std', regex=True, type=MultiArrayList_Entry('.*'), identifier='std_Entry', synth=True, inline_children=True, summary=True)914 add(debugger, category='zig.std', regex=True, type=MultiArrayList_Entry('.*'), identifier='std_Entry', synth=True, inline_children=True, summary=True)