impl<K: Clone + Ord, V: Clone> BTreeClone for BTreeMap<K, V> {
fn clone_from(&mut self, other: &Self) {
// This truncates `self` to `other.len()` by calling `split_off` on
- // the first key after `other.len()` elements if it exists
+ // the first key after `other.len()` elements if it exists.
let split_off_key = if self.len() > other.len() {
let diff = self.len() - other.len();
if diff <= other.len() {
// After truncation, `self` is at most as long as `other` so this loop
// replaces every key-value pair in `self`. Since `oiter` is in sorted
// order and the structure of the `BTreeMap` stays the same,
- // the BTree invariants are maintained at the end of the loop
+ // the BTree invariants are maintained at the end of the loop.
while !siter.is_empty() {
if let Some((ok, ov)) = oiter.next() {
- // SAFETY: This is safe because the `siter.front != siter.back` check
- // ensures that `siter` is nonempty
+ // SAFETY: This is safe because `siter` is nonempty.
let (sk, sv) = unsafe { siter.next_unchecked() };
sk.clone_from(ok);
sv.clone_from(ov);
break;
}
}
- // If `other` is longer than `self`, the remaining elements are inserted
+ // If `other` is longer than `self`, the remaining elements are inserted.
self.extend(oiter.map(|(k, v)| ((*k).clone(), (*v).clone())));
}
}
#[stable(feature = "btree_drop", since = "1.7.0")]
impl<K, V> Drop for IntoIter<K, V> {
fn drop(&mut self) {
- self.for_each(drop);
+ struct DropGuard<'a, K, V>(&'a mut IntoIter<K, V>);
+
+ impl<'a, K, V> Drop for DropGuard<'a, K, V> {
+ fn drop(&mut self) {
+ // Continue the same loop we perform below. This only runs when unwinding, so we
+ // don't have to care about panics this time (they'll abort).
+ while let Some(_) = self.0.next() {}
+ }
+ }
+
+ while let Some(pair) = self.next() {
+ let guard = DropGuard(self);
+ drop(pair);
+ mem::forget(guard);
+ }
+
unsafe {
let leaf_node = ptr::read(&self.front).into_node();
if leaf_node.is_shared_root() {