refactor iterators/adapters to wrap inner structs in Iterator internally

This commit is contained in:
Luuk Machielse 2025-12-10 16:59:30 +01:00
parent 1e9bd2454e
commit 0843f9f17c

View file

@ -3,7 +3,7 @@ const assert = std.debug.assert;
pub fn iter(comptime T: type) type {
return struct {
pub fn fromSlice(slice: anytype) Iterator(SliceIter(T, .value)) {
pub fn fromSlice(slice: anytype) SliceIter(T, .value) {
return .{ .inner = .{ .slice = slice } };
}
@ -19,19 +19,19 @@ pub fn iter(comptime T: type) type {
try expectEqual(null, it.next());
}
pub fn range(start: T, end: T) Iterator(Range(T, .exclusive)) {
pub fn range(start: T, end: T) Range(T, .exclusive) {
return .{ .inner = .{ .current = start, .end = end } };
}
pub fn rangeInclusive(start: T, end: T) Iterator(Range(T, .inclusive)) {
pub fn rangeInclusive(start: T, end: T) Range(T, .inclusive) {
return .{ .inner = .{ .current = start, .end = end } };
}
pub fn once(value: T) Iterator(Once(T)) {
pub fn once(value: T) Once(T) {
return .{ .inner = .{ .value = value } };
}
pub const empty: Iterator(Empty(T)) = .{ .inner = .{} };
pub const empty: Empty(T) = .{ .inner = .{} };
test empty {
var it = iter(i32).empty;
@ -106,11 +106,11 @@ pub fn Iterator(comptime Inner: type) type {
self: Self,
comptime T: type,
f: fn (Item) T,
) Iterator(adapters.Map(Self, T, f)) {
) adapters.Map(Self, T, f) {
return .{ .inner = .{ .inner = self } };
}
pub fn filter(self: Self, predicate: fn (Item) bool) Iterator(adapters.Filter(Self, predicate)) {
pub fn filter(self: Self, predicate: fn (Item) bool) adapters.Filter(Self, predicate) {
return .{ .inner = .{ .inner = self } };
}
@ -118,18 +118,18 @@ pub fn Iterator(comptime Inner: type) type {
self: Self,
comptime T: type,
f: anytype,
) Iterator(adapters.FilterMap(Self, T, f)) {
) adapters.FilterMap(Self, T, f) {
return .{ .inner = .{ .inner = self } };
}
pub fn take(
self: Self,
n: usize,
) Iterator(adapters.Take(Self)) {
) adapters.Take(Self) {
return .{ .inner = .{ .inner = self, .n = n } };
}
pub fn enumerate(self: Self) Iterator(adapters.Enumerate(Self)) {
pub fn enumerate(self: Self) adapters.Enumerate(Self) {
return .{ .inner = .{ .inner = self } };
}
@ -176,11 +176,11 @@ pub fn Iterator(comptime Inner: type) type {
}.some);
}
pub fn chain(self: Self, other: anytype) Iterator(adapters.Chain(Self, @TypeOf(other))) {
pub fn chain(self: Self, other: anytype) adapters.Chain(Self, @TypeOf(other)) {
return .{ .inner = .{ .first = self, .second = other } };
}
pub fn zip(self: Self, other: anytype) Iterator(adapters.Zip(Self, @TypeOf(other))) {
pub fn zip(self: Self, other: anytype) adapters.Zip(Self, @TypeOf(other)) {
return .{ .inner = .{ .a = self, .b = other } };
}
@ -215,7 +215,7 @@ pub const adapters = struct {
comptime T: type,
comptime f: fn (Inner.Item) T,
) type {
return struct {
return Iterator(struct {
inner: Inner,
pub const Item = T;
@ -225,11 +225,11 @@ pub const adapters = struct {
pub fn next(self: *Self) ?Item {
return if (self.inner.next()) |val| f(val) else null;
}
};
});
}
pub fn Filter(comptime Inner: type, comptime predicate: fn (Inner.Item) bool) type {
return struct {
return Iterator(struct {
inner: Inner,
pub const Item = Inner.Item;
@ -243,11 +243,11 @@ pub const adapters = struct {
return null;
}
};
});
}
pub fn FilterMap(comptime Inner: type, comptime T: type, comptime f: fn (Inner.Item) ?T) type {
return struct {
return Iterator(struct {
inner: Inner,
pub const Item = T;
@ -261,11 +261,11 @@ pub const adapters = struct {
return null;
}
};
});
}
pub fn Take(comptime Inner: type) type {
return struct {
return Iterator(struct {
i: usize = 0,
n: usize,
inner: Inner,
@ -279,11 +279,11 @@ pub const adapters = struct {
defer self.i += 1;
return self.inner.next();
}
};
});
}
pub fn Enumerate(comptime Inner: type) type {
return struct {
return Iterator(struct {
inner: Inner,
i: usize = 0,
@ -299,12 +299,12 @@ pub const adapters = struct {
return null;
}
};
});
}
pub fn Chain(comptime First: type, comptime Second: type) type {
comptime assert(First.Item == Second.Item);
return struct {
return Iterator(struct {
first: First,
second: Second,
@ -319,11 +319,11 @@ pub const adapters = struct {
pub fn sizeHint(self: *const Self) usize {
return self.first.sizeHint() + self.second.sizeHint();
}
};
});
}
pub fn Zip(comptime A: type, comptime B: type) type {
return struct {
return Iterator(struct {
a: A,
b: B,
@ -336,14 +336,14 @@ pub const adapters = struct {
const y = self.b.next() orelse return null;
return .{ x, y };
}
};
});
}
};
pub const RangeEndType = enum { exclusive, inclusive };
pub fn Range(comptime T: type, end_type: RangeEndType) type {
return struct {
return Iterator(struct {
current: T,
end: T,
@ -362,11 +362,11 @@ pub fn Range(comptime T: type, end_type: RangeEndType) type {
pub fn sizeHint(self: *const Self) usize {
return @intCast(self.end - self.current + @intFromBool(end_type == .inclusive));
}
};
});
}
pub fn Once(comptime T: type) type {
return struct {
const Inner = struct {
value: ?T,
pub const Item = T;
@ -382,12 +382,14 @@ pub fn Once(comptime T: type) type {
return @intFromBool(self.value != null);
}
};
return Iterator(Inner);
}
pub const SliceItemType = enum { value, ptr, const_ptr };
pub fn SliceIter(comptime T: type, comptime item_type: SliceItemType) type {
return struct {
const Inner = struct {
slice: switch (item_type) {
.value, .const_ptr => []const T,
.ptr => []T,
@ -415,18 +417,24 @@ pub fn SliceIter(comptime T: type, comptime item_type: SliceItemType) type {
return self.slice.len - self.i;
}
};
return Iterator(Inner);
}
pub fn Empty(comptime T: type) type {
return struct {
const Inner = struct {
pub const Item = T;
pub fn next(_: *Empty(T)) ?Item {
const Self = @This();
pub fn next(_: *Self) ?Item {
return null;
}
pub fn sizeHint(_: *const Empty(T)) usize {
pub fn sizeHint(_: *const Self) usize {
return 0;
}
};
return Iterator(Inner);
}