diff --git a/src/liballoc/collections/binary_heap/mod.rs b/src/liballoc/collections/binary_heap/mod.rs index 7168db5..297801c 100644 --- a/src/liballoc/collections/binary_heap/mod.rs +++ b/src/liballoc/collections/binary_heap/mod.rs @@ -153,7 +153,6 @@ use alloc::slice; use alloc::vec::{self, Vec}; use cfg_if::cfg_if; -use super::SpecExtend; use crate::{ default::{OrdStoredKey, OrdTotalOrder}, SortableBy, SortableByWithOrder, TotalOrder, @@ -408,6 +407,17 @@ impl fmt::Debug for BinaryHeap { } } +struct RebuildOnDrop<'a, T: SortableByWithOrder, O: TotalOrder> { + heap: &'a mut BinaryHeap, + rebuild_from: usize, +} + +impl<'a, T: SortableByWithOrder, O: TotalOrder> Drop for RebuildOnDrop<'a, T, O> { + fn drop(&mut self) { + self.heap.rebuild_tail(self.rebuild_from); + } +} + impl, O: TotalOrder> BinaryHeap { /// Creates an empty `BinaryHeap` as a max-heap. /// @@ -849,30 +859,19 @@ impl, O: TotalOrder> BinaryHeap { where F: FnMut(&T) -> bool, { - struct RebuildOnDrop<'a, T: SortableByWithOrder, O: TotalOrder> { - heap: &'a mut BinaryHeap, - first_removed: usize, - } - - let mut guard = RebuildOnDrop { first_removed: self.len(), heap: self }; - + // rebuild_start will be updated to the first touched element below, and the rebuild will + // only be done for the tail. + let mut guard = RebuildOnDrop { rebuild_from: self.len(), heap: self }; let mut i = 0; + guard.heap.data.retain(|e| { let keep = f(e); - if !keep && i < guard.first_removed { - guard.first_removed = i; + if !keep && i < guard.rebuild_from { + guard.rebuild_from = i; } i += 1; keep }); - - impl<'a, T: SortableByWithOrder, O: TotalOrder> Drop for RebuildOnDrop<'a, T, O> { - fn drop(&mut self) { - // data[..first_removed] is untouched, so we only need to - // rebuild the tail: - self.heap.rebuild_tail(self.first_removed); - } - } } #[doc(hidden)] @@ -1739,7 +1738,8 @@ impl<'a, T, O> IntoIterator for &'a BinaryHeap { impl, O: TotalOrder> Extend for BinaryHeap { #[inline] fn extend>(&mut self, iter: I) { - >::spec_extend(self, iter); + let guard = RebuildOnDrop { rebuild_from: self.len(), heap: self }; + guard.heap.data.extend(iter); } #[inline] @@ -1755,47 +1755,6 @@ impl, O: TotalOrder> Extend for BinaryHeap { } } -cfg_if! { - if #[cfg(feature = "specialization")] { - impl, O: TotalOrder, I: IntoIterator> SpecExtend for BinaryHeap { - default fn spec_extend(&mut self, iter: I) { - self.extend_desugared(iter.into_iter()); - } - } - - impl, O: TotalOrder> SpecExtend> for BinaryHeap { - fn spec_extend(&mut self, ref mut other: Vec) { - let start = self.data.len(); - self.data.append(other); - self.rebuild_tail(start); - } - } - - impl, O: TotalOrder> SpecExtend> for BinaryHeap { - fn spec_extend(&mut self, ref mut other: BinaryHeap) { - self.append(other); - } - } - } else { - impl, O: TotalOrder, I: IntoIterator> SpecExtend for BinaryHeap { - fn spec_extend(&mut self, iter: I) { - self.extend_desugared(iter.into_iter()); - } - } - } -} - -impl, O: TotalOrder> BinaryHeap { - fn extend_desugared>(&mut self, iter: I) { - let iterator = iter.into_iter(); - let (lower, _) = iterator.size_hint(); - - self.reserve(lower); - - iterator.for_each(move |elem| self.push(elem)); - } -} - impl<'a, T: 'a + SortableByWithOrder + Copy, O: TotalOrder> Extend<&'a T> for BinaryHeap { fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned());