@@ -823,7 +823,7 @@ impl<A: Array> SmallVec<A> {
823823 /// Insert multiple elements at position `index`, shifting all following elements toward the
824824 /// back.
825825 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 ( ) ;
827827 if index == self . len ( ) {
828828 return self . extend ( iter) ;
829829 }
@@ -832,38 +832,40 @@ impl<A: Array> SmallVec<A> {
832832 assert ! ( lower_size_bound <= std:: isize :: MAX as usize ) ; // Ensure offset is indexable
833833 assert ! ( index + lower_size_bound >= index) ; // Protect against overflow
834834 self . reserve ( lower_size_bound) ;
835+ let mut num_added = 0 ;
835836
836837 unsafe {
837838 let old_len = self . len ( ) ;
838839 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 ) ;
840841
841842 // Move the trailing elements.
842843 ptr:: copy ( ptr, ptr. offset ( lower_size_bound as isize ) , old_len - index) ;
843844
844845 // In case the iterator panics, don't double-drop the items we just copied above.
845846 self . set_len ( index) ;
846847
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 ) ;
857854 ptr:: write ( cur, element) ;
858855 num_added += 1 ;
859856 }
860857 if num_added < lower_size_bound {
861858 // Iterator provided fewer elements than the hint
862859 ptr:: copy ( ptr. offset ( lower_size_bound as isize ) , ptr. offset ( num_added as isize ) , old_len - index) ;
863860 }
864-
865861 self . set_len ( old_len + num_added) ;
866862 }
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+ }
867869 }
868870
869871 /// Convert a SmallVec to a Vec, without reallocating if the SmallVec has already spilled onto
@@ -2371,4 +2373,17 @@ mod tests {
23712373 assert_eq ! ( v. capacity( ) , 4 ) ;
23722374 assert_eq ! ( v[ ..] , [ 0 , 1 , 2 ] ) ;
23732375 }
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+ }
23742389}
0 commit comments