@@ -73,8 +73,8 @@ use core::mem;
73
73
use core:: ops:: { Index , IndexMut } ;
74
74
use core:: ops;
75
75
use core:: ptr;
76
+ use core:: ptr:: Shared ;
76
77
use core:: slice;
77
- use super :: vec_deque:: VecDeque ;
78
78
79
79
use super :: SpecExtend ;
80
80
use super :: range:: RangeArgument ;
@@ -844,20 +844,20 @@ impl<T> Vec<T> {
844
844
let end = * range. end ( ) . unwrap_or ( & len) ;
845
845
assert ! ( start <= end) ;
846
846
assert ! ( end <= len) ;
847
- let mut drain_vec = VecDeque :: new ( ) ;
848
847
849
848
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 _ ) ,
853
860
}
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
861
861
}
862
862
}
863
863
@@ -1756,43 +1756,64 @@ impl<T> Drop for IntoIter<T> {
1756
1756
/// [`drain`]: struct.Vec.html#method.drain
1757
1757
/// [`Vec`]: struct.Vec.html
1758
1758
#[ 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 ,
1760
1764
/// Current remaining range to remove
1761
- deque : VecDeque < T >
1765
+ iter : slice:: Iter < ' a , T > ,
1766
+ vec : Shared < Vec < T > > ,
1762
1767
}
1763
1768
1764
1769
#[ 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 > { }
1766
1771
#[ 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 > { }
1768
1773
1769
1774
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1770
- impl < T > Iterator for Drain < T > {
1775
+ impl < ' a , T > Iterator for Drain < ' a , T > {
1771
1776
type Item = T ;
1772
1777
1773
1778
#[ inline]
1774
1779
fn next ( & mut self ) -> Option < T > {
1775
- self . deque . pop_front ( )
1780
+ self . iter . next ( ) . map ( |elt| unsafe { ptr :: read ( elt as * const _ ) } )
1776
1781
}
1777
1782
1778
1783
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1779
- ( self . deque . len ( ) , Some ( self . deque . len ( ) ) )
1784
+ self . iter . size_hint ( )
1780
1785
}
1781
1786
}
1782
1787
1783
1788
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1784
- impl < T > DoubleEndedIterator for Drain < T > {
1789
+ impl < ' a , T > DoubleEndedIterator for Drain < ' a , T > {
1785
1790
#[ inline]
1786
1791
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 _ ) } )
1788
1793
}
1789
1794
}
1790
1795
1791
1796
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1792
- impl < T > Drop for Drain < T > {
1797
+ impl < ' a , T > Drop for Drain < ' a , T > {
1793
1798
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
+ }
1794
1814
}
1795
1815
}
1796
1816
1817
+
1797
1818
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1798
- impl < T > ExactSizeIterator for Drain < T > { }
1819
+ impl < ' a , T > ExactSizeIterator for Drain < ' a , T > { }
0 commit comments