Auto merge of #99339 - yanchith:binary-heap-ta, r=Amanieu
Make BinaryHeap parametric over Allocator Tracking issue: #32838 Related: https://github.com/rust-lang/wg-allocators/issues/7 This parametrizes `BinaryHeap` with `A`, similarly to how other collections are parametrized. A couple things I left out: ``` BinaryHeap::append Currently requires both structures to have the same allocator type. Could change, but depends on Vec::append, which has the same constraints. impl<T: Ord> Default for BinaryHeap<T> Not parametrized, because there's nowhere to conjure the allocator from. impl<T: Ord> FromIterator<T> for BinaryHeap<T> Not parametrized, because there's nowhere to conjure the allocator from. impl<T: Ord, const N: usize> From<[T; N]> for BinaryHeap<T> Not parametrized, because there's nowhere to conjure the allocator from. unsafe impl<I> AsVecIntoIter for IntoIter<I> AsVecIntoIter is not allocator aware, and I didn't dare change it without guidance. Is this something important? ``` I've seen very few tests for allocator_api in general, but I'd like to at least test this on some usage code in my projects before moving forward. EDIT: Updated the list of impls and functions that are not affected by this. `BinaryHeap` no longer has a `SpecExtend` impl, and prior work made implementing `Extend` possible.
This commit is contained in:
commit
de1ff0a8b5
1 changed files with 175 additions and 63 deletions
|
@ -143,6 +143,7 @@
|
|||
#![allow(missing_docs)]
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use core::alloc::Allocator;
|
||||
use core::fmt;
|
||||
use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedLen};
|
||||
use core::mem::{self, swap, ManuallyDrop};
|
||||
|
@ -150,6 +151,7 @@ use core::num::NonZeroUsize;
|
|||
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};
|
||||
|
@ -271,8 +273,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<T> {
|
||||
data: Vec<T>,
|
||||
pub struct BinaryHeap<
|
||||
T,
|
||||
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
|
||||
> {
|
||||
data: Vec<T, A>,
|
||||
}
|
||||
|
||||
/// Structure wrapping a mutable reference to the greatest item on a
|
||||
|
@ -283,22 +288,26 @@ pub struct BinaryHeap<T> {
|
|||
///
|
||||
/// [`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<T>,
|
||||
pub struct PeekMut<
|
||||
'a,
|
||||
T: 'a + Ord,
|
||||
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
|
||||
> {
|
||||
heap: &'a mut BinaryHeap<T, A>,
|
||||
// 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<NonZeroUsize>,
|
||||
}
|
||||
|
||||
#[stable(feature = "collection_debug", since = "1.17.0")]
|
||||
impl<T: Ord + fmt::Debug> fmt::Debug for PeekMut<'_, T> {
|
||||
impl<T: Ord + fmt::Debug, A: Allocator> 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<T: Ord> Drop for PeekMut<'_, T> {
|
||||
impl<T: Ord, A: Allocator> 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
|
||||
|
@ -315,7 +324,7 @@ impl<T: Ord> Drop for PeekMut<'_, T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
|
||||
impl<T: Ord> Deref for PeekMut<'_, T> {
|
||||
impl<T: Ord, A: Allocator> Deref for PeekMut<'_, T, A> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T {
|
||||
debug_assert!(!self.heap.is_empty());
|
||||
|
@ -325,7 +334,7 @@ impl<T: Ord> Deref for PeekMut<'_, T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
|
||||
impl<T: Ord> DerefMut for PeekMut<'_, T> {
|
||||
impl<T: Ord, A: Allocator> DerefMut for PeekMut<'_, T, A> {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
debug_assert!(!self.heap.is_empty());
|
||||
|
||||
|
@ -353,10 +362,10 @@ impl<T: Ord> DerefMut for PeekMut<'_, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Ord> PeekMut<'a, T> {
|
||||
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>) -> 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.
|
||||
|
@ -371,7 +380,7 @@ impl<'a, T: Ord> PeekMut<'a, T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: Clone> Clone for BinaryHeap<T> {
|
||||
impl<T: Clone, A: Allocator + Clone> Clone for BinaryHeap<T, A> {
|
||||
fn clone(&self) -> Self {
|
||||
BinaryHeap { data: self.data.clone() }
|
||||
}
|
||||
|
@ -391,18 +400,22 @@ impl<T: Ord> Default for BinaryHeap<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "binaryheap_debug", since = "1.4.0")]
|
||||
impl<T: fmt::Debug> fmt::Debug for BinaryHeap<T> {
|
||||
impl<T: fmt::Debug, A: Allocator> fmt::Debug for BinaryHeap<T, A> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_list().entries(self.iter()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
struct RebuildOnDrop<'a, T: Ord> {
|
||||
heap: &'a mut BinaryHeap<T>,
|
||||
struct RebuildOnDrop<
|
||||
'a,
|
||||
T: Ord,
|
||||
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
|
||||
> {
|
||||
heap: &'a mut BinaryHeap<T, A>,
|
||||
rebuild_from: usize,
|
||||
}
|
||||
|
||||
impl<'a, T: Ord> Drop for RebuildOnDrop<'a, T> {
|
||||
impl<T: Ord, A: Allocator> Drop for RebuildOnDrop<'_, T, A> {
|
||||
fn drop(&mut self) {
|
||||
self.heap.rebuild_tail(self.rebuild_from);
|
||||
}
|
||||
|
@ -446,6 +459,52 @@ impl<T: Ord> BinaryHeap<T> {
|
|||
pub fn with_capacity(capacity: usize) -> BinaryHeap<T> {
|
||||
BinaryHeap { data: Vec::with_capacity(capacity) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
|
||||
/// 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<T, A> {
|
||||
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<T, A> {
|
||||
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.
|
||||
|
@ -478,7 +537,7 @@ impl<T: Ord> BinaryHeap<T> {
|
|||
/// 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<PeekMut<'_, T>> {
|
||||
pub fn peek_mut(&mut self) -> Option<PeekMut<'_, T, A>> {
|
||||
if self.is_empty() { None } else { Some(PeekMut { heap: self, original_len: None }) }
|
||||
}
|
||||
|
||||
|
@ -573,7 +632,7 @@ impl<T: Ord> BinaryHeap<T> {
|
|||
/// ```
|
||||
#[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<T> {
|
||||
pub fn into_sorted_vec(mut self) -> Vec<T, A> {
|
||||
let mut end = self.len();
|
||||
while end > 1 {
|
||||
end -= 1;
|
||||
|
@ -831,7 +890,7 @@ impl<T: Ord> BinaryHeap<T> {
|
|||
/// ```
|
||||
#[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 }
|
||||
}
|
||||
|
||||
|
@ -874,7 +933,7 @@ impl<T: Ord> BinaryHeap<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> BinaryHeap<T> {
|
||||
impl<T, A: Allocator> BinaryHeap<T, A> {
|
||||
/// Returns an iterator visiting all values in the underlying vector, in
|
||||
/// arbitrary order.
|
||||
///
|
||||
|
@ -911,7 +970,7 @@ impl<T> BinaryHeap<T> {
|
|||
/// assert_eq!(heap.into_iter_sorted().take(2).collect::<Vec<_>>(), [5, 4]);
|
||||
/// ```
|
||||
#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
|
||||
pub fn into_iter_sorted(self) -> IntoIterSorted<T> {
|
||||
pub fn into_iter_sorted(self) -> IntoIterSorted<T, A> {
|
||||
IntoIterSorted { inner: self }
|
||||
}
|
||||
|
||||
|
@ -1178,10 +1237,17 @@ impl<T> BinaryHeap<T> {
|
|||
/// ```
|
||||
#[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<T> {
|
||||
pub fn into_vec(self) -> Vec<T, A> {
|
||||
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
|
||||
|
@ -1249,7 +1315,7 @@ impl<T> BinaryHeap<T> {
|
|||
/// ```
|
||||
#[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(..) }
|
||||
}
|
||||
|
||||
|
@ -1419,19 +1485,30 @@ impl<T> FusedIterator for Iter<'_, T> {}
|
|||
/// [`into_iter`]: BinaryHeap::into_iter
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[derive(Clone)]
|
||||
pub struct IntoIter<T> {
|
||||
iter: vec::IntoIter<T>,
|
||||
pub struct IntoIter<
|
||||
T,
|
||||
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
|
||||
> {
|
||||
iter: vec::IntoIter<T, A>,
|
||||
}
|
||||
|
||||
impl<T, A: Allocator> IntoIter<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 = "collection_debug", since = "1.17.0")]
|
||||
impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
|
||||
impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> {
|
||||
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<T> Iterator for IntoIter<T> {
|
||||
impl<T, A: Allocator> Iterator for IntoIter<T, A> {
|
||||
type Item = T;
|
||||
|
||||
#[inline]
|
||||
|
@ -1446,7 +1523,7 @@ impl<T> Iterator for IntoIter<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> DoubleEndedIterator for IntoIter<T> {
|
||||
impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<T> {
|
||||
self.iter.next_back()
|
||||
|
@ -1454,14 +1531,14 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> ExactSizeIterator for IntoIter<T> {
|
||||
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.iter.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T> FusedIterator for IntoIter<T> {}
|
||||
impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<T> Default for IntoIter<T> {
|
||||
|
@ -1481,8 +1558,8 @@ impl<T> Default for IntoIter<T> {
|
|||
// also refer to the vec::in_place_collect module documentation to get an overview
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
#[doc(hidden)]
|
||||
unsafe impl<T> SourceIter for IntoIter<T> {
|
||||
type Source = IntoIter<T>;
|
||||
unsafe impl<T, A: Allocator> SourceIter for IntoIter<T, A> {
|
||||
type Source = IntoIter<T, A>;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut Self::Source {
|
||||
|
@ -1492,7 +1569,7 @@ unsafe impl<T> SourceIter for IntoIter<T> {
|
|||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
#[doc(hidden)]
|
||||
unsafe impl<I> InPlaceIterable for IntoIter<I> {}
|
||||
unsafe impl<I, A: Allocator> InPlaceIterable for IntoIter<I, A> {}
|
||||
|
||||
unsafe impl<I> AsVecIntoIter for IntoIter<I> {
|
||||
type Item = I;
|
||||
|
@ -1505,12 +1582,23 @@ unsafe impl<I> AsVecIntoIter for IntoIter<I> {
|
|||
#[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<T> {
|
||||
inner: BinaryHeap<T>,
|
||||
pub struct IntoIterSorted<
|
||||
T,
|
||||
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
|
||||
> {
|
||||
inner: BinaryHeap<T, A>,
|
||||
}
|
||||
|
||||
impl<T, A: Allocator> IntoIterSorted<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_into_iter_sorted", issue = "59278")]
|
||||
impl<T: Ord> Iterator for IntoIterSorted<T> {
|
||||
impl<T: Ord, A: Allocator> Iterator for IntoIterSorted<T, A> {
|
||||
type Item = T;
|
||||
|
||||
#[inline]
|
||||
|
@ -1526,13 +1614,13 @@ impl<T: Ord> Iterator for IntoIterSorted<T> {
|
|||
}
|
||||
|
||||
#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
|
||||
impl<T: Ord> ExactSizeIterator for IntoIterSorted<T> {}
|
||||
impl<T: Ord, A: Allocator> ExactSizeIterator for IntoIterSorted<T, A> {}
|
||||
|
||||
#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
|
||||
impl<T: Ord> FusedIterator for IntoIterSorted<T> {}
|
||||
impl<T: Ord, A: Allocator> FusedIterator for IntoIterSorted<T, A> {}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<T: Ord> TrustedLen for IntoIterSorted<T> {}
|
||||
unsafe impl<T: Ord, A: Allocator> TrustedLen for IntoIterSorted<T, A> {}
|
||||
|
||||
/// A draining iterator over the elements of a `BinaryHeap`.
|
||||
///
|
||||
|
@ -1542,12 +1630,24 @@ unsafe impl<T: Ord> TrustedLen for IntoIterSorted<T> {}
|
|||
/// [`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 = Global,
|
||||
> {
|
||||
iter: vec::Drain<'a, T, A>,
|
||||
}
|
||||
|
||||
impl<T, A: Allocator> 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<T> Iterator for Drain<'_, T> {
|
||||
impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
|
||||
type Item = T;
|
||||
|
||||
#[inline]
|
||||
|
@ -1562,7 +1662,7 @@ impl<T> Iterator for Drain<'_, T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "drain", since = "1.6.0")]
|
||||
impl<T> DoubleEndedIterator for Drain<'_, T> {
|
||||
impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<T> {
|
||||
self.iter.next_back()
|
||||
|
@ -1570,14 +1670,14 @@ impl<T> DoubleEndedIterator for Drain<'_, T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "drain", since = "1.6.0")]
|
||||
impl<T> ExactSizeIterator for Drain<'_, T> {
|
||||
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.iter.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T> FusedIterator for Drain<'_, T> {}
|
||||
impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
|
||||
|
||||
/// A draining iterator over the elements of a `BinaryHeap`.
|
||||
///
|
||||
|
@ -1587,17 +1687,29 @@ impl<T> 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<T>,
|
||||
pub struct DrainSorted<
|
||||
'a,
|
||||
T: Ord,
|
||||
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
|
||||
> {
|
||||
inner: &'a mut BinaryHeap<T, A>,
|
||||
}
|
||||
|
||||
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> Drop for DrainSorted<'a, T> {
|
||||
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>(&'r mut DrainSorted<'a, T>);
|
||||
struct DropGuard<'r, 'a, T: Ord, A: Allocator>(&'r mut DrainSorted<'a, T, A>);
|
||||
|
||||
impl<'r, 'a, T: Ord> Drop for DropGuard<'r, 'a, T> {
|
||||
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() {}
|
||||
}
|
||||
|
@ -1612,7 +1724,7 @@ impl<'a, T: Ord> Drop for DrainSorted<'a, T> {
|
|||
}
|
||||
|
||||
#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
|
||||
impl<T: Ord> Iterator for DrainSorted<'_, T> {
|
||||
impl<T: Ord, A: Allocator> Iterator for DrainSorted<'_, T, A> {
|
||||
type Item = T;
|
||||
|
||||
#[inline]
|
||||
|
@ -1628,20 +1740,20 @@ impl<T: Ord> Iterator for DrainSorted<'_, T> {
|
|||
}
|
||||
|
||||
#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
|
||||
impl<T: Ord> ExactSizeIterator for DrainSorted<'_, T> {}
|
||||
impl<T: Ord, A: Allocator> ExactSizeIterator for DrainSorted<'_, T, A> {}
|
||||
|
||||
#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
|
||||
impl<T: Ord> FusedIterator for DrainSorted<'_, T> {}
|
||||
impl<T: Ord, A: Allocator> FusedIterator for DrainSorted<'_, T, A> {}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<T: Ord> TrustedLen for DrainSorted<'_, T> {}
|
||||
unsafe impl<T: Ord, A: Allocator> TrustedLen for DrainSorted<'_, T, A> {}
|
||||
|
||||
#[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
|
||||
impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
|
||||
impl<T: Ord, A: Allocator> From<Vec<T, A>> for BinaryHeap<T, A> {
|
||||
/// Converts a `Vec<T>` into a `BinaryHeap<T>`.
|
||||
///
|
||||
/// This conversion happens in-place, and has *O*(*n*) time complexity.
|
||||
fn from(vec: Vec<T>) -> BinaryHeap<T> {
|
||||
fn from(vec: Vec<T, A>) -> BinaryHeap<T, A> {
|
||||
let mut heap = BinaryHeap { data: vec };
|
||||
heap.rebuild();
|
||||
heap
|
||||
|
@ -1665,12 +1777,12 @@ impl<T: Ord, const N: usize> From<[T; N]> for BinaryHeap<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
|
||||
impl<T> From<BinaryHeap<T>> for Vec<T> {
|
||||
impl<T, A: Allocator> From<BinaryHeap<T, A>> for Vec<T, A> {
|
||||
/// Converts a `BinaryHeap<T>` into a `Vec<T>`.
|
||||
///
|
||||
/// This conversion requires no data movement or allocation, and has
|
||||
/// constant time complexity.
|
||||
fn from(heap: BinaryHeap<T>) -> Vec<T> {
|
||||
fn from(heap: BinaryHeap<T, A>) -> Vec<T, A> {
|
||||
heap.data
|
||||
}
|
||||
}
|
||||
|
@ -1683,9 +1795,9 @@ impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> IntoIterator for BinaryHeap<T> {
|
||||
impl<T, A: Allocator> IntoIterator for BinaryHeap<T, A> {
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T>;
|
||||
type IntoIter = IntoIter<T, A>;
|
||||
|
||||
/// 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
|
||||
|
@ -1705,13 +1817,13 @@ impl<T> IntoIterator for BinaryHeap<T> {
|
|||
/// println!("{x}");
|
||||
/// }
|
||||
/// ```
|
||||
fn into_iter(self) -> IntoIter<T> {
|
||||
fn into_iter(self) -> IntoIter<T, A> {
|
||||
IntoIter { iter: self.data.into_iter() }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, T> IntoIterator for &'a BinaryHeap<T> {
|
||||
impl<'a, T, A: Allocator> IntoIterator for &'a BinaryHeap<T, A> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
|
@ -1721,7 +1833,7 @@ impl<'a, T> IntoIterator for &'a BinaryHeap<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: Ord> Extend<T> for BinaryHeap<T> {
|
||||
impl<T: Ord, A: Allocator> Extend<T> for BinaryHeap<T, A> {
|
||||
#[inline]
|
||||
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
|
||||
let guard = RebuildOnDrop { rebuild_from: self.len(), heap: self };
|
||||
|
@ -1740,7 +1852,7 @@ impl<T: Ord> Extend<T> for BinaryHeap<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "extend_ref", since = "1.2.0")]
|
||||
impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BinaryHeap<T> {
|
||||
impl<'a, T: 'a + Ord + Copy, A: Allocator> Extend<&'a T> for BinaryHeap<T, A> {
|
||||
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
|
||||
self.extend(iter.into_iter().cloned());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue