Skip to content

Commit d1e2a93

Browse files
committedJul 22, 2016
Readding lifetime parameters and removing allocation
1 parent 97d082c commit d1e2a93

File tree

4 files changed

+51
-30
lines changed

4 files changed

+51
-30
lines changed
 

‎src/libcollections/binary_heap.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1016,12 +1016,12 @@ impl<T> ExactSizeIterator for IntoIter<T> {}
10161016

10171017
/// An iterator that drains a `BinaryHeap`.
10181018
#[stable(feature = "drain", since = "1.6.0")]
1019-
pub struct Drain<T> {
1020-
iter: vec::Drain<T>,
1019+
pub struct Drain<'a, T: 'a> {
1020+
iter: vec::Drain<'a, T>,
10211021
}
10221022

10231023
#[stable(feature = "rust1", since = "1.0.0")]
1024-
impl<T> Iterator for Drain<T> {
1024+
impl<'a, T: 'a> Iterator for Drain<'a, T> {
10251025
type Item = T;
10261026

10271027
#[inline]
@@ -1036,15 +1036,15 @@ impl<T> Iterator for Drain<T> {
10361036
}
10371037

10381038
#[stable(feature = "rust1", since = "1.0.0")]
1039-
impl<T> DoubleEndedIterator for Drain<T> {
1039+
impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
10401040
#[inline]
10411041
fn next_back(&mut self) -> Option<T> {
10421042
self.iter.next_back()
10431043
}
10441044
}
10451045

10461046
#[stable(feature = "rust1", since = "1.0.0")]
1047-
impl<T> ExactSizeIterator for Drain<T> {}
1047+
impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
10481048

10491049
#[stable(feature = "rust1", since = "1.0.0")]
10501050
impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {

‎src/libcollections/vec.rs

+44-23
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ use core::mem;
7373
use core::ops::{Index, IndexMut};
7474
use core::ops;
7575
use core::ptr;
76+
use core::ptr::Shared;
7677
use core::slice;
77-
use super::vec_deque::VecDeque;
7878

7979
use super::SpecExtend;
8080
use super::range::RangeArgument;
@@ -844,20 +844,20 @@ impl<T> Vec<T> {
844844
let end = *range.end().unwrap_or(&len);
845845
assert!(start <= end);
846846
assert!(end <= len);
847-
let mut drain_vec = VecDeque::new();
848847

849848
unsafe {
850-
for i in start..end {
851-
let p = self.as_ptr().offset(i as isize);
852-
drain_vec.push_back(ptr::read(p));
849+
// set self.vec length's to start, to be safe in case Drain is leaked
850+
self.set_len(start);
851+
// Use the borrow in the IterMut to indicate borrowing behavior of the
852+
// whole Drain iterator (like &mut T).
853+
let range_slice = slice::from_raw_parts_mut(self.as_mut_ptr().offset(start as isize),
854+
end - start);
855+
Drain {
856+
tail_start: end,
857+
tail_len: len - end,
858+
iter: range_slice.iter(),
859+
vec: Shared::new(self as *mut _),
853860
}
854-
let src = self.as_ptr().offset(end as isize);
855-
let dst = self.as_mut_ptr().offset(start as isize);
856-
ptr::copy(src, dst, len - end);
857-
self.set_len(len - (end - start));
858-
}
859-
Drain {
860-
deque: drain_vec
861861
}
862862
}
863863

@@ -1756,43 +1756,64 @@ impl<T> Drop for IntoIter<T> {
17561756
/// [`drain`]: struct.Vec.html#method.drain
17571757
/// [`Vec`]: struct.Vec.html
17581758
#[stable(feature = "drain", since = "1.6.0")]
1759-
pub struct Drain<T> {
1759+
pub struct Drain<'a, T: 'a> {
1760+
/// Index of tail to preserve
1761+
tail_start: usize,
1762+
/// Length of tail
1763+
tail_len: usize,
17601764
/// Current remaining range to remove
1761-
deque: VecDeque<T>
1765+
iter: slice::Iter<'a, T>,
1766+
vec: Shared<Vec<T>>,
17621767
}
17631768

17641769
#[stable(feature = "drain", since = "1.6.0")]
1765-
unsafe impl<T: Sync> Sync for Drain<T> {}
1770+
unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {}
17661771
#[stable(feature = "drain", since = "1.6.0")]
1767-
unsafe impl<T: Send> Send for Drain<T> {}
1772+
unsafe impl<'a, T: Send> Send for Drain<'a, T> {}
17681773

17691774
#[stable(feature = "rust1", since = "1.0.0")]
1770-
impl<T> Iterator for Drain<T> {
1775+
impl<'a, T> Iterator for Drain<'a, T> {
17711776
type Item = T;
17721777

17731778
#[inline]
17741779
fn next(&mut self) -> Option<T> {
1775-
self.deque.pop_front()
1780+
self.iter.next().map(|elt| unsafe { ptr::read(elt as *const _) })
17761781
}
17771782

17781783
fn size_hint(&self) -> (usize, Option<usize>) {
1779-
(self.deque.len(), Some(self.deque.len()))
1784+
self.iter.size_hint()
17801785
}
17811786
}
17821787

17831788
#[stable(feature = "rust1", since = "1.0.0")]
1784-
impl<T> DoubleEndedIterator for Drain<T> {
1789+
impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
17851790
#[inline]
17861791
fn next_back(&mut self) -> Option<T> {
1787-
self.deque.pop_back()
1792+
self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) })
17881793
}
17891794
}
17901795

17911796
#[stable(feature = "rust1", since = "1.0.0")]
1792-
impl<T> Drop for Drain<T> {
1797+
impl<'a, T> Drop for Drain<'a, T> {
17931798
fn drop(&mut self) {
1799+
// exhaust self first
1800+
while let Some(_) = self.next() {}
1801+
1802+
if self.tail_len > 0 {
1803+
unsafe {
1804+
let source_vec = &mut **self.vec;
1805+
// memmove back untouched tail, update to new length
1806+
let start = source_vec.len();
1807+
let tail = self.tail_start;
1808+
let src = source_vec.as_ptr().offset(tail as isize);
1809+
let dst = source_vec.as_mut_ptr().offset(start as isize);
1810+
ptr::copy(src, dst, self.tail_len);
1811+
source_vec.set_len(start + self.tail_len);
1812+
}
1813+
}
17941814
}
17951815
}
17961816

1817+
17971818
#[stable(feature = "rust1", since = "1.0.0")]
1798-
impl<T> ExactSizeIterator for Drain<T> {}
1819+
impl<'a, T> ExactSizeIterator for Drain<'a, T> {}

‎src/libcollectionstest/binary_heap.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,5 +296,5 @@ fn test_extend_specialization() {
296296

297297
#[allow(dead_code)]
298298
fn assert_covariance() {
299-
fn drain<'new>(d: Drain<&'static str>) -> Drain<&'new str> { d }
299+
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
300300
}

‎src/libcollectionstest/vec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ fn test_cow_from() {
513513

514514
#[allow(dead_code)]
515515
fn assert_covariance() {
516-
fn drain<'new>(d: Drain<&'static str>) -> Drain<&'new str> { d }
516+
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
517517
}
518518

519519
#[bench]

0 commit comments

Comments
 (0)
Please sign in to comment.