Skip to content

Commit 14e227d

Browse files
committed
std.mem: add cutLast and cutScalarLast
1 parent 97bef50 commit 14e227d

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

lib/std/mem.zig

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ fn lenSliceTo(ptr: anytype, comptime end: std.meta.Elem(@TypeOf(ptr))) usize {
10171017
return indexOfSentinel(array_info.child, end, ptr);
10181018
}
10191019
}
1020-
return indexOfScalar(array_info.child, ptr, end) orelse array_info.len;
1020+
return findScalar(array_info.child, ptr, end) orelse array_info.len;
10211021
},
10221022
else => {},
10231023
},
@@ -1042,7 +1042,7 @@ fn lenSliceTo(ptr: anytype, comptime end: std.meta.Elem(@TypeOf(ptr))) usize {
10421042
return indexOfSentinel(ptr_info.child, s, ptr);
10431043
}
10441044
}
1045-
return indexOfScalar(ptr_info.child, ptr, end) orelse ptr.len;
1045+
return findScalar(ptr_info.child, ptr, end) orelse ptr.len;
10461046
},
10471047
},
10481048
else => {},
@@ -1229,7 +1229,7 @@ pub fn allEqual(comptime T: type, slice: []const T, scalar: T) bool {
12291229
/// Remove a set of values from the beginning of a slice.
12301230
pub fn trimStart(comptime T: type, slice: []const T, values_to_strip: []const T) []const T {
12311231
var begin: usize = 0;
1232-
while (begin < slice.len and indexOfScalar(T, values_to_strip, slice[begin]) != null) : (begin += 1) {}
1232+
while (begin < slice.len and findScalar(T, values_to_strip, slice[begin]) != null) : (begin += 1) {}
12331233
return slice[begin..];
12341234
}
12351235

@@ -1243,7 +1243,7 @@ pub const trimLeft = trimStart;
12431243
/// Remove a set of values from the end of a slice.
12441244
pub fn trimEnd(comptime T: type, slice: []const T, values_to_strip: []const T) []const T {
12451245
var end: usize = slice.len;
1246-
while (end > 0 and indexOfScalar(T, values_to_strip, slice[end - 1]) != null) : (end -= 1) {}
1246+
while (end > 0 and findScalar(T, values_to_strip, slice[end - 1]) != null) : (end -= 1) {}
12471247
return slice[0..end];
12481248
}
12491249

@@ -1258,8 +1258,8 @@ pub const trimRight = trimEnd;
12581258
pub fn trim(comptime T: type, slice: []const T, values_to_strip: []const T) []const T {
12591259
var begin: usize = 0;
12601260
var end: usize = slice.len;
1261-
while (begin < end and indexOfScalar(T, values_to_strip, slice[begin]) != null) : (begin += 1) {}
1262-
while (end > begin and indexOfScalar(T, values_to_strip, slice[end - 1]) != null) : (end -= 1) {}
1261+
while (begin < end and findScalar(T, values_to_strip, slice[begin]) != null) : (begin += 1) {}
1262+
while (end > begin and findScalar(T, values_to_strip, slice[end - 1]) != null) : (end -= 1) {}
12631263
return slice[begin..end];
12641264
}
12651265

@@ -3145,15 +3145,15 @@ test cutSuffix {
31453145
try testing.expectEqual(null, cutSuffix(u8, "foobar", "baz"));
31463146
}
31473147

3148-
/// Returns slice of `haystack` before and after `needle`, or `null` if not
3149-
/// found.
3148+
/// Returns slice of `haystack` before and after first occurrence of `needle`,
3149+
/// or `null` if not found.
31503150
///
31513151
/// See also:
31523152
/// * `cutScalar`
31533153
/// * `split`
31543154
/// * `tokenizeAny`
31553155
pub fn cut(comptime T: type, haystack: []const T, needle: []const T) ?struct { []const T, []const T } {
3156-
const index = indexOf(T, haystack, needle) orelse return null;
3156+
const index = find(T, haystack, needle) orelse return null;
31573157
return .{ haystack[0..index], haystack[index + needle.len ..] };
31583158
}
31593159

@@ -3164,15 +3164,33 @@ test cut {
31643164
try testing.expectEqualStrings(" c", after);
31653165
}
31663166

3167-
/// Returns slice of `haystack` before and after `needle`, or `null` if not
3168-
/// found.
3167+
/// Returns slice of `haystack` before and after last occurrence of `needle`,
3168+
/// or `null` if not found.
3169+
///
3170+
/// See also:
3171+
/// * `cut`
3172+
/// * `cutScalarLast`
3173+
pub fn cutLast(comptime T: type, haystack: []const T, needle: []const T) ?struct { []const T, []const T } {
3174+
const index = findLast(T, haystack, needle) orelse return null;
3175+
return .{ haystack[0..index], haystack[index + needle.len ..] };
3176+
}
3177+
3178+
test cutLast {
3179+
try testing.expectEqual(null, cutLast(u8, "a b c", "B"));
3180+
const before, const after = cutLast(u8, "a be c be d", "be") orelse return error.TestFailed;
3181+
try testing.expectEqualStrings("a be c ", before);
3182+
try testing.expectEqualStrings(" d", after);
3183+
}
3184+
3185+
/// Returns slice of `haystack` before and after first occurrence `needle`, or
3186+
/// `null` if not found.
31693187
///
31703188
/// See also:
31713189
/// * `cut`
31723190
/// * `splitScalar`
31733191
/// * `tokenizeScalar`
31743192
pub fn cutScalar(comptime T: type, haystack: []const T, needle: T) ?struct { []const T, []const T } {
3175-
const index = indexOfScalar(T, haystack, needle) orelse return null;
3193+
const index = findScalar(T, haystack, needle) orelse return null;
31763194
return .{ haystack[0..index], haystack[index + 1 ..] };
31773195
}
31783196

@@ -3183,6 +3201,25 @@ test cutScalar {
31833201
try testing.expectEqualStrings(" c", after);
31843202
}
31853203

3204+
/// Returns slice of `haystack` before and after last occurrence of `needle`,
3205+
/// or `null` if not found.
3206+
///
3207+
/// See also:
3208+
/// * `cut`
3209+
/// * `splitScalar`
3210+
/// * `tokenizeScalar`
3211+
pub fn cutScalarLast(comptime T: type, haystack: []const T, needle: T) ?struct { []const T, []const T } {
3212+
const index = findScalarLast(T, haystack, needle) orelse return null;
3213+
return .{ haystack[0..index], haystack[index + 1 ..] };
3214+
}
3215+
3216+
test cutScalarLast {
3217+
try testing.expectEqual(null, cutScalarLast(u8, "a b c", 'B'));
3218+
const before, const after = cutScalarLast(u8, "a b c b d", 'b') orelse return error.TestFailed;
3219+
try testing.expectEqualStrings("a b c ", before);
3220+
try testing.expectEqualStrings(" d", after);
3221+
}
3222+
31863223
/// Delimiter type for tokenization and splitting operations.
31873224
pub const DelimiterType = enum { sequence, any, scalar };
31883225

src/main.zig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,9 +1057,8 @@ fn buildOutputType(
10571057
fatal("unexpected end-of-parameter mark: --", .{});
10581058
}
10591059
} else if (mem.eql(u8, arg, "--dep")) {
1060-
var it = mem.splitScalar(u8, args_iter.nextOrFatal(), '=');
1061-
const key = it.first();
1062-
const value = if (it.peek() != null) it.rest() else key;
1060+
const next_arg = args_iter.nextOrFatal();
1061+
const key, const value = mem.cutScalar(u8, next_arg, '=') orelse .{ next_arg, next_arg };
10631062
if (mem.eql(u8, key, "std") and !mem.eql(u8, value, "std")) {
10641063
fatal("unable to import as '{s}': conflicts with builtin module", .{
10651064
key,

0 commit comments

Comments
 (0)