Skip to content

Commit d8816a7

Browse files
committed
Revert "use slice rotate methods"
It's slower than not combining remove/insert. This reverts commit 9c6d76e.
1 parent 9c6d76e commit d8816a7

File tree

1 file changed

+46
-3
lines changed

1 file changed

+46
-3
lines changed

src/vec/mod.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -991,13 +991,56 @@ impl<T, LenT: LenType, S: VecStorage<T> + ?Sized> VecInner<T, LenT, S> {
991991
assert!(remove_index < length);
992992
assert!(insert_index < length);
993993

994+
// SAFETY: `remove_index < length` assertion guarantees the pointer is within bounds.
995+
let to_remove = unsafe { ptr::read(self.as_ptr().add(remove_index)) };
996+
994997
match remove_index.cmp(&insert_index) {
995998
Ordering::Equal => (),
996-
Ordering::Less => self[remove_index..=insert_index].rotate_left(1),
997-
Ordering::Greater => self[insert_index..=remove_index].rotate_right(1),
999+
Ordering::Less => {
1000+
// SAFETY: `remove_index < length` assertion guarantees the pointer is within
1001+
// bounds.
1002+
let remove_at = unsafe { self.as_mut_ptr().add(remove_index) };
1003+
1004+
// SAFETY:
1005+
// Copies from
1006+
// (remove_index + 1)..(insert_index + 1)
1007+
// to
1008+
// remove_index..insert_index
1009+
//
1010+
// remove_index < insert_index (this match)
1011+
// remove_index + 1 < insert_index + 1 (can't saturate because <= length)
1012+
// remove_index + 1 <= insert_index < length
1013+
// insert_index + 1 <= length
1014+
//
1015+
// If `remove_index == 0`, and `insert_index + 1 == length`, then we copy from
1016+
// 1..length to 0..(length-1).
1017+
unsafe { ptr::copy(remove_at.add(1), remove_at, insert_index - remove_index) };
1018+
}
1019+
Ordering::Greater => {
1020+
// SAFETY: `insert_index < length` assertion guarantees the pointer is within
1021+
// bounds.
1022+
let insert_at = unsafe { self.as_mut_ptr().add(insert_index) };
1023+
1024+
// SAFETY:
1025+
// Copies from
1026+
// insert_index..remove_index
1027+
// to
1028+
// (insert_index + 1)..(remove_index + 1)
1029+
//
1030+
// insert_index < remove_index (this match)
1031+
// insert_index + 1 < remove_index + 1 (can't saturate because <= length)
1032+
// insert_index + 1 <= remove_index < length
1033+
// remove_index + 1 <= length
1034+
//
1035+
// If `insert_index == 0`, and `remove_index + 1 == length`, then we copy from
1036+
// 0..(length-1) to 1..(length).
1037+
unsafe { ptr::copy(insert_at, insert_at.add(1), remove_index - insert_index) };
1038+
}
9981039
}
9991040

1000-
mem::replace(&mut self[insert_index], element)
1041+
// SAFETY: `insert_index < length` assertion guarantees the pointer is within bounds.
1042+
unsafe { ptr::write(self.as_mut_ptr().add(insert_index), element) };
1043+
to_remove
10011044
}
10021045

10031046
/// Returns true if the vec is full

0 commit comments

Comments
 (0)