From 3437a5dc2684e2a68f862fb79fc356232ea658f6 Mon Sep 17 00:00:00 2001 From: Ole Magnus Fon Johnsen Date: Tue, 30 Sep 2025 12:50:45 +0200 Subject: [PATCH 1/2] feat: add `SoAVec::swap_remove` --- soavec/src/lib.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/soavec/src/lib.rs b/soavec/src/lib.rs index 22de277..108948b 100644 --- a/soavec/src/lib.rs +++ b/soavec/src/lib.rs @@ -1002,6 +1002,50 @@ impl SoAVec { unsafe { T::TupleRepr::drop_in_place(T::TupleRepr::get_pointers(ptr, 0, cap), len) }; } } + + /// Removes an element from the vector and returns it. + /// + /// The removed element is replaced by the last element of the vector. + /// + /// This does not preserve ordering of the remaining elements, but is *O*(n_fields). + /// If you need to preserve the element order, use [`remove`] instead. + /// + /// [`remove`]: SoAVec::remove + /// + /// # Examples + /// + /// ``` + /// use soavec::soavec; + /// + /// let mut v = soavec![("foo", "foo"), ("bar", "bar"), ("baz", "baz"), ("qux", "qux")].unwrap(); + /// + /// assert_eq!(v.swap_remove(1).unwrap(), ("bar", "bar")); + /// assert_eq!(v, soavec![("foo", "foo"), ("qux", "qux"), ("baz", "baz")].unwrap()); + /// + /// assert_eq!(v.swap_remove(0).unwrap(), ("foo", "foo")); + /// assert_eq!(v, soavec![("baz", "baz"), ("qux", "qux")].unwrap()); + /// ``` + pub fn swap_remove(&mut self, index: u32) -> Result { + let len = self.len(); + if index >= len { + return Err(IndexOutOfBoundsError); + } + + let ptr = self.buf.as_mut_ptr(); + let cap = self.capacity(); + + unsafe { + let value = T::from_tuple(T::TupleRepr::read(ptr, index, cap)); + + let src = T::TupleRepr::get_pointers(ptr, len - 1, cap); + let dst = T::TupleRepr::get_pointers(ptr, index, cap); + T::TupleRepr::copy(src, dst, 1); + + self.buf.set_len(len - 1); + + Ok(value) + } + } } impl Drop for SoAVec { From 55597658422d44654711c157e11f1e13a06690a1 Mon Sep 17 00:00:00 2001 From: Ole Magnus Fon Johnsen Date: Wed, 8 Oct 2025 12:12:07 +0200 Subject: [PATCH 2/2] refactor: remove cold functions --- soavec/src/lib.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/soavec/src/lib.rs b/soavec/src/lib.rs index 108948b..83b38fd 100644 --- a/soavec/src/lib.rs +++ b/soavec/src/lib.rs @@ -855,14 +855,9 @@ impl SoAVec { /// assert_eq!(v.len(), 2); /// ``` pub fn remove(&mut self, index: u32) -> Result { - #[cold] - fn assert_index() -> IndexOutOfBoundsError { - IndexOutOfBoundsError - } - let len = self.len(); if index >= len { - return Err(assert_index().into()); + return Err(IndexOutOfBoundsError.into()); } let cap = self.buf.capacity(); @@ -920,14 +915,9 @@ impl SoAVec { /// assert_eq!(vec.get(3), Some((&7, &6))); /// ``` pub fn insert_mut(&mut self, index: u32, element: T) -> Result, InsertError> { - #[cold] - fn assert_index() -> IndexOutOfBoundsError { - IndexOutOfBoundsError - } - let len = self.len(); if index > len { - return Err(assert_index().into()); + return Err(IndexOutOfBoundsError.into()); } if len == self.capacity() {