Skip to content

Commit 9eacf68

Browse files
authored
Implement spare_capacity_mut (#364)
Mirrors the implementation from `Vec::spare_capacity_mut`. This is useful to write directly into the buffer after `SmallVec::with_capacity`, removing the overhead of the `SmallVec` model entirely when doing so.
1 parent f6ec5b2 commit 9eacf68

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

src/lib.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,22 @@ impl<T, const N: usize> SmallVec<T, N> {
14131413
}
14141414
}
14151415

1416+
/// Returns the remaining spare capacity of the vector as a slice of
1417+
/// `MaybeUninit<T>`.
1418+
///
1419+
/// The returned slice can be used to fill the vector with data (e.g. by
1420+
/// reading from a file) before marking the data as initialized using the
1421+
/// [`set_len`](Self::set_len) method.
1422+
#[inline]
1423+
pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
1424+
unsafe {
1425+
core::slice::from_raw_parts_mut(
1426+
self.as_mut_ptr().add(self.len()) as *mut MaybeUninit<T>,
1427+
self.capacity() - self.len(),
1428+
)
1429+
}
1430+
}
1431+
14161432
/// Creates a `SmallVec` directly from the raw components of another `SmallVec`.
14171433
///
14181434
/// # Safety

src/tests.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -1136,7 +1136,9 @@ fn collect_from_iter() {
11361136

11371137
impl<I: Iterator> Iterator for IterNoHint<I> {
11381138
type Item = I::Item;
1139-
fn next(&mut self) -> Option<Self::Item> { self.0.next() }
1139+
fn next(&mut self) -> Option<Self::Item> {
1140+
self.0.next()
1141+
}
11401142

11411143
// no implementation of size_hint means it returns (0, None) - which forces from_iter to
11421144
// grow the allocated space iteratively.
@@ -1148,3 +1150,30 @@ fn collect_from_iter() {
11481150

11491151
let _y: SmallVec<u8, 1> = SmallVec::from_iter(iter);
11501152
}
1153+
1154+
#[test]
1155+
fn test_spare_capacity_mut() {
1156+
let mut v: SmallVec<u8, 2> = SmallVec::new();
1157+
assert!(!v.spilled());
1158+
let spare = v.spare_capacity_mut();
1159+
assert_eq!(spare.len(), 2);
1160+
assert_eq!(spare.as_ptr().cast::<u8>(), v.as_ptr());
1161+
1162+
v.push(1);
1163+
assert!(!v.spilled());
1164+
let spare = v.spare_capacity_mut();
1165+
assert_eq!(spare.len(), 1);
1166+
assert_eq!(spare.as_ptr().cast::<u8>(), unsafe { v.as_ptr().add(1) });
1167+
1168+
v.push(2);
1169+
assert!(!v.spilled());
1170+
let spare = v.spare_capacity_mut();
1171+
assert_eq!(spare.len(), 0);
1172+
assert_eq!(spare.as_ptr().cast::<u8>(), unsafe { v.as_ptr().add(2) });
1173+
1174+
v.push(3);
1175+
assert!(v.spilled());
1176+
let spare = v.spare_capacity_mut();
1177+
assert!(spare.len() >= 1);
1178+
assert_eq!(spare.as_ptr().cast::<u8>(), unsafe { v.as_ptr().add(3) });
1179+
}

0 commit comments

Comments
 (0)