| ... | ... | @@ -134,6 +134,20 @@ pub const Tree = struct { |
| 134 | 134 | root: ?*Node, |
| 135 | 135 | compareFn: fn (*Node, *Node, *Tree) Order, |
| 136 | 136 | |
| 137 | /// Re-sorts a tree with a new compare function |
| 138 | pub fn sort(tree: *Tree, newCompareFn: fn (*Node, *Node, *Tree) Order) !void { |
| 139 | var newTree = Tree.init(newCompareFn); |
| 140 | var node: *Node = undefined; |
| 141 | while (true) { |
| 142 | node = tree.first() orelse break; |
| 143 | tree.remove(node); |
| 144 | if (newTree.insert(node) != null) { |
| 145 | return error.NotUnique; // EEXISTS |
| 146 | } |
| 147 | } |
| 148 | tree.* = newTree; |
| 149 | } |
| 150 | |
| 137 | 151 | /// If you have a need for a version that caches this, please file a bug. |
| 138 | 152 | pub fn first(tree: *Tree) ?*Node { |
| 139 | 153 | var node: *Node = tree.root orelse return null; |
| ... | ... | @@ -244,6 +258,7 @@ pub const Tree = struct { |
| 244 | 258 | return doLookup(key, tree, &parent, &is_left); |
| 245 | 259 | } |
| 246 | 260 | |
| 261 | /// If node is not part of tree, behavior is undefined. |
| 247 | 262 | pub fn remove(tree: *Tree, nodeconst: *Node) void { |
| 248 | 263 | var node = nodeconst; |
| 249 | 264 | // as this has the same value as node, it is unsafe to access node after newnode |
| ... | ... | @@ -514,6 +529,10 @@ fn testCompare(l: *Node, r: *Node, contextIgnored: *Tree) Order { |
| 514 | 529 | unreachable; |
| 515 | 530 | } |
| 516 | 531 | |
| 532 | fn testCompareReverse(l: *Node, r: *Node, contextIgnored: *Tree) Order { |
| 533 | return testCompare(r, l, contextIgnored); |
| 534 | } |
| 535 | |
| 517 | 536 | test "rb" { |
| 518 | 537 | if (@import("builtin").arch == .aarch64) { |
| 519 | 538 | // TODO https://github.com/ziglang/zig/issues/3288 |
| ... | ... | @@ -600,4 +619,8 @@ test "multiple inserts, followed by calling first and last" { |
| 600 | 619 | var lookupNode: testNumber = undefined; |
| 601 | 620 | lookupNode.value = 3; |
| 602 | 621 | assert(tree.lookup(&lookupNode.node) == &third.node); |
| 622 | tree.sort(testCompareReverse) catch unreachable; |
| 623 | assert(testGetNumber(tree.first().?).value == 3); |
| 624 | assert(testGetNumber(tree.last().?).value == 0); |
| 625 | assert(tree.lookup(&lookupNode.node) == &third.node); |
| 603 | 626 | } |