@@ -1009,21 +1009,24 @@ impl<A: Array> SmallVec<A> {
10091009 /// Insert multiple elements at position `index`, shifting all following elements toward the
10101010 /// back.
10111011 pub fn insert_many < I : IntoIterator < Item = A :: Item > > ( & mut self , index : usize , iterable : I ) {
1012- let iter = iterable. into_iter ( ) ;
1012+ let mut iter = iterable. into_iter ( ) ;
10131013 if index == self . len ( ) {
10141014 return self . extend ( iter) ;
10151015 }
10161016
10171017 let ( lower_size_bound, _) = iter. size_hint ( ) ;
10181018 assert ! ( lower_size_bound <= core:: isize :: MAX as usize ) ; // Ensure offset is indexable
10191019 assert ! ( index + lower_size_bound >= index) ; // Protect against overflow
1020- self . reserve ( lower_size_bound) ;
1020+
1021+ let mut num_added = 0 ;
1022+ let old_len = self . len ( ) ;
1023+ assert ! ( index <= old_len) ;
10211024
10221025 unsafe {
1023- let old_len = self . len ( ) ;
1024- assert ! ( index <= old_len ) ;
1026+ // Reserve space for `lower_size_bound` elements.
1027+ self . reserve ( lower_size_bound ) ;
10251028 let start = self . as_mut_ptr ( ) ;
1026- let mut ptr = start. add ( index) ;
1029+ let ptr = start. add ( index) ;
10271030
10281031 // Move the trailing elements.
10291032 ptr:: copy ( ptr, ptr. add ( lower_size_bound) , old_len - index) ;
@@ -1036,42 +1039,39 @@ impl<A: Array> SmallVec<A> {
10361039 len : old_len + lower_size_bound,
10371040 } ;
10381041
1039- let mut num_added = 0 ;
1040- for element in iter {
1041- let mut cur = ptr. add ( num_added) ;
1042- if num_added >= lower_size_bound {
1043- // Iterator provided more elements than the hint. Move trailing items again.
1044- self . reserve ( 1 ) ;
1045- let start = self . as_mut_ptr ( ) ;
1046- ptr = start. add ( index) ;
1047- cur = ptr. add ( num_added) ;
1048- ptr:: copy ( cur, cur. add ( 1 ) , old_len - index) ;
1049-
1050- guard. start = start;
1051- guard. len += 1 ;
1052- guard. skip . end += 1 ;
1053- }
1042+ while num_added < lower_size_bound {
1043+ let element = match iter. next ( ) {
1044+ Some ( x) => x,
1045+ None => break ,
1046+ } ;
1047+ let cur = ptr. add ( num_added) ;
10541048 ptr:: write ( cur, element) ;
10551049 guard. skip . start += 1 ;
10561050 num_added += 1 ;
10571051 }
1058- mem:: forget ( guard) ;
10591052
10601053 if num_added < lower_size_bound {
1061- // Iterator provided fewer elements than the hint
1054+ // Iterator provided fewer elements than the hint. Move the tail backward.
10621055 ptr:: copy (
10631056 ptr. add ( lower_size_bound) ,
10641057 ptr. add ( num_added) ,
10651058 old_len - index,
10661059 ) ;
10671060 }
1068-
1061+ // There are no more duplicate or uninitialized slots, so the guard is not needed.
10691062 self . set_len ( old_len + num_added) ;
1063+ mem:: forget ( guard) ;
1064+ }
1065+
1066+ // Insert any remaining elements one-by-one.
1067+ for element in iter {
1068+ self . insert ( index + num_added, element) ;
1069+ num_added += 1 ;
10701070 }
10711071
10721072 struct DropOnPanic < T > {
10731073 start : * mut T ,
1074- skip : Range < usize > ,
1074+ skip : Range < usize > , // Space we copied-out-of, but haven't written-to yet.
10751075 len : usize ,
10761076 }
10771077
0 commit comments