Readding lifetime parameters and removing allocation
This commit is contained in:
parent
97d082c6cd
commit
d1e2a935d2
4 changed files with 51 additions and 30 deletions
|
@ -1016,12 +1016,12 @@ impl<T> ExactSizeIterator for IntoIter<T> {}
|
||||||
|
|
||||||
/// An iterator that drains a `BinaryHeap`.
|
/// An iterator that drains a `BinaryHeap`.
|
||||||
#[stable(feature = "drain", since = "1.6.0")]
|
#[stable(feature = "drain", since = "1.6.0")]
|
||||||
pub struct Drain<T> {
|
pub struct Drain<'a, T: 'a> {
|
||||||
iter: vec::Drain<T>,
|
iter: vec::Drain<'a, T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> Iterator for Drain<T> {
|
impl<'a, T: 'a> Iterator for Drain<'a, T> {
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1036,7 +1036,7 @@ impl<T> Iterator for Drain<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> DoubleEndedIterator for Drain<T> {
|
impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next_back(&mut self) -> Option<T> {
|
fn next_back(&mut self) -> Option<T> {
|
||||||
self.iter.next_back()
|
self.iter.next_back()
|
||||||
|
@ -1044,7 +1044,7 @@ impl<T> DoubleEndedIterator for Drain<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> ExactSizeIterator for Drain<T> {}
|
impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
|
impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
|
||||||
|
|
|
@ -73,8 +73,8 @@ use core::mem;
|
||||||
use core::ops::{Index, IndexMut};
|
use core::ops::{Index, IndexMut};
|
||||||
use core::ops;
|
use core::ops;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
use core::ptr::Shared;
|
||||||
use core::slice;
|
use core::slice;
|
||||||
use super::vec_deque::VecDeque;
|
|
||||||
|
|
||||||
use super::SpecExtend;
|
use super::SpecExtend;
|
||||||
use super::range::RangeArgument;
|
use super::range::RangeArgument;
|
||||||
|
@ -844,20 +844,20 @@ impl<T> Vec<T> {
|
||||||
let end = *range.end().unwrap_or(&len);
|
let end = *range.end().unwrap_or(&len);
|
||||||
assert!(start <= end);
|
assert!(start <= end);
|
||||||
assert!(end <= len);
|
assert!(end <= len);
|
||||||
let mut drain_vec = VecDeque::new();
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
for i in start..end {
|
// set self.vec length's to start, to be safe in case Drain is leaked
|
||||||
let p = self.as_ptr().offset(i as isize);
|
self.set_len(start);
|
||||||
drain_vec.push_back(ptr::read(p));
|
// Use the borrow in the IterMut to indicate borrowing behavior of the
|
||||||
|
// whole Drain iterator (like &mut T).
|
||||||
|
let range_slice = slice::from_raw_parts_mut(self.as_mut_ptr().offset(start as isize),
|
||||||
|
end - start);
|
||||||
|
Drain {
|
||||||
|
tail_start: end,
|
||||||
|
tail_len: len - end,
|
||||||
|
iter: range_slice.iter(),
|
||||||
|
vec: Shared::new(self as *mut _),
|
||||||
}
|
}
|
||||||
let src = self.as_ptr().offset(end as isize);
|
|
||||||
let dst = self.as_mut_ptr().offset(start as isize);
|
|
||||||
ptr::copy(src, dst, len - end);
|
|
||||||
self.set_len(len - (end - start));
|
|
||||||
}
|
|
||||||
Drain {
|
|
||||||
deque: drain_vec
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1756,43 +1756,64 @@ impl<T> Drop for IntoIter<T> {
|
||||||
/// [`drain`]: struct.Vec.html#method.drain
|
/// [`drain`]: struct.Vec.html#method.drain
|
||||||
/// [`Vec`]: struct.Vec.html
|
/// [`Vec`]: struct.Vec.html
|
||||||
#[stable(feature = "drain", since = "1.6.0")]
|
#[stable(feature = "drain", since = "1.6.0")]
|
||||||
pub struct Drain<T> {
|
pub struct Drain<'a, T: 'a> {
|
||||||
|
/// Index of tail to preserve
|
||||||
|
tail_start: usize,
|
||||||
|
/// Length of tail
|
||||||
|
tail_len: usize,
|
||||||
/// Current remaining range to remove
|
/// Current remaining range to remove
|
||||||
deque: VecDeque<T>
|
iter: slice::Iter<'a, T>,
|
||||||
|
vec: Shared<Vec<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "drain", since = "1.6.0")]
|
#[stable(feature = "drain", since = "1.6.0")]
|
||||||
unsafe impl<T: Sync> Sync for Drain<T> {}
|
unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {}
|
||||||
#[stable(feature = "drain", since = "1.6.0")]
|
#[stable(feature = "drain", since = "1.6.0")]
|
||||||
unsafe impl<T: Send> Send for Drain<T> {}
|
unsafe impl<'a, T: Send> Send for Drain<'a, T> {}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> Iterator for Drain<T> {
|
impl<'a, T> Iterator for Drain<'a, T> {
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<T> {
|
fn next(&mut self) -> Option<T> {
|
||||||
self.deque.pop_front()
|
self.iter.next().map(|elt| unsafe { ptr::read(elt as *const _) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
(self.deque.len(), Some(self.deque.len()))
|
self.iter.size_hint()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> DoubleEndedIterator for Drain<T> {
|
impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next_back(&mut self) -> Option<T> {
|
fn next_back(&mut self) -> Option<T> {
|
||||||
self.deque.pop_back()
|
self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> Drop for Drain<T> {
|
impl<'a, T> Drop for Drain<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
// exhaust self first
|
||||||
|
while let Some(_) = self.next() {}
|
||||||
|
|
||||||
|
if self.tail_len > 0 {
|
||||||
|
unsafe {
|
||||||
|
let source_vec = &mut **self.vec;
|
||||||
|
// memmove back untouched tail, update to new length
|
||||||
|
let start = source_vec.len();
|
||||||
|
let tail = self.tail_start;
|
||||||
|
let src = source_vec.as_ptr().offset(tail as isize);
|
||||||
|
let dst = source_vec.as_mut_ptr().offset(start as isize);
|
||||||
|
ptr::copy(src, dst, self.tail_len);
|
||||||
|
source_vec.set_len(start + self.tail_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> ExactSizeIterator for Drain<T> {}
|
impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
|
||||||
|
|
|
@ -296,5 +296,5 @@ fn test_extend_specialization() {
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn assert_covariance() {
|
fn assert_covariance() {
|
||||||
fn drain<'new>(d: Drain<&'static str>) -> Drain<&'new str> { d }
|
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
|
||||||
}
|
}
|
||||||
|
|
|
@ -513,7 +513,7 @@ fn test_cow_from() {
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn assert_covariance() {
|
fn assert_covariance() {
|
||||||
fn drain<'new>(d: Drain<&'static str>) -> Drain<&'new str> { d }
|
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue