Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

take and into_inner_unchecked functions #187

Merged
merged 4 commits into from May 31, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 24 additions & 5 deletions src/arrayvec.rs
Expand Up @@ -636,14 +636,33 @@ 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] {
let self_ = ManuallyDrop::new(self);
conradludgate marked this conversation as resolved.
Show resolved Hide resolved
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
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