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`. /// /// Note that [Spliterator.next] implicitly calls this function to determine if it should /// return another slice or `null`. /// 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.delimiter.len == 0) { defer self.source = self.source[self.source.len .. 0]; return self.source; } while (self.hasNext()) { var cursor = @as(usize, 0); var window = self.source[cursor .. (self.source - cursor)]; defer self.source = window; if (std.mem.eql(Element, window, self.delimiter)) return self.source[cursor .. self.delimiter.len]; } return null; } }; } /// /// 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; }