pub fn peekable(iterator: anytype) Peekable(@TypeOf(iterator)) { return .{ .iterator = iterator }; } pub fn Peekable(Iterator: type) type { const ActualIterator = switch (@typeInfo(Iterator)) { .pointer => |p| p.child, else => Iterator, }; const Next = @typeInfo(@TypeOf(ActualIterator.next)).@"fn"; const Item = switch (@typeInfo(Next.return_type.?)) { .optional => |o| o.child, else => |i| i, }; return struct { iterator: Iterator, peeked: ?Item = null, pub fn peek(self: *Self) ?Item { if (self.peeked) |peeked| return peeked; const item = self.iterator.next(); self.peeked = item; return item; } pub fn next(self: *Self) ?Item { const item = if (self.peeked) |peeked| peeked else self.iterator.next(); self.peeked = null; return item; } const Self = @This(); }; } test peekable { const expect = std.testing.expect; // std.meta.de var it = std.mem.window(u8, &[_]u8{ 1, 2, 3 }, 1, 1); var peek = peekable(&it); try expect(peek.next().?[0] == 1); try expect(peek.peek().?[0] == 2); try expect(peek.peek().?[0] == 2); try expect(peek.next().?[0] == 2); try expect(peek.next().?[0] == 3); try expect(peek.peek() == null); try expect(peek.next() == null); } const std = @import("std");