From ac32359f085875837007b575a7b52339df017a7b Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 11 Feb 2019 11:58:56 +0100 Subject: [PATCH] Relax some Ord bounds on BinaryHeap Notably, iterators don't require any trait bounds to be iterated. --- src/liballoc/collections/binary_heap.rs | 488 ++++++++++++------------ 1 file changed, 244 insertions(+), 244 deletions(-) diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 3b94379b58f8f..5074d5f5a1e30 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -294,7 +294,7 @@ impl Default for BinaryHeap { } #[stable(feature = "binaryheap_debug", since = "1.4.0")] -impl fmt::Debug for BinaryHeap { +impl fmt::Debug for BinaryHeap { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.iter()).finish() } @@ -336,49 +336,6 @@ impl BinaryHeap { BinaryHeap { data: Vec::with_capacity(capacity) } } - /// Returns an iterator visiting all values in the underlying vector, in - /// arbitrary order. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::collections::BinaryHeap; - /// let heap = BinaryHeap::from(vec![1, 2, 3, 4]); - /// - /// // Print 1, 2, 3, 4 in arbitrary order - /// for x in heap.iter() { - /// println!("{}", x); - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter(&self) -> Iter<'_, T> { - Iter { iter: self.data.iter() } - } - - /// Returns the greatest item in the binary heap, or `None` if it is empty. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::collections::BinaryHeap; - /// let mut heap = BinaryHeap::new(); - /// assert_eq!(heap.peek(), None); - /// - /// heap.push(1); - /// heap.push(5); - /// heap.push(2); - /// assert_eq!(heap.peek(), Some(&5)); - /// - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn peek(&self) -> Option<&T> { - self.data.get(0) - } - /// Returns a mutable reference to the greatest item in the binary heap, or /// `None` if it is empty. /// @@ -415,119 +372,6 @@ impl BinaryHeap { } } - /// Returns the number of elements the binary heap can hold without reallocating. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::collections::BinaryHeap; - /// let mut heap = BinaryHeap::with_capacity(100); - /// assert!(heap.capacity() >= 100); - /// heap.push(4); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn capacity(&self) -> usize { - self.data.capacity() - } - - /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the - /// given `BinaryHeap`. Does nothing if the capacity is already sufficient. - /// - /// Note that the allocator may give the collection more space than it requests. Therefore - /// capacity can not be relied upon to be precisely minimal. Prefer [`reserve`] if future - /// insertions are expected. - /// - /// # Panics - /// - /// Panics if the new capacity overflows `usize`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::collections::BinaryHeap; - /// let mut heap = BinaryHeap::new(); - /// heap.reserve_exact(100); - /// assert!(heap.capacity() >= 100); - /// heap.push(4); - /// ``` - /// - /// [`reserve`]: #method.reserve - #[stable(feature = "rust1", since = "1.0.0")] - pub fn reserve_exact(&mut self, additional: usize) { - self.data.reserve_exact(additional); - } - - /// Reserves capacity for at least `additional` more elements to be inserted in the - /// `BinaryHeap`. The collection may reserve more space to avoid frequent reallocations. - /// - /// # Panics - /// - /// Panics if the new capacity overflows `usize`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::collections::BinaryHeap; - /// let mut heap = BinaryHeap::new(); - /// heap.reserve(100); - /// assert!(heap.capacity() >= 100); - /// heap.push(4); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn reserve(&mut self, additional: usize) { - self.data.reserve(additional); - } - - /// Discards as much additional capacity as possible. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::collections::BinaryHeap; - /// let mut heap: BinaryHeap = BinaryHeap::with_capacity(100); - /// - /// assert!(heap.capacity() >= 100); - /// heap.shrink_to_fit(); - /// assert!(heap.capacity() == 0); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn shrink_to_fit(&mut self) { - self.data.shrink_to_fit(); - } - - /// Discards capacity with a lower bound. - /// - /// The capacity will remain at least as large as both the length - /// and the supplied value. - /// - /// Panics if the current capacity is smaller than the supplied - /// minimum capacity. - /// - /// # Examples - /// - /// ``` - /// #![feature(shrink_to)] - /// use std::collections::BinaryHeap; - /// let mut heap: BinaryHeap = BinaryHeap::with_capacity(100); - /// - /// assert!(heap.capacity() >= 100); - /// heap.shrink_to(10); - /// assert!(heap.capacity() >= 10); - /// ``` - #[inline] - #[unstable(feature = "shrink_to", reason = "new API", issue="56431")] - pub fn shrink_to(&mut self, min_capacity: usize) { - self.data.shrink_to(min_capacity) - } - /// Removes the greatest item from the binary heap and returns it, or `None` if it /// is empty. /// @@ -577,28 +421,6 @@ impl BinaryHeap { self.sift_up(0, old_len); } - /// Consumes the `BinaryHeap` and returns the underlying vector - /// in arbitrary order. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::collections::BinaryHeap; - /// let heap = BinaryHeap::from(vec![1, 2, 3, 4, 5, 6, 7]); - /// let vec = heap.into_vec(); - /// - /// // Will print in some order - /// for x in vec { - /// println!("{}", x); - /// } - /// ``` - #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] - pub fn into_vec(self) -> Vec { - self.into() - } - /// Consumes the `BinaryHeap` and returns a vector in sorted /// (ascending) order. /// @@ -703,6 +525,247 @@ impl BinaryHeap { self.sift_up(start, pos); } + fn rebuild(&mut self) { + let mut n = self.len() / 2; + while n > 0 { + n -= 1; + self.sift_down(n); + } + } + + /// Moves all the elements of `other` into `self`, leaving `other` empty. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::collections::BinaryHeap; + /// + /// let v = vec![-10, 1, 2, 3, 3]; + /// let mut a = BinaryHeap::from(v); + /// + /// let v = vec![-20, 5, 43]; + /// let mut b = BinaryHeap::from(v); + /// + /// a.append(&mut b); + /// + /// assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]); + /// assert!(b.is_empty()); + /// ``` + #[stable(feature = "binary_heap_append", since = "1.11.0")] + pub fn append(&mut self, other: &mut Self) { + if self.len() < other.len() { + swap(self, other); + } + + if other.is_empty() { + return; + } + + #[inline(always)] + fn log2_fast(x: usize) -> usize { + 8 * size_of::() - (x.leading_zeros() as usize) - 1 + } + + // `rebuild` takes O(len1 + len2) operations + // and about 2 * (len1 + len2) comparisons in the worst case + // while `extend` takes O(len2 * log_2(len1)) operations + // and about 1 * len2 * log_2(len1) comparisons in the worst case, + // assuming len1 >= len2. + #[inline] + fn better_to_rebuild(len1: usize, len2: usize) -> bool { + 2 * (len1 + len2) < len2 * log2_fast(len1) + } + + if better_to_rebuild(self.len(), other.len()) { + self.data.append(&mut other.data); + self.rebuild(); + } else { + self.extend(other.drain()); + } + } +} + +impl BinaryHeap { + /// Returns an iterator visiting all values in the underlying vector, in + /// arbitrary order. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::collections::BinaryHeap; + /// let heap = BinaryHeap::from(vec![1, 2, 3, 4]); + /// + /// // Print 1, 2, 3, 4 in arbitrary order + /// for x in heap.iter() { + /// println!("{}", x); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter(&self) -> Iter<'_, T> { + Iter { iter: self.data.iter() } + } + + /// Returns the greatest item in the binary heap, or `None` if it is empty. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::collections::BinaryHeap; + /// let mut heap = BinaryHeap::new(); + /// assert_eq!(heap.peek(), None); + /// + /// heap.push(1); + /// heap.push(5); + /// heap.push(2); + /// assert_eq!(heap.peek(), Some(&5)); + /// + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn peek(&self) -> Option<&T> { + self.data.get(0) + } + + /// Returns the number of elements the binary heap can hold without reallocating. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::collections::BinaryHeap; + /// let mut heap = BinaryHeap::with_capacity(100); + /// assert!(heap.capacity() >= 100); + /// heap.push(4); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn capacity(&self) -> usize { + self.data.capacity() + } + + /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the + /// given `BinaryHeap`. Does nothing if the capacity is already sufficient. + /// + /// Note that the allocator may give the collection more space than it requests. Therefore + /// capacity can not be relied upon to be precisely minimal. Prefer [`reserve`] if future + /// insertions are expected. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `usize`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::collections::BinaryHeap; + /// let mut heap = BinaryHeap::new(); + /// heap.reserve_exact(100); + /// assert!(heap.capacity() >= 100); + /// heap.push(4); + /// ``` + /// + /// [`reserve`]: #method.reserve + #[stable(feature = "rust1", since = "1.0.0")] + pub fn reserve_exact(&mut self, additional: usize) { + self.data.reserve_exact(additional); + } + + /// Reserves capacity for at least `additional` more elements to be inserted in the + /// `BinaryHeap`. The collection may reserve more space to avoid frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `usize`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::collections::BinaryHeap; + /// let mut heap = BinaryHeap::new(); + /// heap.reserve(100); + /// assert!(heap.capacity() >= 100); + /// heap.push(4); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn reserve(&mut self, additional: usize) { + self.data.reserve(additional); + } + + /// Discards as much additional capacity as possible. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::collections::BinaryHeap; + /// let mut heap: BinaryHeap = BinaryHeap::with_capacity(100); + /// + /// assert!(heap.capacity() >= 100); + /// heap.shrink_to_fit(); + /// assert!(heap.capacity() == 0); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn shrink_to_fit(&mut self) { + self.data.shrink_to_fit(); + } + + /// Discards capacity with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::collections::BinaryHeap; + /// let mut heap: BinaryHeap = BinaryHeap::with_capacity(100); + /// + /// assert!(heap.capacity() >= 100); + /// heap.shrink_to(10); + /// assert!(heap.capacity() >= 10); + /// ``` + #[inline] + #[unstable(feature = "shrink_to", reason = "new API", issue="56431")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.data.shrink_to(min_capacity) + } + + /// Consumes the `BinaryHeap` and returns the underlying vector + /// in arbitrary order. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::collections::BinaryHeap; + /// let heap = BinaryHeap::from(vec![1, 2, 3, 4, 5, 6, 7]); + /// let vec = heap.into_vec(); + /// + /// // Will print in some order + /// for x in vec { + /// println!("{}", x); + /// } + /// ``` + #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] + pub fn into_vec(self) -> Vec { + self.into() + } + /// Returns the length of the binary heap. /// /// # Examples @@ -789,67 +852,6 @@ impl BinaryHeap { pub fn clear(&mut self) { self.drain(); } - - fn rebuild(&mut self) { - let mut n = self.len() / 2; - while n > 0 { - n -= 1; - self.sift_down(n); - } - } - - /// Moves all the elements of `other` into `self`, leaving `other` empty. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::collections::BinaryHeap; - /// - /// let v = vec![-10, 1, 2, 3, 3]; - /// let mut a = BinaryHeap::from(v); - /// - /// let v = vec![-20, 5, 43]; - /// let mut b = BinaryHeap::from(v); - /// - /// a.append(&mut b); - /// - /// assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]); - /// assert!(b.is_empty()); - /// ``` - #[stable(feature = "binary_heap_append", since = "1.11.0")] - pub fn append(&mut self, other: &mut Self) { - if self.len() < other.len() { - swap(self, other); - } - - if other.is_empty() { - return; - } - - #[inline(always)] - fn log2_fast(x: usize) -> usize { - 8 * size_of::() - (x.leading_zeros() as usize) - 1 - } - - // `rebuild` takes O(len1 + len2) operations - // and about 2 * (len1 + len2) comparisons in the worst case - // while `extend` takes O(len2 * log_2(len1)) operations - // and about 1 * len2 * log_2(len1) comparisons in the worst case, - // assuming len1 >= len2. - #[inline] - fn better_to_rebuild(len1: usize, len2: usize) -> bool { - 2 * (len1 + len2) < len2 * log2_fast(len1) - } - - if better_to_rebuild(self.len(), other.len()) { - self.data.append(&mut other.data); - self.rebuild(); - } else { - self.extend(other.drain()); - } - } } /// Hole represents a hole in a slice i.e., an index without valid value @@ -1111,7 +1113,7 @@ impl FromIterator for BinaryHeap { } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for BinaryHeap { +impl IntoIterator for BinaryHeap { type Item = T; type IntoIter = IntoIter; @@ -1139,9 +1141,7 @@ impl IntoIterator for BinaryHeap { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a BinaryHeap - where T: Ord -{ +impl<'a, T> IntoIterator for &'a BinaryHeap { type Item = &'a T; type IntoIter = Iter<'a, T>;