@@ -823,7 +823,7 @@ impl<A: Array> SmallVec<A> {
823
823
/// Insert multiple elements at position `index`, shifting all following elements toward the
824
824
/// back.
825
825
pub fn insert_many < I : IntoIterator < Item =A :: Item > > ( & mut self , index : usize , iterable : I ) {
826
- let iter = iterable. into_iter ( ) ;
826
+ let mut iter = iterable. into_iter ( ) ;
827
827
if index == self . len ( ) {
828
828
return self . extend ( iter) ;
829
829
}
@@ -832,38 +832,40 @@ impl<A: Array> SmallVec<A> {
832
832
assert ! ( lower_size_bound <= std:: isize :: MAX as usize ) ; // Ensure offset is indexable
833
833
assert ! ( index + lower_size_bound >= index) ; // Protect against overflow
834
834
self . reserve ( lower_size_bound) ;
835
+ let mut num_added = 0 ;
835
836
836
837
unsafe {
837
838
let old_len = self . len ( ) ;
838
839
assert ! ( index <= old_len) ;
839
- let mut ptr = self . as_mut_ptr ( ) . offset ( index as isize ) ;
840
+ let ptr = self . as_mut_ptr ( ) . offset ( index as isize ) ;
840
841
841
842
// Move the trailing elements.
842
843
ptr:: copy ( ptr, ptr. offset ( lower_size_bound as isize ) , old_len - index) ;
843
844
844
845
// In case the iterator panics, don't double-drop the items we just copied above.
845
846
self . set_len ( index) ;
846
847
847
- let mut num_added = 0 ;
848
- for element in iter {
849
- let mut cur = ptr. offset ( num_added as isize ) ;
850
- if num_added >= lower_size_bound {
851
- // Iterator provided more elements than the hint. Move trailing items again.
852
- self . reserve ( 1 ) ;
853
- ptr = self . as_mut_ptr ( ) . offset ( index as isize ) ;
854
- cur = ptr. offset ( num_added as isize ) ;
855
- ptr:: copy ( cur, cur. offset ( 1 ) , old_len - index) ;
856
- }
848
+ while num_added < lower_size_bound {
849
+ let element = match iter. next ( ) {
850
+ Some ( x) => x,
851
+ None => break ,
852
+ } ;
853
+ let cur = ptr. offset ( num_added as isize ) ;
857
854
ptr:: write ( cur, element) ;
858
855
num_added += 1 ;
859
856
}
860
857
if num_added < lower_size_bound {
861
858
// Iterator provided fewer elements than the hint
862
859
ptr:: copy ( ptr. offset ( lower_size_bound as isize ) , ptr. offset ( num_added as isize ) , old_len - index) ;
863
860
}
864
-
865
861
self . set_len ( old_len + num_added) ;
866
862
}
863
+
864
+ // If the iterator has more than `lower_size_bound` elements, insert the rest one-by-one.
865
+ for element in iter {
866
+ self . insert ( index + num_added, element) ;
867
+ num_added += 1 ;
868
+ }
867
869
}
868
870
869
871
/// Convert a SmallVec to a Vec, without reallocating if the SmallVec has already spilled onto
@@ -2371,4 +2373,17 @@ mod tests {
2371
2373
assert_eq ! ( v. capacity( ) , 4 ) ;
2372
2374
assert_eq ! ( v[ ..] , [ 0 , 1 , 2 ] ) ;
2373
2375
}
2376
+
2377
+ #[ test]
2378
+ fn test_insert_many_overflow ( ) {
2379
+ let mut v: SmallVec < [ u8 ; 1 ] > = SmallVec :: new ( ) ;
2380
+ v. push ( 123 ) ;
2381
+
2382
+ // Prepare an iterator with small lower bound
2383
+ let iter = ( 0u8 ..5 ) . filter ( |n| n % 2 == 0 ) ;
2384
+ assert_eq ! ( iter. size_hint( ) . 0 , 0 ) ;
2385
+
2386
+ v. insert_many ( 0 , iter) ;
2387
+ assert_eq ! ( & * v, & [ 0 , 2 , 4 , 123 ] ) ;
2388
+ }
2374
2389
}
0 commit comments