An iterator interface
Emulating interfaces by providing an implementation and overriding functions.
const std = @import("std");
const IteratorImplementation = struct {
containerType: type,
valueType: type,
baseImpl: type,
};
fn Iterator(implementation: IteratorImplementation) type {
const containerType = implementation.containerType;
const valueType = implementation.valueType;
const baseImpl = implementation.baseImpl;
return struct {
const next = baseImpl.next;
const sum = if (@hasDecl(baseImpl, "sum")) baseImpl.sum else (struct {
fn impl(it: *containerType) valueType {
var res: valueType = 0;
while (next(it)) |val| {
res += val;
}
return res;
}
}).impl;
};
}
test "Iterator" {
const MyImpl = Iterator(.{
.containerType = []const f64,
.valueType = f64,
.baseImpl = struct {
fn next(it: *[]const f64) ?f64 {
if (it.*.len == 0) {
return null;
} else {
defer it.* = it.*[1..];
return it.*[0];
}
}
},
});
var x: []const f64 = &.{ 3.141, 1.0, -42.0 };
std.debug.print("{}\n", .{MyImpl.sum(&x)});
}
Test with: zig test iter.zig
$ zig test iter.zig
-37.859
All 1 tests passed.