extern crate alloc;
use alloc::vec::Vec;
use core::mem::MaybeUninit;
use core::ptr;
pub(super) trait InsertMany<T> {
fn insert_many(&mut self, insert: &mut Vec<(usize, T)>);
}
impl<T> InsertMany<T> for Vec<T> {
fn insert_many(&mut self, insert: &mut Vec<(usize, T)>) {
self.reserve(insert.len());
insert.sort_by_key(|d| d.0);
let new_len = self
.len()
.checked_add(insert.len())
.expect("<Vec<T> as InsertMany>: New len overflows usize");
if let Some((idx, _)) = insert.last() {
assert!(
*idx <= self.len(),
"<Vec<T> as InsertMany>: an index passed was greater than the length of the list"
);
}
{
unsafe { self.set_len(0) };
let raw_vec = self.spare_capacity_mut();
let mut insert_left = insert.len();
let mut written_to = new_len;
for (idx, t) in insert.drain(..).rev() {
insert_left -= 1;
let my_idx = insert_left + idx;
let v_ptr = (raw_vec as *mut [MaybeUninit<T>]).cast::<MaybeUninit<T>>();
if (written_to - (my_idx + 1)) != 0 {
debug_assert!(my_idx + 1 < new_len);
debug_assert!(written_to <= new_len);
debug_assert!(idx < new_len);
unsafe {
ptr::copy(
v_ptr.add(idx).cast_const(),
v_ptr.add(my_idx + 1),
written_to - (my_idx + 1),
);
}
}
raw_vec[my_idx].write(t);
written_to = my_idx;
}
unsafe { self.set_len(new_len) };
}
}
}
#[test]
fn oh_boy() {
extern crate std;
let mut v = std::vec![1, 2, 3, 4];
v.insert_many(&mut std::vec![
(0, 8i32),
(0, 7),
(1, 6),
(4, 5),
(4, 10),
(3, 11)
]);
assert_eq!(v, &[8, 7, 1, 6, 2, 3, 11, 4, 5, 10]);
v.insert_many(&mut [(0, 0)].into());
assert_eq!(v, &[0, 8, 7, 1, 6, 2, 3, 11, 4, 5, 10]);
v.insert_many(&mut std::vec![(v.len(), 32)]);
assert_eq!(v, &[0, 8, 7, 1, 6, 2, 3, 11, 4, 5, 10, 32]);
Vec::<u8>::new().insert_many(&mut Vec::new());
Vec::<u8>::new().insert_many(&mut std::vec![(0, 1), (0, 2), (0, 3)]);
Vec::<u8>::from([1, 2, 3]).insert_many(&mut Vec::new());
Vec::<u8>::from([1]).insert_many(&mut Vec::new());
}
#[test]
#[should_panic]
fn size_overflow() {
extern crate std;
use alloc::vec;
vec![].insert_many(&mut vec![(1, 2u8)]);
}
#[test]
fn assert_zsts() {
use alloc::vec;
vec![(), (), ()].insert_many(&mut vec![(0, ()), (1, ()), (2, ()), (3, ()), (1, ())]);
vec![(), ()].insert_many(&mut vec![(0, ()), (1, ()), (2, ()), (1, ())]);
vec![].insert_many(&mut vec![(0, ())]);
}