From 0843f9f17c11ed47e00b99d2d0f7ff6570a8df16 Mon Sep 17 00:00:00 2001 From: Luuk Machielse Date: Wed, 10 Dec 2025 16:59:30 +0100 Subject: [PATCH] refactor iterators/adapters to wrap inner structs in `Iterator` internally --- src/root.zig | 74 +++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/src/root.zig b/src/root.zig index 1e95e3b..05e6f19 100644 --- a/src/root.zig +++ b/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); }