mirror of
https://github.com/Noratrieb/datastructures.git
synced 2026-01-14 17:35:02 +01:00
insert_after on cursor
This commit is contained in:
parent
5c4deeadc0
commit
3c7ddc8340
2 changed files with 19 additions and 5 deletions
|
|
@ -399,7 +399,7 @@ impl<T> Node<T> {
|
||||||
fn allocate_nonnull<T>(element: T) -> NonNull<T> {
|
fn allocate_nonnull<T>(element: T) -> NonNull<T> {
|
||||||
let boxed = Box::new(element);
|
let boxed = Box::new(element);
|
||||||
// SAFETY: box is always non-null
|
// SAFETY: box is always non-null
|
||||||
unsafe { NonNull::new_unchecked(Box::leak(boxed)) }
|
unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The iterator over the linked list
|
/// The iterator over the linked list
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use std::ptr::NonNull;
|
||||||
|
|
||||||
fn allocate_nonnull<T>(element: T) -> NonNull<T> {
|
fn allocate_nonnull<T>(element: T) -> NonNull<T> {
|
||||||
// SAFETY: box is always non-null
|
// SAFETY: box is always non-null
|
||||||
unsafe { NonNull::new_unchecked(Box::leak(Box::new(element))) }
|
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(element))) }
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -363,6 +363,7 @@ impl<T, const COUNT: usize> Node<T, COUNT> {
|
||||||
// copy all values up
|
// copy all values up
|
||||||
if COUNT > 1 {
|
if COUNT > 1 {
|
||||||
std::ptr::copy(
|
std::ptr::copy(
|
||||||
|
// todo miri error here
|
||||||
&self.values[index] as *const _,
|
&self.values[index] as *const _,
|
||||||
&mut self.values[index + 1] as *mut _,
|
&mut self.values[index + 1] as *mut _,
|
||||||
self.size - index,
|
self.size - index,
|
||||||
|
|
@ -506,8 +507,21 @@ impl<'a, T, const COUNT: usize> CursorMut<'a, T, COUNT> {
|
||||||
// SAFETY: the node is not full and the index is not out of bounds
|
// SAFETY: the node is not full and the index is not out of bounds
|
||||||
(false, false) => unsafe { current.insert(element, self.index + 1) },
|
(false, false) => unsafe { current.insert(element, self.index + 1) },
|
||||||
(false, true) => {
|
(false, true) => {
|
||||||
// check whether the next node is full. if it is not full, insert it at the start
|
// we need to copy some values to the next node, always allocate a new one to avoid needing to copy too many values
|
||||||
// if it is full or the next node doesn't exist, allocate a new node inbetween
|
// nodes that are not very full will make insertions faster later, so we prefer them
|
||||||
|
unsafe {
|
||||||
|
let mut next = self.allocate_new_node_after();
|
||||||
|
let next = next.as_mut();
|
||||||
|
let to_copy = next.size - self.index;
|
||||||
|
std::ptr::copy_nonoverlapping(
|
||||||
|
¤t.values[self.index] as *const _,
|
||||||
|
&mut next.values[0] as *mut _,
|
||||||
|
to_copy,
|
||||||
|
);
|
||||||
|
current.values[self.index] = MaybeUninit::new(element);
|
||||||
|
next.size = to_copy;
|
||||||
|
current.size = self.index + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -656,7 +670,7 @@ mod iter {
|
||||||
node: list.first.map(|nn| unsafe { Box::from_raw(nn.as_ptr()) }),
|
node: list.first.map(|nn| unsafe { Box::from_raw(nn.as_ptr()) }),
|
||||||
index: 0,
|
index: 0,
|
||||||
};
|
};
|
||||||
// do not drop the list
|
// do not drop the list, the iterator has taken 'ownership'
|
||||||
mem::forget(list);
|
mem::forget(list);
|
||||||
iter
|
iter
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue