Skip to content

Commit d16285a

Browse files
committed
Add into_inner
Converts a SmallVec into an array, provided the SmallVec has not been spilled to the heap.
1 parent d3898ca commit d16285a

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

lib.rs

Lines changed: 31 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,19 @@ impl<A: Array> SmallVec<A> {
812821
}
813822
}
814823

824+
/// If the SmallVec has not spilled onto the heap, convert it into an `A`. Otherwise return `Err(Self)`.
825+
pub fn into_inner(mut self) -> Result<A, Self> {
826+
if self.spilled() {
827+
Err(self)
828+
} else {
829+
unsafe {
830+
let data = mem::replace(&mut self.data, SmallVecData::from_inline(mem::uninitialized()));
831+
mem::forget(self);
832+
Ok(data.into_inline())
833+
}
834+
}
835+
}
836+
815837
/// Retains only the elements specified by the predicate.
816838
///
817839
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
@@ -1945,6 +1967,15 @@ mod tests {
19451967
assert_eq!(vec.into_vec(), vec![0, 1, 2]);
19461968
}
19471969

1970+
#[test]
1971+
fn test_into_inner() {
1972+
let vec = SmallVec::<[u8; 2]>::from_iter(0..2);
1973+
assert_eq!(vec.into_inner(), Ok([0, 1]));
1974+
1975+
let vec = SmallVec::<[u8; 2]>::from_iter(0..3);
1976+
assert_eq!(vec.clone().into_inner(), Err(vec));
1977+
}
1978+
19481979
#[test]
19491980
fn test_from_vec() {
19501981
let vec = vec![];

0 commit comments

Comments
 (0)