diff --git a/Cargo.toml b/Cargo.toml index d48b17b..7a066d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "orx-split-vec" -version = "3.22.0" +version = "3.23.0" edition = "2024" authors = ["orxfun "] description = "An efficient dynamic capacity vector with pinned element guarantees." @@ -12,7 +12,7 @@ categories = ["data-structures", "rust-patterns", "no-std"] [dependencies] orx-iterable = { version = "1.3.0", default-features = false } orx-pseudo-default = { version = "2.1.0", default-features = false } -orx-pinned-vec = { version = "3.21.0", default-features = false } +orx-pinned-vec = { version = "3.23.0", default-features = false } orx-concurrent-iter = { version = "3.3.0", default-features = false } [[bench]] diff --git a/src/pinned_vec.rs b/src/pinned_vec.rs index bad277b..696a7a2 100644 --- a/src/pinned_vec.rs +++ b/src/pinned_vec.rs @@ -317,13 +317,50 @@ impl PinnedVec for SplitVec { let last = &mut self.fragments[f]; let available = last.room(); - if available < slice.len() { - last.extend_from_slice(&slice[0..available]); - slice = &slice[available..]; + match available < slice.len() { + true => { + last.extend_from_slice(&slice[0..available]); + slice = &slice[available..]; + self.add_fragment(); + } + false => { + last.extend_from_slice(slice); + break; + } + } + } + } + + unsafe fn extend_from_nonoverlapping(&mut self, mut src: *const T, count: usize) { + self.len += count; + let mut left = count; + while left > 0 { + if !self.has_capacity_for_one() { self.add_fragment(); - } else { - last.extend_from_slice(slice); - break; + } + let f = self.fragments.len() - 1; + + let last = &mut self.fragments[f]; + let last_len = last.len(); + let last_available = last.room(); + + let dst = unsafe { last.as_mut_ptr().add(last.len()) }; + match last_available < left { + true => { + unsafe { dst.copy_from_nonoverlapping(src, last_available) }; + unsafe { last.set_len(last_len + last_available) }; + debug_assert_eq!(last.len(), last.capacity()); + + src = unsafe { src.add(last_available) }; + left -= last_available; + + self.add_fragment(); + } + false => { + unsafe { dst.copy_from_nonoverlapping(src, left) }; + unsafe { last.set_len(last_len + left) }; + break; + } } } }