diff --git a/src/lib.rs b/src/lib.rs index e6bc8c7..8f92164 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1223,6 +1223,12 @@ impl SmallVec { #[inline] pub fn push(&mut self, value: T) { + _ = self.push_mut(value); + } + + #[inline] + #[must_use] + pub fn push_mut(&mut self, value: T) -> &mut T { let len = self.len(); if len == self.capacity() { self.reserve(1); @@ -1233,6 +1239,7 @@ impl SmallVec { // writes. unsafe { ptr.write(value) }; unsafe { self.set_len(len + 1) } + unsafe { &mut *ptr } } #[inline] @@ -1497,20 +1504,29 @@ impl SmallVec { #[inline] pub fn insert(&mut self, index: usize, value: T) { + _ = self.insert_mut(index, value); + } + + #[inline] + #[must_use] + pub fn insert_mut(&mut self, index: usize, value: T) -> &mut T { let len = self.len(); assert!(index <= len, "insertion index (is {index}) should be <= len (is {len})"); self.reserve(1); - let ptr = self.as_mut_ptr(); + let mut ptr = self.as_mut_ptr(); unsafe { // the elements at `index + 1..len + 1` are now initialized if index < len { copy(ptr.add(index), ptr.add(index + 1), len - index); } // the element at `index` is now initialized - ptr.add(index).write(value); + ptr = ptr.add(index); + ptr.write(value); // SAFETY: all the elements are initialized self.set_len(len + 1); + + &mut *ptr } } diff --git a/src/tests.rs b/src/tests.rs index 2082f96..d8098f0 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -19,6 +19,38 @@ pub fn test_zero() { // We heap allocate all these strings so that double frees will show up under valgrind. +#[test] +pub fn test_push_mut() { + let mut v = SmallVec::<_, 16>::new(); + + let first_elem = v.push_mut("hello".to_owned()); + assert_eq!(&*first_elem, &"hello".to_owned()); + + *first_elem = "hi".to_owned(); + assert_eq!(&*first_elem, &"hi".to_owned()); + + v.push("there".to_owned()); + assert_eq!(&*v, &["hi".to_owned(), "there".to_owned(),][..]); +} + +#[test] +pub fn test_insert_mut() { + let mut v = SmallVec::<_, 16>::new(); + v.push("hello".to_owned()); + v.push("there".to_owned()); + + let second_elem = v.insert_mut(1, ",".to_owned()); + assert_eq!(&*second_elem, &",".to_owned()); + + *second_elem = ";".to_owned(); + assert_eq!(&*second_elem, &";".to_owned()); + + assert_eq!( + &*v, + &["hello".to_owned(), ";".to_owned(), "there".to_owned(),][..] + ); +} + #[test] pub fn test_inline() { let mut v = SmallVec::<_, 16>::new(); @@ -587,10 +619,7 @@ fn test_from() { #[test] fn test_from_slice() { assert_eq!(&SmallVec::::from(&[1][..])[..], [1]); - assert_eq!( - &SmallVec::::from(&[1, 2, 3][..])[..], - [1, 2, 3] - ); + assert_eq!(&SmallVec::::from(&[1, 2, 3][..])[..], [1, 2, 3]); } #[test]