authorgravatar for mariorules24@gmail.comKyle Coffey <mariorules24@gmail.com> 2023-05-10 09:47:58-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-05-10 17:47:58+03:00
logebc3773542ef2bccedd268cfa42ee2cdd529210a
tree50e816fdfcfc0206cbbe0d13d39d24de6012068f
parent6d7bb255a45ab89e08ab1981b48898ae7e6bef88
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Add std.mem.indexOfNone

This introduces a parallel set of functions to the std.mem.indexOfAny functions. They simply invert the logic, yielding the first/last index which is *not* contained in the "values" slice. Inverting this logic is useful when you are attempting to determine the initial span which contains only characters in a particular set. * Document the `indexOfNone` family. These descriptions are somewhat brief, but the functions themselves are also simple enough to describe in such a way.

1 files changed, 48 insertions(+), 0 deletions(-)

lib/std/mem.zig+48
......@@ -1013,6 +1013,54 @@ pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, val
10131013 return null;
10141014}
10151015
1016/// Find the first item in `slice` which is not contained in `values`.
1017///
1018/// Comparable to `strspn` in the C standard library.
1019pub fn indexOfNone(comptime T: type, slice: []const T, values: []const T) ?usize {
1020 return indexOfNonePos(T, slice, 0, values);
1021}
1022
1023/// Find the last item in `slice` which is not contained in `values`.
1024///
1025/// Like `strspn` in the C standard library, but searches from the end.
1026pub fn lastIndexOfNone(comptime T: type, slice: []const T, values: []const T) ?usize {
1027 var i: usize = slice.len;
1028 outer: while (i != 0) {
1029 i -= 1;
1030 for (values) |value| {
1031 if (slice[i] == value) continue :outer;
1032 }
1033 return i;
1034 }
1035 return null;
1036}
1037
1038/// Find the first item in `slice[start_index..]` which is not contained in `values`.
1039/// The returned index will be relative to the start of `slice`, and never less than `start_index`.
1040///
1041/// Comparable to `strspn` in the C standard library.
1042pub fn indexOfNonePos(comptime T: type, slice: []const T, start_index: usize, values: []const T) ?usize {
1043 var i: usize = start_index;
1044 outer: while (i < slice.len) : (i += 1) {
1045 for (values) |value| {
1046 if (slice[i] == value) continue :outer;
1047 }
1048 return i;
1049 }
1050 return null;
1051}
1052
1053test "indexOfNone" {
1054 try testing.expect(indexOfNone(u8, "abc123", "123").? == 0);
1055 try testing.expect(lastIndexOfNone(u8, "abc123", "123").? == 2);
1056 try testing.expect(indexOfNone(u8, "123abc", "123").? == 3);
1057 try testing.expect(lastIndexOfNone(u8, "123abc", "123").? == 5);
1058 try testing.expect(indexOfNone(u8, "123123", "123") == null);
1059 try testing.expect(indexOfNone(u8, "333333", "123") == null);
1060
1061 try testing.expect(indexOfNonePos(u8, "abc123", 3, "321") == null);
1062}
1063
10161064pub fn indexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize {
10171065 return indexOfPos(T, haystack, 0, needle);
10181066}