mirror of
https://codeberg.org/kaasboteram/zig-iterating.git
synced 2025-12-14 17:23:15 +01:00
refactor iterators/adapters to wrap inner structs in Iterator internally
This commit is contained in:
parent
1e9bd2454e
commit
0843f9f17c
1 changed files with 41 additions and 33 deletions
74
src/root.zig
74
src/root.zig
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue