ona/src/mem.zig

59 lines
1.8 KiB
Zig
Raw Normal View History

2022-09-25 00:09:02 +02:00
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;
}