blob: 58911e934a7d86291e797e41ec8b148fc98781f4 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
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");
|