use std::ptr;
use crate::base::marker::ThreadBound;
#[derive(Debug)]
#[must_use = "insert a value or abandon the searched position"]
pub struct Gap<'a, T> {
values: &'a mut Vec<T>,
index: usize,
_bound: ThreadBound,
}
impl<'a, T> Gap<'a, T> {
pub fn partition(values: &'a mut Vec<T>, before: impl FnMut(&T) -> bool) -> Self {
let index = values.partition_point(before);
Self {
values,
index,
_bound: ThreadBound::NEW,
}
}
pub const fn index(&self) -> usize {
self.index
}
pub fn tail(&self) -> &[T] {
unsafe { self.values.get_unchecked(self.index..) }
}
pub fn try_insert(self, value: T) -> Result<(), T> {
let len = self.values.len();
if len == self.values.capacity() {
return Err(value);
}
unsafe {
let start = self.values.as_mut_ptr().add(self.index);
ptr::copy(start, start.add(1), len - self.index);
start.write(value);
self.values.set_len(len + 1);
}
Ok(())
}
}