diff --git a/lib/std/crypto/chacha20.zig b/lib/std/crypto/chacha20.zig index 8a0f677660..d67877b051 100644 --- a/lib/std/crypto/chacha20.zig +++ b/lib/std/crypto/chacha20.zig @@ -224,7 +224,7 @@ test "crypto.chacha20 test vector sunscreen" { // Chacha20 is self-reversing. var plaintext: [114]u8 = undefined; chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce); - testing.expect(mem.compare(u8, input, &plaintext) == mem.Compare.Equal); + testing.expect(mem.order(u8, input, &plaintext) == .eq); } // https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7 diff --git a/lib/std/http/headers.zig b/lib/std/http/headers.zig index 588ee7f796..b1d047aeec 100644 --- a/lib/std/http/headers.zig +++ b/lib/std/http/headers.zig @@ -70,12 +70,12 @@ const HeaderEntry = struct { } // Sort lexicographically on header name - return mem.compare(u8, a.name, b.name) == mem.Compare.LessThan; + return mem.order(u8, a.name, b.name) == .lt; } // Sort lexicographically on header value if (!mem.eql(u8, a.value, b.value)) { - return mem.compare(u8, a.value, b.value) == mem.Compare.LessThan; + return mem.order(u8, a.value, b.value) == .lt; } // Doesn't matter here; need to pick something for sort consistency diff --git a/lib/std/math.zig b/lib/std/math.zig index a12bf5f4e9..051dc341a2 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -926,9 +926,6 @@ test "minInt and maxInt" { } test "max value type" { - // If the type of maxInt(i32) was i32 then this implicit cast to - // u32 would not work. But since the value is a number literal, - // it works fine. const x: u32 = maxInt(i32); testing.expect(x == 2147483647); } @@ -944,7 +941,32 @@ test "math.mulWide" { testing.expect(mulWide(u8, 100, 100) == 10000); } -/// Not to be confused with `std.mem.Compare`. +/// See also `CompareOperator`. +pub const Order = enum { + /// Less than (`<`) + lt, + + /// Equal (`==`) + eq, + + /// Greater than (`>`) + gt, +}; + +/// Given two numbers, this function returns the order they are with respect to each other. +pub fn order(a: var, b: var) Order { + if (a == b) { + return .eq; + } else if (a < b) { + return .lt; + } else if (a > b) { + return .gt; + } else { + unreachable; + } +} + +/// See also `Order`. pub const CompareOperator = enum { /// Less than (`<`) lt, @@ -979,7 +1001,7 @@ pub fn compare(a: var, op: CompareOperator, b: var) bool { }; } -test "math.lt, et al < <= > >= between signed and unsigned" { +test "compare between signed and unsigned" { testing.expect(compare(@as(i8, -1), .lt, @as(u8, 255))); testing.expect(compare(@as(i8, 2), .gt, @as(u8, 1))); testing.expect(!compare(@as(i8, -1), .gte, @as(u8, 255))); diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 133e3b8a2d..48f4a68a5e 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -239,12 +239,6 @@ pub const Allocator = struct { } }; -pub const Compare = enum { - LessThan, - Equal, - GreaterThan, -}; - /// Copy all of source into dest at position 0. /// dest.len must be >= source.len. /// dest.ptr must be <= src.ptr. @@ -297,46 +291,30 @@ test "mem.secureZero" { testing.expectEqualSlices(u8, a[0..], b[0..]); } -pub fn compare(comptime T: type, lhs: []const T, rhs: []const T) Compare { +pub fn order(comptime T: type, lhs: []const T, rhs: []const T) math.Order { const n = math.min(lhs.len, rhs.len); var i: usize = 0; while (i < n) : (i += 1) { - if (lhs[i] == rhs[i]) { - continue; - } else if (lhs[i] < rhs[i]) { - return Compare.LessThan; - } else if (lhs[i] > rhs[i]) { - return Compare.GreaterThan; - } else { - unreachable; + switch (math.order(lhs[i], rhs[i])) { + .eq => continue, + .lt => return .lt, + .gt => return .gt, } } - - if (lhs.len == rhs.len) { - return Compare.Equal; - } else if (lhs.len < rhs.len) { - return Compare.LessThan; - } else if (lhs.len > rhs.len) { - return Compare.GreaterThan; - } - unreachable; + return math.order(lhs.len, rhs.len); } -test "mem.compare" { - testing.expect(compare(u8, "abcd", "bee") == Compare.LessThan); - testing.expect(compare(u8, "abc", "abc") == Compare.Equal); - testing.expect(compare(u8, "abc", "abc0") == Compare.LessThan); - testing.expect(compare(u8, "", "") == Compare.Equal); - testing.expect(compare(u8, "", "a") == Compare.LessThan); +test "order" { + testing.expect(order(u8, "abcd", "bee") == .lt); + testing.expect(order(u8, "abc", "abc") == .eq); + testing.expect(order(u8, "abc", "abc0") == .lt); + testing.expect(order(u8, "", "") == .eq); + testing.expect(order(u8, "", "a") == .lt); } /// Returns true if lhs < rhs, false otherwise pub fn lessThan(comptime T: type, lhs: []const T, rhs: []const T) bool { - var result = compare(T, lhs, rhs); - if (result == Compare.LessThan) { - return true; - } else - return false; + return order(T, lhs, rhs) == .lt; } test "mem.lessThan" { diff --git a/lib/std/rb.zig b/lib/std/rb.zig index 4180c7459c..c41a269a27 100644 --- a/lib/std/rb.zig +++ b/lib/std/rb.zig @@ -1,7 +1,7 @@ const std = @import("std.zig"); const assert = std.debug.assert; const testing = std.testing; -const mem = std.mem; // For mem.Compare +const Order = std.math.Order; const Color = enum(u1) { Black, @@ -132,7 +132,7 @@ pub const Node = struct { pub const Tree = struct { root: ?*Node, - compareFn: fn (*Node, *Node) mem.Compare, + compareFn: fn (*Node, *Node) Order, /// If you have a need for a version that caches this, please file a bug. pub fn first(tree: *Tree) ?*Node { @@ -389,7 +389,7 @@ pub const Tree = struct { var new = newconst; // I assume this can get optimized out if the caller already knows. - if (tree.compareFn(old, new) != mem.Compare.Equal) return ReplaceError.NotEqual; + if (tree.compareFn(old, new) != .eq) return ReplaceError.NotEqual; if (old.getParent()) |parent| { parent.setChild(new, parent.left == old); @@ -404,7 +404,7 @@ pub const Tree = struct { new.* = old.*; } - pub fn init(tree: *Tree, f: fn (*Node, *Node) mem.Compare) void { + pub fn init(tree: *Tree, f: fn (*Node, *Node) Order) void { tree.root = null; tree.compareFn = f; } @@ -469,19 +469,21 @@ fn doLookup(key: *Node, tree: *Tree, pparent: *?*Node, is_left: *bool) ?*Node { is_left.* = false; while (maybe_node) |node| { - var res: mem.Compare = tree.compareFn(node, key); - if (res == mem.Compare.Equal) { + const res = tree.compareFn(node, key); + if (res == .eq) { return node; } pparent.* = node; - if (res == mem.Compare.GreaterThan) { - is_left.* = true; - maybe_node = node.left; - } else if (res == mem.Compare.LessThan) { - is_left.* = false; - maybe_node = node.right; - } else { - unreachable; + switch (res) { + .gt => { + is_left.* = true; + maybe_node = node.left; + }, + .lt => { + is_left.* = false; + maybe_node = node.right; + }, + .eq => unreachable, // handled above } } return null; @@ -496,16 +498,16 @@ fn testGetNumber(node: *Node) *testNumber { return @fieldParentPtr(testNumber, "node", node); } -fn testCompare(l: *Node, r: *Node) mem.Compare { +fn testCompare(l: *Node, r: *Node) Order { var left = testGetNumber(l); var right = testGetNumber(r); if (left.value < right.value) { - return mem.Compare.LessThan; + return .lt; } else if (left.value == right.value) { - return mem.Compare.Equal; + return .eq; } else if (left.value > right.value) { - return mem.Compare.GreaterThan; + return .gt; } unreachable; }