Skip to content

Commit

Permalink
add: extend_from_slice()
Browse files Browse the repository at this point in the history
  • Loading branch information
cehteh committed Sep 23, 2024
1 parent decaeed commit 4f9352c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,13 @@ impl<H, T> HeaderVec<H, T> {
unsafe { (self.ptr as *mut T).add(Self::offset()) }
}

/// Gets the pointer to the end of the slice. This returns a mutable pointer to
/// uninitialized memory behind the last element.
#[inline(always)]
fn end_ptr_mut(&mut self) -> *mut T {
unsafe { self.start_ptr_mut().add(self.len_exact())}
}

#[inline(always)]
fn header(&self) -> &HeaderVecHeader<H> {
// The beginning of the memory is always the header.
Expand All @@ -427,6 +434,28 @@ impl<H, T> HeaderVec<H, T> {
}
}

impl<H, T: Clone> HeaderVec<H, T> {
/// Adds items from a slice to the end of the list.
///
/// Returns `Some(*const ())` if the memory was moved to a new location.
/// In this case, you are responsible for updating the weak nodes.
pub fn extend_from_slice(&mut self, slice: &[T]) -> Option<*const ()> {
let previous_pointer = self.reserve(slice.len());

// copy data
let end_ptr = self.end_ptr_mut();
for (index, item) in slice.iter().enumerate() {
unsafe {
core::ptr::write(end_ptr.add(index), item.clone());
}
}
// correct the len
self.header_mut().len = (self.len_exact() + slice.len()).into();

previous_pointer
}
}

#[cfg(feature = "atomic_append")]
/// The atomic append API is only enabled when the `atomic_append` feature flag is set (which
/// is the default).
Expand Down
9 changes: 9 additions & 0 deletions tests/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,12 @@ fn test_push() {
hv.push(123);
assert_eq!(hv[0], 123);
}

#[test]
fn test_extend_from_slice() {
let mut hv = HeaderVec::new(());

hv.extend_from_slice(&[0, 1, 2]);
hv.extend_from_slice(&[3, 4, 5]);
assert_eq!(hv.as_slice(), &[0, 1, 2, 3, 4, 5]);
}

0 comments on commit 4f9352c

Please sign in to comment.