about summary refs log tree commit diff
path: root/library/alloc/src
diff options
context:
space:
mode:
authorStein Somers <git@steinsomers.be>2020-08-09 12:25:20 +0200
committerStein Somers <git@steinsomers.be>2020-09-25 11:29:38 +0200
commit396552457033925010df3eccbee21bdff2aa1122 (patch)
treefcd66dc3b16dc1876044d2028dd0ac92fb94ef97 /library/alloc/src
parent1e64d98761c4713f739656bcff218dbdb1b08ad9 (diff)
downloadrust-396552457033925010df3eccbee21bdff2aa1122.tar.gz
rust-396552457033925010df3eccbee21bdff2aa1122.zip
BTreeMap: introduce edge methods similar to those of keys and values
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/collections/btree/node.rs58
1 files changed, 34 insertions, 24 deletions
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index a141c1d08e2..3ce5dfbc4dc 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -351,7 +351,22 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
     unsafe fn val_at(&self, idx: usize) -> &V {
         unsafe { self.reborrow().into_val_at(idx) }
     }
+}
 
+impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> {
+    /// Borrows a reference to the contents of one of the edges that delimit
+    /// the elements of the node, without invalidating other references.
+    ///
+    /// # Safety
+    /// The node has more than `idx` initialized elements.
+    unsafe fn edge_at(&self, idx: usize) -> &BoxedNode<K, V> {
+        debug_assert!(idx <= self.len());
+        let node = self.as_internal_ptr();
+        unsafe { (*node).edges.get_unchecked(idx).assume_init_ref() }
+    }
+}
+
+impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
     /// Finds the parent of the current node. Returns `Ok(handle)` if the current
     /// node actually has a parent, where `handle` points to the edge of the parent
     /// that points to the current node. Returns `Err(self)` if the current node has
@@ -498,6 +513,17 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
     }
 }
 
+impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
+    fn edges_mut(&mut self) -> &mut [BoxedNode<K, V>] {
+        unsafe {
+            slice::from_raw_parts_mut(
+                MaybeUninit::slice_as_mut_ptr(&mut self.as_internal_mut().edges),
+                self.len() + 1,
+            )
+        }
+    }
+}
+
 impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
     /// # Safety
     /// The node has more than `idx` initialized elements.
@@ -669,9 +695,8 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
             let val = ptr::read(self.val_at(idx));
             let edge = match self.reborrow_mut().force() {
                 ForceResult::Leaf(_) => None,
-                ForceResult::Internal(mut internal) => {
-                    let edge =
-                        ptr::read(internal.as_internal().edges.get_unchecked(idx + 1).as_ptr());
+                ForceResult::Internal(internal) => {
+                    let edge = ptr::read(internal.edge_at(idx + 1));
                     let mut new_root = Root { node: edge, height: internal.height - 1 };
                     new_root.node_as_mut().as_leaf_mut().parent = None;
                     Some(new_root)
@@ -696,14 +721,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
             let edge = match self.reborrow_mut().force() {
                 ForceResult::Leaf(_) => None,
                 ForceResult::Internal(mut internal) => {
-                    let edge = slice_remove(
-                        slice::from_raw_parts_mut(
-                            MaybeUninit::slice_as_mut_ptr(&mut internal.as_internal_mut().edges),
-                            old_len + 1,
-                        ),
-                        0,
-                    );
-
+                    let edge = slice_remove(internal.edges_mut(), 0);
                     let mut new_root = Root { node: edge, height: internal.height - 1 };
                     new_root.node_as_mut().as_leaf_mut().parent = None;
 
@@ -972,17 +990,9 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
         debug_assert!(edge.height == self.node.height - 1);
 
         unsafe {
+            slice_insert(self.node.edges_mut(), self.idx + 1, edge.node);
             self.leafy_insert_fit(key, val);
 
-            slice_insert(
-                slice::from_raw_parts_mut(
-                    MaybeUninit::slice_as_mut_ptr(&mut self.node.as_internal_mut().edges),
-                    self.node.len(),
-                ),
-                self.idx + 1,
-                edge.node,
-            );
-
             self.node.correct_childrens_parent_links((self.idx + 1)..=self.node.len());
         }
     }
@@ -1253,7 +1263,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
                 right_len,
             );
 
-            slice_remove(&mut self.node.as_internal_mut().edges, self.idx + 1);
+            slice_remove(&mut self.node.edges_mut(), self.idx + 1);
             let self_len = self.node.len();
             self.node.correct_childrens_parent_links(self.idx + 1..self_len);
             self.node.as_leaf_mut().len -= 1;
@@ -1264,10 +1274,10 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
                 // SAFETY: the height of the nodes being merged is one below the height
                 // of the node of this edge, thus above zero, so they are internal.
                 let mut left_node = left_node.cast_unchecked::<marker::Internal>();
-                let mut right_node = right_node.cast_unchecked::<marker::Internal>();
+                let right_node = right_node.cast_unchecked::<marker::Internal>();
                 ptr::copy_nonoverlapping(
-                    right_node.as_internal().edges.as_ptr(),
-                    left_node.as_internal_mut().edges.as_mut_ptr().add(left_len + 1),
+                    right_node.edge_at(0),
+                    left_node.edges_mut().as_mut_ptr().add(left_len + 1),
                     right_len + 1,
                 );