@@ -1009,21 +1009,24 @@ impl<A: Array> SmallVec<A> {
1009
1009
/// Insert multiple elements at position `index`, shifting all following elements toward the
1010
1010
/// back.
1011
1011
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 ( ) ;
1013
1013
if index == self . len ( ) {
1014
1014
return self . extend ( iter) ;
1015
1015
}
1016
1016
1017
1017
let ( lower_size_bound, _) = iter. size_hint ( ) ;
1018
1018
assert ! ( lower_size_bound <= core:: isize :: MAX as usize ) ; // Ensure offset is indexable
1019
1019
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) ;
1021
1024
1022
1025
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 ) ;
1025
1028
let start = self . as_mut_ptr ( ) ;
1026
- let mut ptr = start. add ( index) ;
1029
+ let ptr = start. add ( index) ;
1027
1030
1028
1031
// Move the trailing elements.
1029
1032
ptr:: copy ( ptr, ptr. add ( lower_size_bound) , old_len - index) ;
@@ -1036,42 +1039,39 @@ impl<A: Array> SmallVec<A> {
1036
1039
len : old_len + lower_size_bound,
1037
1040
} ;
1038
1041
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) ;
1054
1048
ptr:: write ( cur, element) ;
1055
1049
guard. skip . start += 1 ;
1056
1050
num_added += 1 ;
1057
1051
}
1058
- mem:: forget ( guard) ;
1059
1052
1060
1053
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.
1062
1055
ptr:: copy (
1063
1056
ptr. add ( lower_size_bound) ,
1064
1057
ptr. add ( num_added) ,
1065
1058
old_len - index,
1066
1059
) ;
1067
1060
}
1068
-
1061
+ // There are no more duplicate or uninitialized slots, so the guard is not needed.
1069
1062
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 ;
1070
1070
}
1071
1071
1072
1072
struct DropOnPanic < T > {
1073
1073
start : * mut T ,
1074
- skip : Range < usize > ,
1074
+ skip : Range < usize > , // Space we copied-out-of, but haven't written-to yet.
1075
1075
len : usize ,
1076
1076
}
1077
1077
0 commit comments