Function eql [src]
Compares two of any type for equality. Containers that do not support comparison
on their own are compared on a field-by-field basis. Pointers are not followed.
Prototype
pub fn eql(a: anytype, b: @TypeOf(a)) bool
Parameters
b: @TypeOf(a)
Example
test eql {
const S = struct {
a: u32,
b: f64,
c: [5]u8,
};
const U = union(enum) {
s: S,
f: ?f32,
};
const s_1 = S{
.a = 134,
.b = 123.3,
.c = "12345".*,
};
var s_3 = S{
.a = 134,
.b = 123.3,
.c = "12345".*,
};
const u_1 = U{ .f = 24 };
const u_2 = U{ .s = s_1 };
const u_3 = U{ .f = 24 };
try testing.expect(eql(s_1, s_3));
try testing.expect(eql(&s_1, &s_1));
try testing.expect(!eql(&s_1, &s_3));
try testing.expect(eql(u_1, u_3));
try testing.expect(!eql(u_1, u_2));
const a1 = "abcdef".*;
const a2 = "abcdef".*;
const a3 = "ghijkl".*;
try testing.expect(eql(a1, a2));
try testing.expect(!eql(a1, a3));
const EU = struct {
fn tst(err: bool) !u8 {
if (err) return error.Error;
return @as(u8, 5);
}
};
try testing.expect(eql(EU.tst(true), EU.tst(true)));
try testing.expect(eql(EU.tst(false), EU.tst(false)));
try testing.expect(!eql(EU.tst(false), EU.tst(true)));
const V = @Vector(4, u32);
const v1: V = @splat(1);
const v2: V = @splat(1);
const v3: V = @splat(2);
try testing.expect(eql(v1, v2));
try testing.expect(!eql(v1, v3));
const CU = union(enum) {
a: void,
b: void,
c: comptime_int,
};
try testing.expect(eql(CU{ .a = {} }, .a));
try testing.expect(!eql(CU{ .a = {} }, .b));
}
Source
pub fn eql(a: anytype, b: @TypeOf(a)) bool {
const T = @TypeOf(a);
switch (@typeInfo(T)) {
.@"struct" => |info| {
if (info.layout == .@"packed") return a == b;
inline for (info.fields) |field_info| {
if (!eql(@field(a, field_info.name), @field(b, field_info.name))) return false;
}
return true;
},
.error_union => {
if (a) |a_p| {
if (b) |b_p| return eql(a_p, b_p) else |_| return false;
} else |a_e| {
if (b) |_| return false else |b_e| return a_e == b_e;
}
},
.@"union" => |info| {
if (info.tag_type) |UnionTag| {
const tag_a: UnionTag = a;
const tag_b: UnionTag = b;
if (tag_a != tag_b) return false;
return switch (a) {
inline else => |val, tag| return eql(val, @field(b, @tagName(tag))),
};
}
@compileError("cannot compare untagged union type " ++ @typeName(T));
},
.array => {
if (a.len != b.len) return false;
for (a, 0..) |e, i|
if (!eql(e, b[i])) return false;
return true;
},
.vector => |info| {
var i: usize = 0;
while (i < info.len) : (i += 1) {
if (!eql(a[i], b[i])) return false;
}
return true;
},
.pointer => |info| {
return switch (info.size) {
.one, .many, .c => a == b,
.slice => a.ptr == b.ptr and a.len == b.len,
};
},
.optional => {
if (a == null and b == null) return true;
if (a == null or b == null) return false;
return eql(a.?, b.?);
},
else => return a == b,
}
}