Skip to content

Commit

Permalink
Make insert_many panic-safe
Browse files Browse the repository at this point in the history
Fixes servo#96.
  • Loading branch information
mbrubeck committed Jul 18, 2018
1 parent bfdd7ee commit 3088dd0
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -772,23 +772,30 @@ impl<A: Array> SmallVec<A> {
let old_len = self.len();
assert!(index <= old_len);
let ptr = self.as_mut_ptr().offset(index as isize);

// Move the trailing elements.
ptr::copy(ptr, ptr.offset(lower_size_bound as isize), old_len - index);
for (off, element) in iter.enumerate() {
if off < lower_size_bound {
ptr::write(ptr.offset(off as isize), element);
let len = self.len() + 1;
self.set_len(len);
} else {
// Iterator provided more elements than the hint.
assert!(index + off >= index); // Protect against overflow.
self.insert(index + off, element);

// In case the iterator panics, don't double-drop the items we just copied above.
self.set_len(index);

let mut num_added = 0;
for element in iter {
let cur = ptr.offset(num_added as isize);
if num_added >= lower_size_bound {
// Iterator provided more elements than the hint. Move trailing items again.
self.reserve(1);
ptr::copy(cur, cur.offset(1), old_len - index);
}
ptr::write(cur, element);
num_added += 1;
}
let num_added = self.len() - old_len;
if num_added < lower_size_bound {
// Iterator provided fewer elements than the hint
ptr::copy(ptr.offset(lower_size_bound as isize), ptr.offset(num_added as isize), old_len - index);
}

self.set_len(old_len + num_added);
}
}

Expand Down

0 comments on commit 3088dd0

Please sign in to comment.