authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-01 18:08:40-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-01 18:08:40-05:00
log5575e2a168c07d2dcc0e58146231e490ef8a898e
tree7cd93a54d6012066a9daf63465c40b342946ecdd
parent7b62d5dfd872de8719cc05c2486f77b261e863e9
signature Commit is signed but in an unrecognized format.

std.mem.compare: breaking API changes

* `std.mem.Compare` is now `std.math.Order` and the enum tags renamed to follow new style convention. * `std.mem.compare` is renamed to `std.mem.order`. * new function `std.math.order`

5 files changed, 63 insertions(+), 61 deletions(-)

lib/std/crypto/chacha20.zig+1-1
...@@ -224,7 +224,7 @@ test "crypto.chacha20 test vector sunscreen" {...@@ -224,7 +224,7 @@ test "crypto.chacha20 test vector sunscreen" {
224 // Chacha20 is self-reversing.224 // Chacha20 is self-reversing.
225 var plaintext: [114]u8 = undefined;225 var plaintext: [114]u8 = undefined;
226 chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce);226 chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce);
227 testing.expect(mem.compare(u8, input, &plaintext) == mem.Compare.Equal);227 testing.expect(mem.order(u8, input, &plaintext) == .eq);
228}228}
229229
230// https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7230// https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7
lib/std/http/headers.zig+2-2
...@@ -70,12 +70,12 @@ const HeaderEntry = struct {...@@ -70,12 +70,12 @@ const HeaderEntry = struct {
70 }70 }
7171
72 // Sort lexicographically on header name72 // Sort lexicographically on header name
73 return mem.compare(u8, a.name, b.name) == mem.Compare.LessThan;73 return mem.order(u8, a.name, b.name) == .lt;
74 }74 }
7575
76 // Sort lexicographically on header value76 // Sort lexicographically on header value
77 if (!mem.eql(u8, a.value, b.value)) {77 if (!mem.eql(u8, a.value, b.value)) {
78 return mem.compare(u8, a.value, b.value) == mem.Compare.LessThan;78 return mem.order(u8, a.value, b.value) == .lt;
79 }79 }
8080
81 // Doesn't matter here; need to pick something for sort consistency81 // Doesn't matter here; need to pick something for sort consistency
lib/std/math.zig+27-5
...@@ -926,9 +926,6 @@ test "minInt and maxInt" {...@@ -926,9 +926,6 @@ test "minInt and maxInt" {
926}926}
927927
928test "max value type" {928test "max value type" {
929 // If the type of maxInt(i32) was i32 then this implicit cast to
930 // u32 would not work. But since the value is a number literal,
931 // it works fine.
932 const x: u32 = maxInt(i32);929 const x: u32 = maxInt(i32);
933 testing.expect(x == 2147483647);930 testing.expect(x == 2147483647);
934}931}
...@@ -944,7 +941,32 @@ test "math.mulWide" {...@@ -944,7 +941,32 @@ test "math.mulWide" {
944 testing.expect(mulWide(u8, 100, 100) == 10000);941 testing.expect(mulWide(u8, 100, 100) == 10000);
945}942}
946943
947/// Not to be confused with `std.mem.Compare`.944/// See also `CompareOperator`.
945pub const Order = enum {
946 /// Less than (`<`)
947 lt,
948
949 /// Equal (`==`)
950 eq,
951
952 /// Greater than (`>`)
953 gt,
954};
955
956/// Given two numbers, this function returns the order they are with respect to each other.
957pub fn order(a: var, b: var) Order {
958 if (a == b) {
959 return .eq;
960 } else if (a < b) {
961 return .lt;
962 } else if (a > b) {
963 return .gt;
964 } else {
965 unreachable;
966 }
967}
968
969/// See also `Order`.
948pub const CompareOperator = enum {970pub const CompareOperator = enum {
949 /// Less than (`<`)971 /// Less than (`<`)
950 lt,972 lt,
...@@ -979,7 +1001,7 @@ pub fn compare(a: var, op: CompareOperator, b: var) bool {...@@ -979,7 +1001,7 @@ pub fn compare(a: var, op: CompareOperator, b: var) bool {
979 };1001 };
980}1002}
9811003
982test "math.lt, et al < <= > >= between signed and unsigned" {1004test "compare between signed and unsigned" {
983 testing.expect(compare(@as(i8, -1), .lt, @as(u8, 255)));1005 testing.expect(compare(@as(i8, -1), .lt, @as(u8, 255)));
984 testing.expect(compare(@as(i8, 2), .gt, @as(u8, 1)));1006 testing.expect(compare(@as(i8, 2), .gt, @as(u8, 1)));
985 testing.expect(!compare(@as(i8, -1), .gte, @as(u8, 255)));1007 testing.expect(!compare(@as(i8, -1), .gte, @as(u8, 255)));
lib/std/mem.zig+13-35
...@@ -239,12 +239,6 @@ pub const Allocator = struct {...@@ -239,12 +239,6 @@ pub const Allocator = struct {
239 }239 }
240};240};
241241
242pub const Compare = enum {
243 LessThan,
244 Equal,
245 GreaterThan,
246};
247
248/// Copy all of source into dest at position 0.242/// Copy all of source into dest at position 0.
249/// dest.len must be >= source.len.243/// dest.len must be >= source.len.
250/// dest.ptr must be <= src.ptr.244/// dest.ptr must be <= src.ptr.
...@@ -297,46 +291,30 @@ test "mem.secureZero" {...@@ -297,46 +291,30 @@ test "mem.secureZero" {
297 testing.expectEqualSlices(u8, a[0..], b[0..]);291 testing.expectEqualSlices(u8, a[0..], b[0..]);
298}292}
299293
300pub fn compare(comptime T: type, lhs: []const T, rhs: []const T) Compare {294pub fn order(comptime T: type, lhs: []const T, rhs: []const T) math.Order {
301 const n = math.min(lhs.len, rhs.len);295 const n = math.min(lhs.len, rhs.len);
302 var i: usize = 0;296 var i: usize = 0;
303 while (i < n) : (i += 1) {297 while (i < n) : (i += 1) {
304 if (lhs[i] == rhs[i]) {298 switch (math.order(lhs[i], rhs[i])) {
305 continue;299 .eq => continue,
306 } else if (lhs[i] < rhs[i]) {300 .lt => return .lt,
307 return Compare.LessThan;301 .gt => return .gt,
308 } else if (lhs[i] > rhs[i]) {
309 return Compare.GreaterThan;
310 } else {
311 unreachable;
312 }302 }
313 }303 }
314304 return math.order(lhs.len, rhs.len);
315 if (lhs.len == rhs.len) {
316 return Compare.Equal;
317 } else if (lhs.len < rhs.len) {
318 return Compare.LessThan;
319 } else if (lhs.len > rhs.len) {
320 return Compare.GreaterThan;
321 }
322 unreachable;
323}305}
324306
325test "mem.compare" {307test "order" {
326 testing.expect(compare(u8, "abcd", "bee") == Compare.LessThan);308 testing.expect(order(u8, "abcd", "bee") == .lt);
327 testing.expect(compare(u8, "abc", "abc") == Compare.Equal);309 testing.expect(order(u8, "abc", "abc") == .eq);
328 testing.expect(compare(u8, "abc", "abc0") == Compare.LessThan);310 testing.expect(order(u8, "abc", "abc0") == .lt);
329 testing.expect(compare(u8, "", "") == Compare.Equal);311 testing.expect(order(u8, "", "") == .eq);
330 testing.expect(compare(u8, "", "a") == Compare.LessThan);312 testing.expect(order(u8, "", "a") == .lt);
331}313}
332314
333/// Returns true if lhs < rhs, false otherwise315/// Returns true if lhs < rhs, false otherwise
334pub fn lessThan(comptime T: type, lhs: []const T, rhs: []const T) bool {316pub fn lessThan(comptime T: type, lhs: []const T, rhs: []const T) bool {
335 var result = compare(T, lhs, rhs);317 return order(T, lhs, rhs) == .lt;
336 if (result == Compare.LessThan) {
337 return true;
338 } else
339 return false;
340}318}
341319
342test "mem.lessThan" {320test "mem.lessThan" {
lib/std/rb.zig+20-18
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const std = @import("std.zig");1const std = @import("std.zig");
2const assert = std.debug.assert;2const assert = std.debug.assert;
3const testing = std.testing;3const testing = std.testing;
4const mem = std.mem; // For mem.Compare4const Order = std.math.Order;
55
6const Color = enum(u1) {6const Color = enum(u1) {
7 Black,7 Black,
...@@ -132,7 +132,7 @@ pub const Node = struct {...@@ -132,7 +132,7 @@ pub const Node = struct {
132132
133pub const Tree = struct {133pub const Tree = struct {
134 root: ?*Node,134 root: ?*Node,
135 compareFn: fn (*Node, *Node) mem.Compare,135 compareFn: fn (*Node, *Node) Order,
136136
137 /// If you have a need for a version that caches this, please file a bug.137 /// If you have a need for a version that caches this, please file a bug.
138 pub fn first(tree: *Tree) ?*Node {138 pub fn first(tree: *Tree) ?*Node {
...@@ -389,7 +389,7 @@ pub const Tree = struct {...@@ -389,7 +389,7 @@ pub const Tree = struct {
389 var new = newconst;389 var new = newconst;
390390
391 // I assume this can get optimized out if the caller already knows.391 // I assume this can get optimized out if the caller already knows.
392 if (tree.compareFn(old, new) != mem.Compare.Equal) return ReplaceError.NotEqual;392 if (tree.compareFn(old, new) != .eq) return ReplaceError.NotEqual;
393393
394 if (old.getParent()) |parent| {394 if (old.getParent()) |parent| {
395 parent.setChild(new, parent.left == old);395 parent.setChild(new, parent.left == old);
...@@ -404,7 +404,7 @@ pub const Tree = struct {...@@ -404,7 +404,7 @@ pub const Tree = struct {
404 new.* = old.*;404 new.* = old.*;
405 }405 }
406406
407 pub fn init(tree: *Tree, f: fn (*Node, *Node) mem.Compare) void {407 pub fn init(tree: *Tree, f: fn (*Node, *Node) Order) void {
408 tree.root = null;408 tree.root = null;
409 tree.compareFn = f;409 tree.compareFn = f;
410 }410 }
...@@ -469,19 +469,21 @@ fn doLookup(key: *Node, tree: *Tree, pparent: *?*Node, is_left: *bool) ?*Node {...@@ -469,19 +469,21 @@ fn doLookup(key: *Node, tree: *Tree, pparent: *?*Node, is_left: *bool) ?*Node {
469 is_left.* = false;469 is_left.* = false;
470470
471 while (maybe_node) |node| {471 while (maybe_node) |node| {
472 var res: mem.Compare = tree.compareFn(node, key);472 const res = tree.compareFn(node, key);
473 if (res == mem.Compare.Equal) {473 if (res == .eq) {
474 return node;474 return node;
475 }475 }
476 pparent.* = node;476 pparent.* = node;
477 if (res == mem.Compare.GreaterThan) {477 switch (res) {
478 is_left.* = true;478 .gt => {
479 maybe_node = node.left;479 is_left.* = true;
480 } else if (res == mem.Compare.LessThan) {480 maybe_node = node.left;
481 is_left.* = false;481 },
482 maybe_node = node.right;482 .lt => {
483 } else {483 is_left.* = false;
484 unreachable;484 maybe_node = node.right;
485 },
486 .eq => unreachable, // handled above
485 }487 }
486 }488 }
487 return null;489 return null;
...@@ -496,16 +498,16 @@ fn testGetNumber(node: *Node) *testNumber {...@@ -496,16 +498,16 @@ fn testGetNumber(node: *Node) *testNumber {
496 return @fieldParentPtr(testNumber, "node", node);498 return @fieldParentPtr(testNumber, "node", node);
497}499}
498500
499fn testCompare(l: *Node, r: *Node) mem.Compare {501fn testCompare(l: *Node, r: *Node) Order {
500 var left = testGetNumber(l);502 var left = testGetNumber(l);
501 var right = testGetNumber(r);503 var right = testGetNumber(r);
502504
503 if (left.value < right.value) {505 if (left.value < right.value) {
504 return mem.Compare.LessThan;506 return .lt;
505 } else if (left.value == right.value) {507 } else if (left.value == right.value) {
506 return mem.Compare.Equal;508 return .eq;
507 } else if (left.value > right.value) {509 } else if (left.value > right.value) {
508 return mem.Compare.GreaterThan;510 return .gt;
509 }511 }
510 unreachable;512 unreachable;
511}513}