Skip to content

Commit 17b68fe

Browse files
author
bors-servo
authored
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 -->
2 parents d3898ca + 852b817 commit 17b68fe

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

lib.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ impl<A: Array> SmallVecData<A> {
287287
SmallVecData { inline }
288288
}
289289
#[inline]
290+
unsafe fn into_inline(self) -> A { self.inline }
291+
#[inline]
290292
unsafe fn heap(&self) -> (*mut A::Item, usize) {
291293
self.heap
292294
}
@@ -327,6 +329,13 @@ impl<A: Array> SmallVecData<A> {
327329
SmallVecData::Inline(ManuallyDrop::new(inline))
328330
}
329331
#[inline]
332+
unsafe fn into_inline(self) -> A {
333+
match self {
334+
SmallVecData::Inline(a) => ManuallyDrop::into_inner(a),
335+
_ => debug_unreachable!(),
336+
}
337+
}
338+
#[inline]
330339
unsafe fn heap(&self) -> (*mut A::Item, usize) {
331340
match *self {
332341
SmallVecData::Heap(data) => data,
@@ -812,6 +821,22 @@ impl<A: Array> SmallVec<A> {
812821
}
813822
}
814823

824+
/// Convert the SmallVec into an `A` if possible. Otherwise return `Err(Self)`.
825+
///
826+
/// This method returns `Err(Self)` if the SmallVec is too short (and the `A` contains uninitialized elements),
827+
/// or if the SmallVec is too long (and all the elements were spilled to the heap).
828+
pub fn into_inner(self) -> Result<A, Self> {
829+
if self.spilled() || self.len() != A::size() {
830+
Err(self)
831+
} else {
832+
unsafe {
833+
let data = ptr::read(&self.data);
834+
mem::forget(self);
835+
Ok(data.into_inline())
836+
}
837+
}
838+
}
839+
815840
/// Retains only the elements specified by the predicate.
816841
///
817842
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
@@ -1945,6 +1970,18 @@ mod tests {
19451970
assert_eq!(vec.into_vec(), vec![0, 1, 2]);
19461971
}
19471972

1973+
#[test]
1974+
fn test_into_inner() {
1975+
let vec = SmallVec::<[u8; 2]>::from_iter(0..2);
1976+
assert_eq!(vec.into_inner(), Ok([0, 1]));
1977+
1978+
let vec = SmallVec::<[u8; 2]>::from_iter(0..1);
1979+
assert_eq!(vec.clone().into_inner(), Err(vec));
1980+
1981+
let vec = SmallVec::<[u8; 2]>::from_iter(0..3);
1982+
assert_eq!(vec.clone().into_inner(), Err(vec));
1983+
}
1984+
19481985
#[test]
19491986
fn test_from_vec() {
19501987
let vec = vec![];

0 commit comments

Comments
 (0)