Auto merge of #115 - 1tgr:master, r=mbrubeck

Add into_inner

Converts a SmallVec into an array, provided the SmallVec has not been spilled to the heap.

Addresses #85.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-smallvec/115)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo
2018-08-13 14:57:43 -04:00
committed by GitHub
+37
View File
@@ -287,6 +287,8 @@ impl<A: Array> SmallVecData<A> {
SmallVecData { inline }
}
#[inline]
unsafe fn into_inline(self) -> A { self.inline }
#[inline]
unsafe fn heap(&self) -> (*mut A::Item, usize) {
self.heap
}
@@ -327,6 +329,13 @@ impl<A: Array> SmallVecData<A> {
SmallVecData::Inline(ManuallyDrop::new(inline))
}
#[inline]
unsafe fn into_inline(self) -> A {
match self {
SmallVecData::Inline(a) => ManuallyDrop::into_inner(a),
_ => debug_unreachable!(),
}
}
#[inline]
unsafe fn heap(&self) -> (*mut A::Item, usize) {
match *self {
SmallVecData::Heap(data) => data,
@@ -812,6 +821,22 @@ impl<A: Array> SmallVec<A> {
}
}
/// Convert the SmallVec into an `A` if possible. Otherwise return `Err(Self)`.
///
/// This method returns `Err(Self)` if the SmallVec is too short (and the `A` contains uninitialized elements),
/// or if the SmallVec is too long (and all the elements were spilled to the heap).
pub fn into_inner(self) -> Result<A, Self> {
if self.spilled() || self.len() != A::size() {
Err(self)
} else {
unsafe {
let data = ptr::read(&self.data);
mem::forget(self);
Ok(data.into_inline())
}
}
}
/// Retains only the elements specified by the predicate.
///
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
@@ -1945,6 +1970,18 @@ mod tests {
assert_eq!(vec.into_vec(), vec![0, 1, 2]);
}
#[test]
fn test_into_inner() {
let vec = SmallVec::<[u8; 2]>::from_iter(0..2);
assert_eq!(vec.into_inner(), Ok([0, 1]));
let vec = SmallVec::<[u8; 2]>::from_iter(0..1);
assert_eq!(vec.clone().into_inner(), Err(vec));
let vec = SmallVec::<[u8; 2]>::from_iter(0..3);
assert_eq!(vec.clone().into_inner(), Err(vec));
}
#[test]
fn test_from_vec() {
let vec = vec![];