Skip to content

Commit

Permalink
Merge pull request #187 from conradludgate/into-inner-take
Browse files Browse the repository at this point in the history
take and into_inner_unchecked functions
  • Loading branch information
bluss authored May 31, 2021
2 parents dfceb6d + 0fdf39f commit 515a18c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
30 changes: 25 additions & 5 deletions src/arrayvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -636,14 +636,34 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
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)
Expand Down
24 changes: 24 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
{
Expand Down Expand Up @@ -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::<i32, 4>::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() {
Expand Down

0 comments on commit 515a18c

Please sign in to comment.