diff --git a/src/arrayvec.rs b/src/arrayvec.rs index 9a8a918..6b4faf8 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -636,14 +636,34 @@ impl ArrayVec { if self.len() < self.capacity() { Err(self) } else { - unsafe { - let self_ = ManuallyDrop::new(self); - let array = ptr::read(self_.as_ptr() as *const [T; CAP]); - Ok(array) - } + unsafe { Ok(self.into_inner_unchecked()) } } } + /// Return the inner fixed size array. + /// + /// Safety: + /// This operation is safe if and only if length equals capacity. + pub unsafe fn into_inner_unchecked(self) -> [T; CAP] { + debug_assert_eq!(self.len(), self.capacity()); + let self_ = ManuallyDrop::new(self); + let array = ptr::read(self_.as_ptr() as *const [T; CAP]); + array + } + + /// Returns the ArrayVec, replacing the original with a new empty ArrayVec. + /// + /// ``` + /// use arrayvec::ArrayVec; + /// + /// let mut v = ArrayVec::from([0, 1, 2, 3]); + /// assert_eq!([0, 1, 2, 3], v.take().into_inner().unwrap()); + /// assert!(v.is_empty()); + /// ``` + pub fn take(&mut self) -> Self { + mem::replace(self, Self::new()) + } + /// Return a slice containing all elements of the vector. pub fn as_slice(&self) -> &[T] { ArrayVecImpl::as_slice(self) diff --git a/tests/tests.rs b/tests/tests.rs index ca42c74..26d09ae 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -153,6 +153,21 @@ fn test_drop() { assert_eq!(flag.get(), 3); } + // test take + flag.set(0); + { + let mut array1 = ArrayVec::<_, 3>::new(); + array1.push(Bump(flag)); + array1.push(Bump(flag)); + array1.push(Bump(flag)); + let array2 = array1.take(); + assert_eq!(flag.get(), 0); + drop(array1); + assert_eq!(flag.get(), 0); + drop(array2); + assert_eq!(flag.get(), 3); + } + // test cloning into_iter flag.set(0); { @@ -461,6 +476,15 @@ fn test_into_inner_3() { assert_eq!(v.into_inner().unwrap(), [1, 2, 3, 4]); } +#[test] +fn test_take() { + let mut v1 = ArrayVec::::new(); + v1.extend(1..=4); + let v2 = v1.take(); + assert!(v1.into_inner().is_err()); + assert_eq!(v2.into_inner().unwrap(), [1, 2, 3, 4]); +} + #[cfg(feature="std")] #[test] fn test_write() {