diff options
| author | Isaac Freund <ifreund@ifreund.xyz> | 2020-07-08 23:07:44 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-07-12 22:17:40 +0000 |
| commit | ef17af1270155e803a77955c9f37175dd09c43d4 (patch) | |
| tree | 6acbd18cdd280d95e10f45b75df45da7cdb704cf /lib/std | |
| parent | 5b570bceb531656c320684fbe42a87feff710a3b (diff) | |
| download | zig-ef17af1270155e803a77955c9f37175dd09c43d4.tar.gz zig-ef17af1270155e803a77955c9f37175dd09c43d4.zip | |
std: add mem.joinZ
currently the only options are doing a second allocation and copying or
implementing this yourself.
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/mem.zig | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 2f17a83422..0fbe96942e 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -1674,12 +1674,23 @@ pub const SplitIterator = struct { /// Naively combines a series of slices with a separator. /// Allocates memory for the result, which must be freed by the caller. pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []const u8) ![]u8 { + return joinMaybeZ(allocator, separator, slices, false); +} + +/// Naively combines a series of slices with a separator and null terminator. +/// Allocates memory for the result, which must be freed by the caller. +pub fn joinZ(allocator: *Allocator, separator: []const u8, slices: []const []const u8) ![:0]u8 { + const out = try joinMaybeZ(allocator, separator, slices, true); + return out[0 .. out.len - 1 :0]; +} + +fn joinMaybeZ(allocator: *Allocator, separator: []const u8, slices: []const []const u8, zero: bool) ![]u8 { if (slices.len == 0) return &[0]u8{}; const total_len = blk: { var sum: usize = separator.len * (slices.len - 1); - for (slices) |slice| - sum += slice.len; + for (slices) |slice| sum += slice.len; + if (zero) sum += 1; break :blk sum; }; @@ -1695,6 +1706,8 @@ pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []cons buf_index += slice.len; } + if (zero) buf[buf.len - 1] = 0; + // No need for shrink since buf is exactly the correct size. return buf; } @@ -1717,6 +1730,27 @@ test "mem.join" { } } +test "mem.joinZ" { + { + const str = try joinZ(testing.allocator, ",", &[_][]const u8{ "a", "b", "c" }); + defer testing.allocator.free(str); + testing.expect(eql(u8, str, "a,b,c")); + testing.expectEqual(str[str.len], 0); + } + { + const str = try joinZ(testing.allocator, ",", &[_][]const u8{"a"}); + defer testing.allocator.free(str); + testing.expect(eql(u8, str, "a")); + testing.expectEqual(str[str.len], 0); + } + { + const str = try joinZ(testing.allocator, ",", &[_][]const u8{ "a", "", "b", "", "c" }); + defer testing.allocator.free(str); + testing.expect(eql(u8, str, "a,,b,,c")); + testing.expectEqual(str[str.len], 0); + } +} + /// Copies each T from slices into a new slice that exactly holds all the elements. pub fn concat(allocator: *Allocator, comptime T: type, slices: []const []const T) ![]T { if (slices.len == 0) return &[0]T{}; |
