Skip to content

Commit cedf0bf

Browse files
committed
Add setObjectSize, make List setUnsafe/getUnsafe use usize, add list a iterator that borrows
1 parent fdd5555 commit cedf0bf

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

py.zig

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,11 @@ pub inline fn ObjectProtocol(comptime T: type) type {
454454
return c.PyObject_Size(@ptrCast(self));
455455
}
456456

457+
// Set ob_size size
458+
pub inline fn setObjectSize(self: *T, size: isize) void {
459+
c.Py_SET_SIZE(@ptrCast(self), size);
460+
}
461+
457462
// Compute and return the hash value of an object o.
458463
// This is the equivalent of the Python expression hash(o).
459464
pub inline fn hash(self: *T) !isize {
@@ -1550,7 +1555,7 @@ pub const List = extern struct {
15501555
return c.PyList_Check(@as([*c]c.PyObject, @constCast(@ptrCast(obj)))) != 0;
15511556
}
15521557

1553-
// Return a new empty dictionary, or NULL on failure.
1558+
// Return a new empty list, or NULL on failure.
15541559
// Returns a new reference
15551560
pub inline fn new(len: usize) !*List {
15561561
if (c.PyList_New(@intCast(len))) |r| {
@@ -1578,6 +1583,11 @@ pub const List = extern struct {
15781583
return c.PyList_Size(@ptrCast(self));
15791584
}
15801585

1586+
pub inline fn sizeUnsafe(self: *List) isize {
1587+
std.debug.assert(List.check(@ptrCast(self)));
1588+
return self.impl.ob_size;
1589+
}
1590+
15811591
// Get a borrowed reference to the list item.
15821592
// The position must be non-negative; indexing from the end of the list
15831593
// is not supported. If index is out of bounds (<0 or >=len(list)),
@@ -1596,7 +1606,7 @@ pub const List = extern struct {
15961606

15971607
// Get borrowed refernce to list item at index without type or bounds checking
15981608
// Calls PyList_GET_ITEM(self, index).
1599-
pub inline fn getUnsafe(self: *List, index: usize) ?*Object {
1609+
pub inline fn getUnsafe(self: *const List, index: usize) ?*Object {
16001610
std.debug.assert(List.check(@ptrCast(self)));
16011611
return @ptrCast(self.impl.ob_item[index]);
16021612
}
@@ -1622,7 +1632,7 @@ pub const List = extern struct {
16221632
// content. This macro “steals” a reference to item, and, unlike PyList_SetItem(),
16231633
// does not discard a reference to any item that is being replaced;
16241634
// any reference in list at position i will be leaked.
1625-
pub inline fn setUnsafe(self: *List, index: isize, item: *Object) void {
1635+
pub inline fn setUnsafe(self: *List, index: usize, item: *Object) void {
16261636
std.debug.assert(List.check(@ptrCast(self)));
16271637
self.impl.ob_item[index] = @ptrCast(item);
16281638
}
@@ -1739,6 +1749,21 @@ pub const List = extern struct {
17391749
return c.PyList_Reverse(@ptrCast(self));
17401750
}
17411751

1752+
// Iterate over list items inplace.
1753+
// Assumes the item has been checked that is is indeed a List
1754+
// This is likely slower than using for(0..n) |item|
1755+
// Returns a borrowed reference to the item
1756+
pub inline fn next(self: *List, pos: *usize) ?*Object {
1757+
// Zig will safety check this for -1 in release safe
1758+
const n: usize = @intCast(self.sizeUnsafe());
1759+
const i = pos.*;
1760+
if (i < n) {
1761+
pos.* = i + 1;
1762+
return self.getUnsafe(i).?;
1763+
}
1764+
return null;
1765+
}
1766+
17421767
// Return a new tuple object containing the contents of list; equivalent to tuple(list).
17431768
// Returns a new reference
17441769
pub inline fn asTuple(self: *List) !*Tuple {

0 commit comments

Comments
 (0)