| ... | @@ -654,10 +654,14 @@ const eqlBytes_allowed = switch (builtin.zig_backend) { | ... | @@ -654,10 +654,14 @@ const eqlBytes_allowed = switch (builtin.zig_backend) { |
| 654 | else => !builtin.fuzz, | 654 | else => !builtin.fuzz, |
| 655 | }; | 655 | }; |
| 656 | | 656 | |
| 657 | /// Compares two slices and returns whether they are equal. | 657 | /// Returns true if and only if the slices have the same length and all elements |
| | 658 | /// compare true using equality operator. |
| 658 | pub fn eql(comptime T: type, a: []const T, b: []const T) bool { | 659 | pub fn eql(comptime T: type, a: []const T, b: []const T) bool { |
| 659 | if (@sizeOf(T) == 0) return true; | 660 | if (!@inComptime() and @sizeOf(T) != 0 and std.meta.hasUniqueRepresentation(T) and |
| 660 | if (!@inComptime() and std.meta.hasUniqueRepresentation(T) and eqlBytes_allowed) return eqlBytes(sliceAsBytes(a), sliceAsBytes(b)); | 661 | eqlBytes_allowed) |
| | 662 | { |
| | 663 | return eqlBytes(sliceAsBytes(a), sliceAsBytes(b)); |
| | 664 | } |
| 661 | | 665 | |
| 662 | if (a.len != b.len) return false; | 666 | if (a.len != b.len) return false; |
| 663 | if (a.len == 0 or a.ptr == b.ptr) return true; | 667 | if (a.len == 0 or a.ptr == b.ptr) return true; |
| ... | @@ -668,6 +672,25 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { | ... | @@ -668,6 +672,25 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { |
| 668 | return true; | 672 | return true; |
| 669 | } | 673 | } |
| 670 | | 674 | |
| | 675 | test eql { |
| | 676 | try testing.expect(eql(u8, "abcd", "abcd")); |
| | 677 | try testing.expect(!eql(u8, "abcdef", "abZdef")); |
| | 678 | try testing.expect(!eql(u8, "abcdefg", "abcdef")); |
| | 679 | |
| | 680 | comptime { |
| | 681 | try testing.expect(eql(type, &.{ bool, f32 }, &.{ bool, f32 })); |
| | 682 | try testing.expect(!eql(type, &.{ bool, f32 }, &.{ f32, bool })); |
| | 683 | try testing.expect(!eql(type, &.{ bool, f32 }, &.{bool})); |
| | 684 | |
| | 685 | try testing.expect(eql(comptime_int, &.{ 1, 2, 3 }, &.{ 1, 2, 3 })); |
| | 686 | try testing.expect(!eql(comptime_int, &.{ 1, 2, 3 }, &.{ 3, 2, 1 })); |
| | 687 | try testing.expect(!eql(comptime_int, &.{1}, &.{ 1, 2 })); |
| | 688 | } |
| | 689 | |
| | 690 | try testing.expect(eql(void, &.{ {}, {} }, &.{ {}, {} })); |
| | 691 | try testing.expect(!eql(void, &.{{}}, &.{ {}, {} })); |
| | 692 | } |
| | 693 | |
| 671 | /// std.mem.eql heavily optimized for slices of bytes. | 694 | /// std.mem.eql heavily optimized for slices of bytes. |
| 672 | fn eqlBytes(a: []const u8, b: []const u8) bool { | 695 | fn eqlBytes(a: []const u8, b: []const u8) bool { |
| 673 | comptime assert(eqlBytes_allowed); | 696 | comptime assert(eqlBytes_allowed); |
| ... | @@ -3292,12 +3315,6 @@ test concat { | ... | @@ -3292,12 +3315,6 @@ test concat { |
| 3292 | } | 3315 | } |
| 3293 | } | 3316 | } |
| 3294 | | 3317 | |
| 3295 | test eql { | | |
| 3296 | try testing.expect(eql(u8, "abcd", "abcd")); | | |
| 3297 | try testing.expect(!eql(u8, "abcdef", "abZdef")); | | |
| 3298 | try testing.expect(!eql(u8, "abcdefg", "abcdef")); | | |
| 3299 | } | | |
| 3300 | | | |
| 3301 | fn moreReadIntTests() !void { | 3318 | fn moreReadIntTests() !void { |
| 3302 | { | 3319 | { |
| 3303 | const bytes = [_]u8{ | 3320 | const bytes = [_]u8{ |