From 98dd8856ef901b99f198d992146abd0545adb5b2 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Fri, 3 Oct 2025 14:22:11 -0700 Subject: [PATCH] std.mem: Add `countScalar` --- build.zig | 2 +- lib/std/mem.zig | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/build.zig b/build.zig index c57c3e713a..7208d1fbb9 100644 --- a/build.zig +++ b/build.zig @@ -260,7 +260,7 @@ pub fn build(b: *std.Build) !void { }; const git_describe = mem.trim(u8, git_describe_untrimmed, " \n\r"); - switch (mem.count(u8, git_describe, "-")) { + switch (mem.countScalar(u8, git_describe, '-')) { 0 => { // Tagged release version (e.g. 0.10.0). if (!mem.eql(u8, git_describe, version_string)) { diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 3cd0507bee..3763de5180 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -1704,6 +1704,26 @@ test count { try testing.expect(count(u8, "owowowu", "owowu") == 1); } +/// Returns the number of needles inside the haystack +pub fn countScalar(comptime T: type, haystack: []const T, needle: T) usize { + var i: usize = 0; + var found: usize = 0; + + while (findScalarPos(T, haystack, i, needle)) |idx| { + i = idx + 1; + found += 1; + } + + return found; +} + +test countScalar { + try testing.expectEqual(0, countScalar(u8, "", 'h')); + try testing.expectEqual(1, countScalar(u8, "h", 'h')); + try testing.expectEqual(2, countScalar(u8, "hh", 'h')); + try testing.expectEqual(3, countScalar(u8, " abcabc abc", 'b')); +} + /// Returns true if the haystack contains expected_count or more needles /// needle.len must be > 0 /// does not count overlapping needles