Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const std = @import("std");
- const warn = std.debug.warn;
- fn Iterator(comptime T: type) type {
- return struct {
- const Self = this;
- next_fn: fn(self: &Self) ?T,
- fn next(self: &Self) ?T {
- return self.next_fn(self);
- }
- };
- }
- fn filter(comptime predicate: var) {
- const FnType = @typeOf(predicate);
- if (@typeId(FnType) != TypeId.Fn) {
- @compileError("Filter expect a function paramater");
- }
- if (FnType.arg_count != 1) {
- @compileError("Filter expects a function with one argument.");
- }
- if (FnType.ReturnType != bool) {
- @compileError("Filter expect a function that returns a bool");
- }
- const T = @ArgType(FnType, 0);
- //both Iterators have the same `items`, whatever you wanna call it.
- const InputIt = Iterator(T);
- const OutputIt = Iterator(T);
- return struct {
- const Self = this;
- it: OutputIt,
- input_it: &InPutIt,
- fn init(input_it: &InputIt) Self {
- return Self {
- .it = OutPutIt {
- .next_fn = next,
- },
- .input_it = InputIt,
- };
- }
- fn next(it: &OutPutIt) ?T {
- const self = @fieldParentPtr(Self, "it", it);
- const val = self.input_it.next() ?? return null;
- if (predicate(val)) {
- return val;
- }
- return null;
- }
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment