| ... | @@ -269,6 +269,39 @@ pub fn copyBackwards(comptime T: type, dest: []T, source: []const T) void { | ... | @@ -269,6 +269,39 @@ pub fn copyBackwards(comptime T: type, dest: []T, source: []const T) void { |
| 269 | } | 269 | } |
| 270 | } | 270 | } |
| 271 | | 271 | |
| | 272 | /// Copy `source` into `dest`, excluding the sentinel. |
| | 273 | /// |
| | 274 | /// Asserts no overlap. Asserts `dest.len` greater or equal to source len. Returns number of elements copied, |
| | 275 | /// not counting the sentinel. |
| | 276 | pub fn copySentinel(comptime T: type, comptime s: T, dest: []T, source: [*:s]const T) usize { |
| | 277 | const i = findSentinel(T, s, source); |
| | 278 | @memcpy(dest[0..i], source[0..i]); |
| | 279 | return i; |
| | 280 | } |
| | 281 | |
| | 282 | test copySentinel { |
| | 283 | var dst: [11]u8 = @splat(0xff); |
| | 284 | const n = copySentinel(u8, 0, &dst, "hello this\x00is my null-terminated string"); |
| | 285 | try testing.expectEqualStrings("hello this\xff", &dst); |
| | 286 | try testing.expectEqual(n, 10); |
| | 287 | } |
| | 288 | |
| | 289 | /// Copy `source` into `dest`, including the sentinel. |
| | 290 | /// |
| | 291 | /// Asserts no overlap. Asserts `dest.len` greater or equal to source len, including room for the sentinel. |
| | 292 | /// Returns number of elements copied, including the sentinel. |
| | 293 | pub fn copySentinelInclusive(comptime T: type, comptime s: T, dest: []T, source: [*:s]const T) usize { |
| | 294 | const i = findSentinel(T, s, source) + 1; |
| | 295 | @memcpy(dest[0..i], source[0..i]); |
| | 296 | return i; |
| | 297 | } |
| | 298 | |
| | 299 | test copySentinelInclusive { |
| | 300 | var dst: [12]u8 = @splat(0xff); |
| | 301 | const n = copySentinelInclusive(u8, 0, &dst, "hello this\x00is my null-terminated string"); |
| | 302 | try testing.expectEqualStrings("hello this\x00\xff", &dst); |
| | 303 | try testing.expectEqual(n, 11); |
| | 304 | } |
| 272 | /// Generally, Zig users are encouraged to explicitly initialize all fields of a struct explicitly rather than using this function. | 305 | /// Generally, Zig users are encouraged to explicitly initialize all fields of a struct explicitly rather than using this function. |
| 273 | /// However, it is recognized that there are sometimes use cases for initializing all fields to a "zero" value. For example, when | 306 | /// However, it is recognized that there are sometimes use cases for initializing all fields to a "zero" value. For example, when |
| 274 | /// interfacing with a C API where this practice is more common and relied upon. If you are performing code review and see this | 307 | /// interfacing with a C API where this practice is more common and relied upon. If you are performing code review and see this |
| ... | @@ -733,6 +766,19 @@ test lessThan { | ... | @@ -733,6 +766,19 @@ test lessThan { |
| 733 | try testing.expect(lessThan(u8, "", "a")); | 766 | try testing.expect(lessThan(u8, "", "a")); |
| 734 | } | 767 | } |
| 735 | | 768 | |
| | 769 | /// Returns `true` if `lhs < rhs`; `false` otherwise, operating on null-terminated arrays. |
| | 770 | pub fn lessThanZ(comptime T: type, lhs: [*:0]const T, rhs: [*:0]const T) bool { |
| | 771 | return orderZ(T, lhs, rhs) == .lt; |
| | 772 | } |
| | 773 | |
| | 774 | test lessThanZ { |
| | 775 | try testing.expect(lessThanZ(u8, "abcd", "bee")); |
| | 776 | try testing.expect(!lessThanZ(u8, "abc", "abc")); |
| | 777 | try testing.expect(lessThanZ(u8, "abc", "abc0")); |
| | 778 | try testing.expect(!lessThanZ(u8, "", "")); |
| | 779 | try testing.expect(lessThanZ(u8, "", "a")); |
| | 780 | } |
| | 781 | |
| 736 | const use_vectors = switch (builtin.zig_backend) { | 782 | const use_vectors = switch (builtin.zig_backend) { |
| 737 | // These backends don't support vectors yet. | 783 | // These backends don't support vectors yet. |
| 738 | .stage2_aarch64, | 784 | .stage2_aarch64, |