From a3122b8138e9c972cb3ef84fb90744be48fe2add Mon Sep 17 00:00:00 2001 From: yanchith Date: Sat, 16 Jul 2022 18:38:03 +0200 Subject: [PATCH 1/9] Parametrize BinaryHeap with Allocator --- library/alloc/src/collections/binary_heap.rs | 156 +++++++++++++------ 1 file changed, 111 insertions(+), 45 deletions(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 197e7aaaccf3d..97f0c1eeb0de0 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -143,12 +143,14 @@ #![allow(missing_docs)] #![stable(feature = "rust1", since = "1.0.0")] +use core::alloc::Allocator; use core::fmt; use core::iter::{FromIterator, FusedIterator, InPlaceIterable, SourceIter, TrustedLen}; use core::mem::{self, swap, ManuallyDrop}; use core::ops::{Deref, DerefMut}; use core::ptr; +use crate::alloc::Global; use crate::collections::TryReserveError; use crate::slice; use crate::vec::{self, AsVecIntoIter, Vec}; @@ -265,8 +267,11 @@ mod tests; /// [peek\_mut]: BinaryHeap::peek_mut #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "BinaryHeap")] -pub struct BinaryHeap { - data: Vec, +pub struct BinaryHeap< + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + data: Vec, } /// Structure wrapping a mutable reference to the greatest item on a @@ -277,20 +282,24 @@ pub struct BinaryHeap { /// /// [`peek_mut`]: BinaryHeap::peek_mut #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -pub struct PeekMut<'a, T: 'a + Ord> { - heap: &'a mut BinaryHeap, +pub struct PeekMut< + 'a, + T: 'a + Ord, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global, +> { + heap: &'a mut BinaryHeap, sift: bool, } #[stable(feature = "collection_debug", since = "1.17.0")] -impl fmt::Debug for PeekMut<'_, T> { +impl fmt::Debug for PeekMut<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("PeekMut").field(&self.heap.data[0]).finish() } } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl Drop for PeekMut<'_, T> { +impl Drop for PeekMut<'_, T, A> { fn drop(&mut self) { if self.sift { // SAFETY: PeekMut is only instantiated for non-empty heaps. @@ -300,7 +309,7 @@ impl Drop for PeekMut<'_, T> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl Deref for PeekMut<'_, T> { +impl Deref for PeekMut<'_, T, A> { type Target = T; fn deref(&self) -> &T { debug_assert!(!self.heap.is_empty()); @@ -310,7 +319,7 @@ impl Deref for PeekMut<'_, T> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl DerefMut for PeekMut<'_, T> { +impl DerefMut for PeekMut<'_, T, A> { fn deref_mut(&mut self) -> &mut T { debug_assert!(!self.heap.is_empty()); self.sift = true; @@ -330,7 +339,7 @@ impl<'a, T: Ord> PeekMut<'a, T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for BinaryHeap { +impl Clone for BinaryHeap { fn clone(&self) -> Self { BinaryHeap { data: self.data.clone() } } @@ -350,13 +359,13 @@ 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() } } -impl BinaryHeap { +impl BinaryHeap { /// Creates an empty `BinaryHeap` as a max-heap. /// /// # Examples @@ -394,6 +403,52 @@ impl BinaryHeap { pub fn with_capacity(capacity: usize) -> BinaryHeap { BinaryHeap { data: Vec::with_capacity(capacity) } } +} + +impl BinaryHeap { + /// Creates an empty `BinaryHeap` as a max-heap, using `A` as allocator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// use std::collections::BinaryHeap; + /// let mut heap = BinaryHeap::new_in(System); + /// heap.push(4); + /// ``` + #[unstable(feature = "allocator_api", issue = "32838")] + #[must_use] + pub fn new_in(alloc: A) -> BinaryHeap { + BinaryHeap { data: Vec::new_in(alloc) } + } + + /// Creates an empty `BinaryHeap` with at least the specified capacity, using `A` as allocator. + /// + /// The binary heap will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is 0, the binary heap will not allocate. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// use std::collections::BinaryHeap; + /// let mut heap = BinaryHeap::with_capacity_in(10, System); + /// heap.push(4); + /// ``` + #[unstable(feature = "allocator_api", issue = "32838")] + #[must_use] + pub fn with_capacity_in(capacity: usize, alloc: A) -> BinaryHeap { + BinaryHeap { data: Vec::with_capacity_in(capacity, alloc) } + } /// Returns a mutable reference to the greatest item in the binary heap, or /// `None` if it is empty. @@ -425,7 +480,7 @@ impl BinaryHeap { /// If the item is modified then the worst case time complexity is *O*(log(*n*)), /// otherwise it's *O*(1). #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] - pub fn peek_mut(&mut self) -> Option> { + pub fn peek_mut(&mut self) -> Option> { if self.is_empty() { None } else { Some(PeekMut { heap: self, sift: false }) } } @@ -520,7 +575,7 @@ impl BinaryHeap { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] - pub fn into_sorted_vec(mut self) -> Vec { + pub fn into_sorted_vec(mut self) -> Vec { let mut end = self.len(); while end > 1 { end -= 1; @@ -778,7 +833,7 @@ impl BinaryHeap { /// ``` #[inline] #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] - pub fn drain_sorted(&mut self) -> DrainSorted<'_, T> { + pub fn drain_sorted(&mut self) -> DrainSorted<'_, T, A> { DrainSorted { inner: self } } @@ -821,7 +876,7 @@ impl BinaryHeap { } } -impl BinaryHeap { +impl BinaryHeap { /// Returns an iterator visiting all values in the underlying vector, in /// arbitrary order. /// @@ -858,7 +913,7 @@ impl BinaryHeap { /// assert_eq!(heap.into_iter_sorted().take(2).collect::>(), [5, 4]); /// ``` #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] - pub fn into_iter_sorted(self) -> IntoIterSorted { + pub fn into_iter_sorted(self) -> IntoIterSorted { IntoIterSorted { inner: self } } @@ -1124,7 +1179,7 @@ impl BinaryHeap { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] - pub fn into_vec(self) -> Vec { + pub fn into_vec(self) -> Vec { self.into() } @@ -1195,7 +1250,7 @@ impl BinaryHeap { /// ``` #[inline] #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self) -> Drain<'_, T> { + pub fn drain(&mut self) -> Drain<'_, T, A> { Drain { iter: self.data.drain(..) } } @@ -1438,12 +1493,15 @@ unsafe impl AsVecIntoIter for IntoIter { #[must_use = "iterators are lazy and do nothing unless consumed"] #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] #[derive(Clone, Debug)] -pub struct IntoIterSorted { - inner: BinaryHeap, +pub struct IntoIterSorted< + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + inner: BinaryHeap, } #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] -impl Iterator for IntoIterSorted { +impl Iterator for IntoIterSorted { type Item = T; #[inline] @@ -1459,13 +1517,13 @@ impl Iterator for IntoIterSorted { } #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] -impl ExactSizeIterator for IntoIterSorted {} +impl ExactSizeIterator for IntoIterSorted {} #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] -impl FusedIterator for IntoIterSorted {} +impl FusedIterator for IntoIterSorted {} #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for IntoIterSorted {} +unsafe impl TrustedLen for IntoIterSorted {} /// A draining iterator over the elements of a `BinaryHeap`. /// @@ -1475,12 +1533,16 @@ unsafe impl TrustedLen for IntoIterSorted {} /// [`drain`]: BinaryHeap::drain #[stable(feature = "drain", since = "1.6.0")] #[derive(Debug)] -pub struct Drain<'a, T: 'a> { - iter: vec::Drain<'a, T>, +pub struct Drain< + 'a, + T: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global, +> { + iter: vec::Drain<'a, T, A>, } #[stable(feature = "drain", since = "1.6.0")] -impl Iterator for Drain<'_, T> { +impl<'a, T, A: Allocator + 'a> Iterator for Drain<'a, T, A> { type Item = T; #[inline] @@ -1495,7 +1557,7 @@ impl Iterator for Drain<'_, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl DoubleEndedIterator for Drain<'_, T> { +impl<'a, T, A: Allocator + 'a> DoubleEndedIterator for Drain<'a, T, A> { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back() @@ -1503,14 +1565,14 @@ impl DoubleEndedIterator for Drain<'_, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl ExactSizeIterator for Drain<'_, T> { +impl<'a, T, A: Allocator + 'a> ExactSizeIterator for Drain<'a, T, A> { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Drain<'_, T> {} +impl<'a, T, A: Allocator + 'a> FusedIterator for Drain<'a, T, A> {} /// A draining iterator over the elements of a `BinaryHeap`. /// @@ -1520,17 +1582,21 @@ impl FusedIterator for Drain<'_, T> {} /// [`drain_sorted`]: BinaryHeap::drain_sorted #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] #[derive(Debug)] -pub struct DrainSorted<'a, T: Ord> { - inner: &'a mut BinaryHeap, +pub struct DrainSorted< + 'a, + T: Ord, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global, +> { + inner: &'a mut BinaryHeap, } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl<'a, T: Ord> Drop for DrainSorted<'a, T> { +impl<'a, T: Ord, A: Allocator + 'a> Drop for DrainSorted<'a, T, A> { /// Removes heap elements in heap order. fn drop(&mut self) { - struct DropGuard<'r, 'a, T: Ord>(&'r mut DrainSorted<'a, T>); + struct DropGuard<'r, 'a, T: Ord, A: Allocator + 'a>(&'r mut DrainSorted<'a, T, A>); - impl<'r, 'a, T: Ord> Drop for DropGuard<'r, 'a, T> { + impl<'r, 'a, T: Ord, A: Allocator + 'a> Drop for DropGuard<'r, 'a, T, A> { fn drop(&mut self) { while self.0.inner.pop().is_some() {} } @@ -1545,7 +1611,7 @@ impl<'a, T: Ord> Drop for DrainSorted<'a, T> { } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl Iterator for DrainSorted<'_, T> { +impl Iterator for DrainSorted<'_, T, A> { type Item = T; #[inline] @@ -1561,20 +1627,20 @@ impl Iterator for DrainSorted<'_, T> { } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl ExactSizeIterator for DrainSorted<'_, T> {} +impl ExactSizeIterator for DrainSorted<'_, T, A> {} #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl FusedIterator for DrainSorted<'_, T> {} +impl FusedIterator for DrainSorted<'_, T, A> {} #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for DrainSorted<'_, T> {} +unsafe impl TrustedLen for DrainSorted<'_, T, A> {} #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] -impl From> for BinaryHeap { +impl From> for BinaryHeap { /// Converts a `Vec` into a `BinaryHeap`. /// /// This conversion happens in-place, and has *O*(*n*) time complexity. - fn from(vec: Vec) -> BinaryHeap { + fn from(vec: Vec) -> BinaryHeap { let mut heap = BinaryHeap { data: vec }; heap.rebuild(); heap @@ -1598,12 +1664,12 @@ impl From<[T; N]> for BinaryHeap { } #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] -impl From> for Vec { +impl From> for Vec { /// Converts a `BinaryHeap` into a `Vec`. /// /// This conversion requires no data movement or allocation, and has /// constant time complexity. - fn from(heap: BinaryHeap) -> Vec { + fn from(heap: BinaryHeap) -> Vec { heap.data } } @@ -1644,7 +1710,7 @@ impl IntoIterator for BinaryHeap { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a BinaryHeap { +impl<'a, T, A: Allocator + 'a> IntoIterator for &'a BinaryHeap { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -1691,7 +1757,7 @@ impl SpecExtend> for BinaryHeap { } } -impl BinaryHeap { +impl BinaryHeap { fn extend_desugared>(&mut self, iter: I) { let iterator = iter.into_iter(); let (lower, _) = iterator.size_hint(); From d48b281468c90b09eed472cd3fb60539869585a2 Mon Sep 17 00:00:00 2001 From: yanchith Date: Sat, 16 Jul 2022 18:51:15 +0200 Subject: [PATCH 2/9] Mark lifetimes explicitly --- library/alloc/src/collections/binary_heap.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 97f0c1eeb0de0..b166c526c0d62 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -292,14 +292,14 @@ pub struct PeekMut< } #[stable(feature = "collection_debug", since = "1.17.0")] -impl fmt::Debug for PeekMut<'_, T, A> { +impl<'a, T: Ord + fmt::Debug, A: Allocator + 'a> fmt::Debug for PeekMut<'a, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("PeekMut").field(&self.heap.data[0]).finish() } } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl Drop for PeekMut<'_, T, A> { +impl<'a, T: Ord, A: Allocator + 'a> Drop for PeekMut<'a, T, A> { fn drop(&mut self) { if self.sift { // SAFETY: PeekMut is only instantiated for non-empty heaps. @@ -309,7 +309,7 @@ impl Drop for PeekMut<'_, T, A> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl Deref for PeekMut<'_, T, A> { +impl<'a, T: Ord, A: Allocator + 'a> Deref for PeekMut<'a, T, A> { type Target = T; fn deref(&self) -> &T { debug_assert!(!self.heap.is_empty()); @@ -319,7 +319,7 @@ impl Deref for PeekMut<'_, T, A> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl DerefMut for PeekMut<'_, T, A> { +impl<'a, T: Ord, A: Allocator + 'a> DerefMut for PeekMut<'a, T, A> { fn deref_mut(&mut self) -> &mut T { debug_assert!(!self.heap.is_empty()); self.sift = true; @@ -328,10 +328,10 @@ impl DerefMut for PeekMut<'_, T, A> { } } -impl<'a, T: Ord> PeekMut<'a, T> { +impl<'a, T: Ord, A: Allocator + 'a> PeekMut<'a, T, A> { /// Removes the peeked value from the heap and returns it. #[stable(feature = "binary_heap_peek_mut_pop", since = "1.18.0")] - pub fn pop(mut this: PeekMut<'a, T>) -> T { + pub fn pop(mut this: PeekMut<'a, T, A>) -> T { let value = this.heap.pop().unwrap(); this.sift = false; value @@ -1611,7 +1611,7 @@ impl<'a, T: Ord, A: Allocator + 'a> Drop for DrainSorted<'a, T, A> { } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl Iterator for DrainSorted<'_, T, A> { +impl<'a, T: Ord, A: Allocator + 'a> Iterator for DrainSorted<'a, T, A> { type Item = T; #[inline] @@ -1627,13 +1627,13 @@ impl Iterator for DrainSorted<'_, T, A> { } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl ExactSizeIterator for DrainSorted<'_, T, A> {} +impl<'a, T: Ord, A: Allocator + 'a> ExactSizeIterator for DrainSorted<'a, T, A> {} #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl FusedIterator for DrainSorted<'_, T, A> {} +impl<'a, T: Ord, A: Allocator + 'a> FusedIterator for DrainSorted<'a, T, A> {} #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for DrainSorted<'_, T, A> {} +unsafe impl<'a, T: Ord, A: Allocator + 'a> TrustedLen for DrainSorted<'a, T, A> {} #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] impl From> for BinaryHeap { From 24df5f28e12c6ca4c1c6ef36f6d42f376c6060c3 Mon Sep 17 00:00:00 2001 From: yanchith Date: Sat, 16 Jul 2022 19:25:50 +0200 Subject: [PATCH 3/9] Parametrize a few more things --- library/alloc/src/collections/binary_heap.rs | 35 +++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index b166c526c0d62..c9f0e08649572 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -1421,19 +1421,22 @@ impl FusedIterator for Iter<'_, T> {} /// [`IntoIterator`]: core::iter::IntoIterator #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] -pub struct IntoIter { - iter: vec::IntoIter, +pub struct IntoIter< + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + iter: vec::IntoIter, } #[stable(feature = "collection_debug", since = "1.17.0")] -impl fmt::Debug for IntoIter { +impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IntoIter").field(&self.iter.as_slice()).finish() } } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = T; #[inline] @@ -1448,7 +1451,7 @@ impl Iterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for IntoIter { +impl DoubleEndedIterator for IntoIter { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back() @@ -1456,21 +1459,21 @@ impl DoubleEndedIterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for IntoIter { +impl ExactSizeIterator for IntoIter { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for IntoIter {} +impl FusedIterator for IntoIter {} // In addition to the SAFETY invariants of the following three unsafe traits // also refer to the vec::in_place_collect module documentation to get an overview #[unstable(issue = "none", feature = "inplace_iteration")] #[doc(hidden)] -unsafe impl SourceIter for IntoIter { - type Source = IntoIter; +unsafe impl SourceIter for IntoIter { + type Source = IntoIter; #[inline] unsafe fn as_inner(&mut self) -> &mut Self::Source { @@ -1480,9 +1483,9 @@ unsafe impl SourceIter for IntoIter { #[unstable(issue = "none", feature = "inplace_iteration")] #[doc(hidden)] -unsafe impl InPlaceIterable for IntoIter {} +unsafe impl InPlaceIterable for IntoIter {} -unsafe impl AsVecIntoIter for IntoIter { +unsafe impl AsVecIntoIter for IntoIter { type Item = I; fn as_into_iter(&mut self) -> &mut vec::IntoIter { @@ -1682,9 +1685,9 @@ 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; + type IntoIter = IntoIter; /// Creates a consuming iterator, that is, one that moves each value out of /// the binary heap in arbitrary order. The binary heap cannot be used @@ -1704,7 +1707,7 @@ impl IntoIterator for BinaryHeap { /// println!("{x}"); /// } /// ``` - fn into_iter(self) -> IntoIter { + fn into_iter(self) -> IntoIter { IntoIter { iter: self.data.into_iter() } } } @@ -1720,7 +1723,7 @@ impl<'a, T, A: Allocator + 'a> IntoIterator for &'a BinaryHeap { } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for BinaryHeap { +impl Extend for BinaryHeap { #[inline] fn extend>(&mut self, iter: I) { >::spec_extend(self, iter); @@ -1737,7 +1740,7 @@ impl Extend for BinaryHeap { } } -impl> SpecExtend for BinaryHeap { +impl> SpecExtend for BinaryHeap { default fn spec_extend(&mut self, iter: I) { self.extend_desugared(iter.into_iter()); } From 7a9f282528fe95e160b177b880e06cc5ca2a426a Mon Sep 17 00:00:00 2001 From: yanchith Date: Fri, 9 Jun 2023 11:48:11 +0200 Subject: [PATCH 4/9] Reallocatorize after merge --- .../alloc/src/collections/binary_heap/mod.rs | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index f5e6bd20ea58b..abc29b32bbc0c 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -280,7 +280,6 @@ pub struct BinaryHeap< data: Vec, } -// XXX: PeekMut /// Structure wrapping a mutable reference to the greatest item on a /// `BinaryHeap`. /// @@ -289,8 +288,12 @@ pub struct BinaryHeap< /// /// [`peek_mut`]: BinaryHeap::peek_mut #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -pub struct PeekMut<'a, T: 'a + Ord> { - heap: &'a mut BinaryHeap, +pub struct PeekMut< + 'a, + T: 'a + Ord, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + heap: &'a mut BinaryHeap, // If a set_len + sift_down are required, this is Some. If a &mut T has not // yet been exposed to peek_mut()'s caller, it's None. original_len: Option, @@ -359,11 +362,10 @@ impl<'a, T: Ord, A: Allocator + 'a> DerefMut for PeekMut<'a, T, A> { } } -// XXX: PeekMut impl<'a, T: Ord, A: Allocator + 'a> PeekMut<'a, T, A> { /// Removes the peeked value from the heap and returns it. #[stable(feature = "binary_heap_peek_mut_pop", since = "1.18.0")] - pub fn pop(mut this: PeekMut<'a, T>) -> T { + pub fn pop(mut this: PeekMut<'a, T, A>) -> T { if let Some(original_len) = this.original_len.take() { // SAFETY: This is how many elements were in the Vec at the time of // the BinaryHeap::peek_mut call. @@ -404,18 +406,21 @@ impl fmt::Debug for BinaryHeap { } } -struct RebuildOnDrop<'a, T: Ord> { - heap: &'a mut BinaryHeap, +struct RebuildOnDrop< + 'a, + T: Ord, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + heap: &'a mut BinaryHeap, rebuild_from: usize, } -impl<'a, T: Ord> Drop for RebuildOnDrop<'a, T> { +impl<'a, T: Ord, A: Allocator> Drop for RebuildOnDrop<'a, T, A> { fn drop(&mut self) { self.heap.rebuild_tail(self.rebuild_from); } } -// XXX: BinaryHeap impl BinaryHeap { /// Creates an empty `BinaryHeap` as a max-heap. /// @@ -501,7 +506,6 @@ impl BinaryHeap { BinaryHeap { data: Vec::with_capacity_in(capacity, alloc) } } - // XXX: peek_mut /// Returns a mutable reference to the greatest item in the binary heap, or /// `None` if it is empty. /// @@ -533,7 +537,7 @@ impl BinaryHeap { /// If the item is modified then the worst case time complexity is *O*(log(*n*)), /// otherwise it's *O*(1). #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] - pub fn peek_mut(&mut self) -> Option> { + pub fn peek_mut(&mut self) -> Option> { if self.is_empty() { None } else { @@ -1813,7 +1817,7 @@ impl Extend for BinaryHeap { } #[stable(feature = "extend_ref", since = "1.2.0")] -impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BinaryHeap { +impl<'a, T: 'a + Ord + Copy, A: Allocator> Extend<&'a T> for BinaryHeap { fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); } From 208da513ccfd042cb2df9ef12d0bc116b7b63304 Mon Sep 17 00:00:00 2001 From: yanchith Date: Fri, 9 Jun 2023 11:53:28 +0200 Subject: [PATCH 5/9] Add allocator function --- library/alloc/src/collections/binary_heap/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index abc29b32bbc0c..9c2588c26b49d 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -1245,6 +1245,13 @@ impl BinaryHeap { self.into() } + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn allocator(&self) -> &A { + self.data.allocator() + } + /// Returns the length of the binary heap. /// /// # Examples From 767a7119a08b51ed6fa2d4f6092418e63ce2877a Mon Sep 17 00:00:00 2001 From: yanchith Date: Fri, 9 Jun 2023 12:02:25 +0200 Subject: [PATCH 6/9] Pass tidy again --- library/alloc/src/collections/binary_heap/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 9c2588c26b49d..657c380d65d76 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -538,11 +538,7 @@ impl BinaryHeap { /// otherwise it's *O*(1). #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] pub fn peek_mut(&mut self) -> Option> { - if self.is_empty() { - None - } else { - Some(PeekMut { heap: self, original_len: None }) - } + if self.is_empty() { None } else { Some(PeekMut { heap: self, original_len: None }) } } /// Removes the greatest item from the binary heap and returns it, or `None` if it From 4df4c0d00be1e35fe2e47bbec277504bcdb4c381 Mon Sep 17 00:00:00 2001 From: yanchith Date: Fri, 9 Jun 2023 12:19:17 +0200 Subject: [PATCH 7/9] Don't explicitly name Global --- library/alloc/src/collections/binary_heap/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 657c380d65d76..904e163da8880 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -1563,7 +1563,7 @@ unsafe impl SourceIter for IntoIter { #[doc(hidden)] unsafe impl InPlaceIterable for IntoIter {} -unsafe impl AsVecIntoIter for IntoIter { +unsafe impl AsVecIntoIter for IntoIter { type Item = I; fn as_into_iter(&mut self) -> &mut vec::IntoIter { From d9b6181d2f04fa1d444b853eca6dd3fb9e0009ed Mon Sep 17 00:00:00 2001 From: yanchith Date: Sun, 11 Jun 2023 22:42:50 +0200 Subject: [PATCH 8/9] Remove explicit lifetimes --- .../alloc/src/collections/binary_heap/mod.rs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 904e163da8880..93e799410d384 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -300,14 +300,14 @@ pub struct PeekMut< } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: Ord + fmt::Debug, A: Allocator + 'a> fmt::Debug for PeekMut<'a, T, A> { +impl fmt::Debug for PeekMut<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("PeekMut").field(&self.heap.data[0]).finish() } } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl<'a, T: Ord, A: Allocator + 'a> Drop for PeekMut<'a, T, A> { +impl Drop for PeekMut<'_, T, A> { fn drop(&mut self) { if let Some(original_len) = self.original_len { // SAFETY: That's how many elements were in the Vec at the time of @@ -324,7 +324,7 @@ impl<'a, T: Ord, A: Allocator + 'a> Drop for PeekMut<'a, T, A> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl<'a, T: Ord, A: Allocator + 'a> Deref for PeekMut<'a, T, A> { +impl Deref for PeekMut<'_, T, A> { type Target = T; fn deref(&self) -> &T { debug_assert!(!self.heap.is_empty()); @@ -334,7 +334,7 @@ impl<'a, T: Ord, A: Allocator + 'a> Deref for PeekMut<'a, T, A> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl<'a, T: Ord, A: Allocator + 'a> DerefMut for PeekMut<'a, T, A> { +impl DerefMut for PeekMut<'_, T, A> { fn deref_mut(&mut self) -> &mut T { debug_assert!(!self.heap.is_empty()); @@ -362,7 +362,7 @@ impl<'a, T: Ord, A: Allocator + 'a> DerefMut for PeekMut<'a, T, A> { } } -impl<'a, T: Ord, A: Allocator + 'a> PeekMut<'a, T, A> { +impl<'a, T: Ord, A: Allocator> PeekMut<'a, T, A> { /// Removes the peeked value from the heap and returns it. #[stable(feature = "binary_heap_peek_mut_pop", since = "1.18.0")] pub fn pop(mut this: PeekMut<'a, T, A>) -> T { @@ -415,7 +415,7 @@ struct RebuildOnDrop< rebuild_from: usize, } -impl<'a, T: Ord, A: Allocator> Drop for RebuildOnDrop<'a, T, A> { +impl Drop for RebuildOnDrop<'_, T, A> { fn drop(&mut self) { self.heap.rebuild_tail(self.rebuild_from); } @@ -1617,13 +1617,13 @@ unsafe impl TrustedLen for IntoIterSorted {} pub struct Drain< 'a, T: 'a, - #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, > { iter: vec::Drain<'a, T, A>, } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T, A: Allocator + 'a> Iterator for Drain<'a, T, A> { +impl Iterator for Drain<'_, T, A> { type Item = T; #[inline] @@ -1638,7 +1638,7 @@ impl<'a, T, A: Allocator + 'a> Iterator for Drain<'a, T, A> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T, A: Allocator + 'a> DoubleEndedIterator for Drain<'a, T, A> { +impl DoubleEndedIterator for Drain<'_, T, A> { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back() @@ -1646,14 +1646,14 @@ impl<'a, T, A: Allocator + 'a> DoubleEndedIterator for Drain<'a, T, A> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T, A: Allocator + 'a> ExactSizeIterator for Drain<'a, T, A> { +impl ExactSizeIterator for Drain<'_, T, A> { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T, A: Allocator + 'a> FusedIterator for Drain<'a, T, A> {} +impl FusedIterator for Drain<'_, T, A> {} /// A draining iterator over the elements of a `BinaryHeap`. /// @@ -1666,18 +1666,18 @@ impl<'a, T, A: Allocator + 'a> FusedIterator for Drain<'a, T, A> {} pub struct DrainSorted< 'a, T: Ord, - #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, > { inner: &'a mut BinaryHeap, } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl<'a, T: Ord, A: Allocator + 'a> Drop for DrainSorted<'a, T, A> { +impl<'a, T: Ord, A: Allocator> Drop for DrainSorted<'a, T, A> { /// Removes heap elements in heap order. fn drop(&mut self) { - struct DropGuard<'r, 'a, T: Ord, A: Allocator + 'a>(&'r mut DrainSorted<'a, T, A>); + struct DropGuard<'r, 'a, T: Ord, A: Allocator>(&'r mut DrainSorted<'a, T, A>); - impl<'r, 'a, T: Ord, A: Allocator + 'a> Drop for DropGuard<'r, 'a, T, A> { + impl<'r, 'a, T: Ord, A: Allocator> Drop for DropGuard<'r, 'a, T, A> { fn drop(&mut self) { while self.0.inner.pop().is_some() {} } @@ -1692,7 +1692,7 @@ impl<'a, T: Ord, A: Allocator + 'a> Drop for DrainSorted<'a, T, A> { } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl<'a, T: Ord, A: Allocator + 'a> Iterator for DrainSorted<'a, T, A> { +impl Iterator for DrainSorted<'_, T, A> { type Item = T; #[inline] @@ -1708,13 +1708,13 @@ impl<'a, T: Ord, A: Allocator + 'a> Iterator for DrainSorted<'a, T, A> { } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl<'a, T: Ord, A: Allocator + 'a> ExactSizeIterator for DrainSorted<'a, T, A> {} +impl ExactSizeIterator for DrainSorted<'_, T, A> {} #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl<'a, T: Ord, A: Allocator + 'a> FusedIterator for DrainSorted<'a, T, A> {} +impl FusedIterator for DrainSorted<'_, T, A> {} #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl<'a, T: Ord, A: Allocator + 'a> TrustedLen for DrainSorted<'a, T, A> {} +unsafe impl TrustedLen for DrainSorted<'_, T, A> {} #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] impl From> for BinaryHeap { @@ -1791,7 +1791,7 @@ impl IntoIterator for BinaryHeap { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, A: Allocator + 'a> IntoIterator for &'a BinaryHeap { +impl<'a, T, A: Allocator> IntoIterator for &'a BinaryHeap { type Item = &'a T; type IntoIter = Iter<'a, T>; From e0e355dd253b46380f975acd33b43302ac470236 Mon Sep 17 00:00:00 2001 From: yanchith Date: Sun, 11 Jun 2023 22:56:16 +0200 Subject: [PATCH 9/9] Impl allocator function for iterators --- .../alloc/src/collections/binary_heap/mod.rs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 93e799410d384..66573b90db963 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -1492,6 +1492,14 @@ pub struct IntoIter< iter: vec::IntoIter, } +impl IntoIter { + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn allocator(&self) -> &A { + self.iter.allocator() + } +} + #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -1581,6 +1589,14 @@ pub struct IntoIterSorted< inner: BinaryHeap, } +impl IntoIterSorted { + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn allocator(&self) -> &A { + self.inner.allocator() + } +} + #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] impl Iterator for IntoIterSorted { type Item = T; @@ -1622,6 +1638,14 @@ pub struct Drain< iter: vec::Drain<'a, T, A>, } +impl Drain<'_, T, A> { + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn allocator(&self) -> &A { + self.iter.allocator() + } +} + #[stable(feature = "drain", since = "1.6.0")] impl Iterator for Drain<'_, T, A> { type Item = T; @@ -1671,6 +1695,14 @@ pub struct DrainSorted< inner: &'a mut BinaryHeap, } +impl<'a, T: Ord, A: Allocator> DrainSorted<'a, T, A> { + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn allocator(&self) -> &A { + self.inner.allocator() + } +} + #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] impl<'a, T: Ord, A: Allocator> Drop for DrainSorted<'a, T, A> { /// Removes heap elements in heap order.