Some algorithms recursively split an array into smaller fragments. You can build an explicit binary tree, which is obtained from a process where each leaf contains a disjoint slice of the array. If you need to change or rearrange the order of elements in a sheet, its slice must be changed.
enum Tree<'a> {
Branch(Box<[Tree<'a>; 2]>),
Leaf(&'a mut[f32]),
}
Suppose I need to break all leaves that are greater than a certain threshold. Easy: recursively walk the tree from the root; when I find a sheet with a slice long enough, break it into two halves, wrap them in a two-leaf subtree and replace the sheet.
impl<'a> Tree<'a> {
fn split(&mut self, max: usize) {
match self {
&mut Tree::Branch(ref mut trees) => {
trees[0].split(max);
trees[1].split(max);
},
&mut Tree::Leaf(ref mut leaf) if leaf.len() > max => {
let mid = leaf.len() / 2;
let (l, r) = leaf.split_at_mut(mid);
let trees = [Tree::Leaf(l), Tree::Leaf(r)];
*self = Tree::Branch(Box::new(trees));
},
}
}
}
Unfortunately, the borrower cannot find a suitable life time for the template ref mut leaf. He wants him to be dead before allowing the assignment *self, but I don’t see how to make the appointment out of the hands of the match.
?