const std = @import("std"); /// /// State machine for lazily computing all components of [Spliterator.source] that match the pattern /// in [Spliterator.delimiter]. /// pub fn Spliterator(comptime Element: type) type { return struct { source: []const Element, delimiter: []const Element, const Self = @This(); /// /// Returns `true` if there is more data to be processed, otherwise `false`. /// pub fn hasNext(self: Self) bool { return (self.source.len != 0); } /// /// Iterates on `self` and returns the next view of [Spliterator.source] that matches /// [Spliterator.delimiter], or `null` if there is no more data to be processed. /// pub fn next(self: *Self) ?[]const Element { if (!self.hasNext()) return null; if (std.mem.indexOfPos(Element, self.source, 0, self.delimiter)) |index| { defer self.source = self.source[(index + self.delimiter.len) .. self.source.len]; return self.source[0 .. index]; } defer self.source = self.source[self.source.len .. self.source.len]; return self.source; } }; } test { const testing = std.testing; // Single-character delimiter. { var spliterator = Spliterator(u8){ .source = "single.character.separated.hello.world", .delimiter = ".", }; const components = [_][]const u8{"single", "character", "separated", "hello", "world"}; var index = @as(usize, 0); while (spliterator.next()) |split| : (index += 1) { try testing.expect(std.mem.eql(u8, split, components[index])); } } // Multi-character delimiter. { var spliterator = Spliterator(u8){ .source = "finding a needle in a needle stack", .delimiter = "needle", }; const components = [_][]const u8{"finding a ", " in a ", " stack"}; var index = @as(usize, 0); while (spliterator.next()) |split| : (index += 1) { try testing.expect(std.mem.eql(u8, split, components[index])); } } } /// /// Searches the slice of `Data` referenced by `data` for the first instance of `sought_datum`, /// returning its index or `null` if it could not be found. /// pub fn findFirst(comptime Data: type, data: []const Data, sought_datum: Data) ?usize { for (data) |datum, index| if (datum == sought_datum) return index; return null; } test { try std.testing.expectEqual(findFirst(u8, "1234567890", '7'), 6); }