@@ -55,12 +55,15 @@ use std::borrow::{Borrow, BorrowMut};
55
55
use std:: cmp;
56
56
use std:: fmt;
57
57
use std:: hash:: { Hash , Hasher } ;
58
- use std:: iter:: { IntoIterator , FromIterator , repeat} ;
58
+ use std:: iter:: { IntoIterator , FromIterator , FusedIterator , repeat} ;
59
59
use std:: mem;
60
60
use std:: mem:: ManuallyDrop ;
61
61
use std:: ops;
62
62
use std:: ptr;
63
+ use std:: fmt:: Debug ;
63
64
use std:: slice;
65
+ use std:: ops:: { RangeBounds , Bound } ;
66
+ use std:: ptr:: NonNull ;
64
67
#[ cfg( feature = "std" ) ]
65
68
use std:: io;
66
69
#[ cfg( feature = "serde" ) ]
@@ -240,15 +243,32 @@ unsafe fn deallocate<T>(ptr: *mut T, capacity: usize) {
240
243
/// Returned from [`SmallVec::drain`][1].
241
244
///
242
245
/// [1]: struct.SmallVec.html#method.drain
243
- pub struct Drain < ' a , T : ' a > {
244
- iter : slice:: IterMut < ' a , T > ,
246
+ pub struct Drain < ' a , T : ' a + Array > {
247
+ tail_start : usize ,
248
+ tail_len : usize ,
249
+ iter : slice:: Iter < ' a , T :: Item > ,
250
+ vec : NonNull < SmallVec < T > >
245
251
}
246
252
247
- impl < ' a , T : ' a > Iterator for Drain < ' a , T > {
248
- type Item = T ;
253
+ impl < ' a , T : ' a + Array > fmt:: Debug for Drain < ' a , T >
254
+ where T :: Item : Debug
255
+ {
256
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
257
+ f. debug_tuple ( "Drain" )
258
+ . field ( & self . iter . as_slice ( ) )
259
+ . finish ( )
260
+ }
261
+ }
262
+
263
+ unsafe impl < ' a , T : Sync + Array > Sync for Drain < ' a , T > { }
264
+ unsafe impl < ' a , T : Send + Array > Send for Drain < ' a , T > { }
265
+
266
+
267
+ impl < ' a , T : ' a + Array > Iterator for Drain < ' a , T > {
268
+ type Item = T :: Item ;
249
269
250
270
#[ inline]
251
- fn next ( & mut self ) -> Option < T > {
271
+ fn next ( & mut self ) -> Option < T :: Item > {
252
272
self . iter . next ( ) . map ( |reference| unsafe { ptr:: read ( reference) } )
253
273
}
254
274
@@ -258,19 +278,41 @@ impl<'a, T: 'a> Iterator for Drain<'a,T> {
258
278
}
259
279
}
260
280
261
- impl < ' a , T : ' a > DoubleEndedIterator for Drain < ' a , T > {
281
+ impl < ' a , T : ' a + Array > DoubleEndedIterator for Drain < ' a , T > {
262
282
#[ inline]
263
- fn next_back ( & mut self ) -> Option < T > {
283
+ fn next_back ( & mut self ) -> Option < T :: Item > {
264
284
self . iter . next_back ( ) . map ( |reference| unsafe { ptr:: read ( reference) } )
265
285
}
266
286
}
267
287
268
- impl < ' a , T > ExactSizeIterator for Drain < ' a , T > { }
288
+ impl < ' a , T : Array > ExactSizeIterator for Drain < ' a , T > {
289
+ #[ inline]
290
+ fn len ( & self ) -> usize {
291
+ self . iter . len ( )
292
+ }
293
+ }
269
294
270
- impl < ' a , T : ' a > Drop for Drain < ' a , T > {
295
+ impl < ' a , T : Array > FusedIterator for Drain < ' a , T > { }
296
+
297
+ impl < ' a , T : ' a + Array > Drop for Drain < ' a , T > {
271
298
fn drop ( & mut self ) {
272
- // Destroy the remaining elements.
273
- for _ in self . by_ref ( ) { }
299
+ self . for_each ( drop) ;
300
+
301
+ if self . tail_len > 0 {
302
+ unsafe {
303
+ let source_vec = self . vec . as_mut ( ) ;
304
+
305
+ // memmove back untouched tail, update to new length
306
+ let start = source_vec. len ( ) ;
307
+ let tail = self . tail_start ;
308
+ if tail != start {
309
+ let src = source_vec. as_ptr ( ) . add ( tail) ;
310
+ let dst = source_vec. as_mut_ptr ( ) . add ( start) ;
311
+ ptr:: copy ( src, dst, self . tail_len ) ;
312
+ }
313
+ source_vec. set_len ( start + self . tail_len ) ;
314
+ }
315
+ }
274
316
}
275
317
}
276
318
@@ -596,18 +638,50 @@ impl<A: Array> SmallVec<A> {
596
638
self . capacity > A :: size ( )
597
639
}
598
640
599
- /// Empty the vector and return an iterator over its former contents.
600
- pub fn drain ( & mut self ) -> Drain < A :: Item > {
601
- unsafe {
602
- let ptr = self . as_mut_ptr ( ) ;
641
+ /// Creates a draining iterator that removes the specified range in the vector
642
+ /// and yields the removed items.
643
+ ///
644
+ /// Note 1: The element range is removed even if the iterator is only
645
+ /// partially consumed or not consumed at all.
646
+ ///
647
+ /// Note 2: It is unspecified how many elements are removed from the vector
648
+ /// if the `Drain` value is leaked.
649
+ ///
650
+ /// # Panics
651
+ ///
652
+ /// Panics if the starting point is greater than the end point or if
653
+ /// the end point is greater than the length of the vector.
654
+ pub fn drain < R > ( & mut self , range : R ) -> Drain < A >
655
+ where R : RangeBounds < usize >
656
+ {
657
+ use Bound :: * ;
603
658
604
- let current_len = self . len ( ) ;
605
- self . set_len ( 0 ) ;
659
+ let len = self . len ( ) ;
660
+ let start = match range. start_bound ( ) {
661
+ Included ( & n) => n,
662
+ Excluded ( & n) => n + 1 ,
663
+ Unbounded => 0 ,
664
+ } ;
665
+ let end = match range. end_bound ( ) {
666
+ Included ( & n) => n + 1 ,
667
+ Excluded ( & n) => n,
668
+ Unbounded => len,
669
+ } ;
670
+
671
+ assert ! ( start <= end) ;
672
+ assert ! ( end <= len) ;
673
+
674
+ unsafe {
675
+ self . set_len ( start) ;
606
676
607
- let slice = slice:: from_raw_parts_mut ( ptr, current_len) ;
677
+ let range_slice = slice:: from_raw_parts_mut ( self . as_mut_ptr ( ) . add ( start) ,
678
+ end - start) ;
608
679
609
680
Drain {
610
- iter : slice. iter_mut ( ) ,
681
+ tail_start : end,
682
+ tail_len : len - end,
683
+ iter : range_slice. iter ( ) ,
684
+ vec : NonNull :: from ( self ) ,
611
685
}
612
686
}
613
687
}
@@ -1711,26 +1785,36 @@ mod tests {
1711
1785
fn drain ( ) {
1712
1786
let mut v: SmallVec < [ u8 ; 2 ] > = SmallVec :: new ( ) ;
1713
1787
v. push ( 3 ) ;
1714
- assert_eq ! ( v. drain( ) . collect:: <Vec <_>>( ) , & [ 3 ] ) ;
1788
+ assert_eq ! ( v. drain( .. ) . collect:: <Vec <_>>( ) , & [ 3 ] ) ;
1715
1789
1716
1790
// spilling the vec
1717
1791
v. push ( 3 ) ;
1718
1792
v. push ( 4 ) ;
1719
1793
v. push ( 5 ) ;
1720
- assert_eq ! ( v. drain( ) . collect:: <Vec <_>>( ) , & [ 3 , 4 , 5 ] ) ;
1794
+ let old_capacity = v. capacity ( ) ;
1795
+ assert_eq ! ( v. drain( 1 ..) . collect:: <Vec <_>>( ) , & [ 4 , 5 ] ) ;
1796
+ // drain should not change the capacity
1797
+ assert_eq ! ( v. capacity( ) , old_capacity) ;
1721
1798
}
1722
1799
1723
1800
#[ test]
1724
1801
fn drain_rev ( ) {
1725
1802
let mut v: SmallVec < [ u8 ; 2 ] > = SmallVec :: new ( ) ;
1726
1803
v. push ( 3 ) ;
1727
- assert_eq ! ( v. drain( ) . rev( ) . collect:: <Vec <_>>( ) , & [ 3 ] ) ;
1804
+ assert_eq ! ( v. drain( .. ) . rev( ) . collect:: <Vec <_>>( ) , & [ 3 ] ) ;
1728
1805
1729
1806
// spilling the vec
1730
1807
v. push ( 3 ) ;
1731
1808
v. push ( 4 ) ;
1732
1809
v. push ( 5 ) ;
1733
- assert_eq ! ( v. drain( ) . rev( ) . collect:: <Vec <_>>( ) , & [ 5 , 4 , 3 ] ) ;
1810
+ assert_eq ! ( v. drain( ..) . rev( ) . collect:: <Vec <_>>( ) , & [ 5 , 4 , 3 ] ) ;
1811
+ }
1812
+
1813
+ #[ test]
1814
+ fn drain_forget ( ) {
1815
+ let mut v: SmallVec < [ u8 ; 1 ] > = smallvec ! [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ;
1816
+ std:: mem:: forget ( v. drain ( 2 ..5 ) ) ;
1817
+ assert_eq ! ( v. len( ) , 2 ) ;
1734
1818
}
1735
1819
1736
1820
#[ test]
@@ -2125,7 +2209,8 @@ mod tests {
2125
2209
fn test_exact_size_iterator ( ) {
2126
2210
let mut vec = SmallVec :: < [ u32 ; 2 ] > :: from ( & [ 1 , 2 , 3 ] [ ..] ) ;
2127
2211
assert_eq ! ( vec. clone( ) . into_iter( ) . len( ) , 3 ) ;
2128
- assert_eq ! ( vec. drain( ) . len( ) , 3 ) ;
2212
+ assert_eq ! ( vec. drain( ..2 ) . len( ) , 2 ) ;
2213
+ assert_eq ! ( vec. into_iter( ) . len( ) , 1 ) ;
2129
2214
}
2130
2215
2131
2216
#[ test]
0 commit comments