Auto merge of #97870 - eggyal:inplace_fold_spec, r=wesleywiser

Use liballoc's specialised in-place vec collection

liballoc already specialises in-place vector collection, so manually
reimplementing it in `IdFunctor::try_map_id` was superfluous.
This commit is contained in:
bors 2022-11-19 02:28:47 +00:00
commit becc24a23a

View File

@ -34,43 +34,11 @@ impl<T> IdFunctor for Vec<T> {
type Inner = T; type Inner = T;
#[inline] #[inline]
fn try_map_id<F, E>(self, mut f: F) -> Result<Self, E> fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
where where
F: FnMut(Self::Inner) -> Result<Self::Inner, E>, F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
{ {
struct HoleVec<T> { self.into_iter().map(f).collect()
vec: Vec<mem::ManuallyDrop<T>>,
hole: Option<usize>,
}
impl<T> Drop for HoleVec<T> {
fn drop(&mut self) {
unsafe {
for (index, slot) in self.vec.iter_mut().enumerate() {
if self.hole != Some(index) {
mem::ManuallyDrop::drop(slot);
}
}
}
}
}
unsafe {
let (ptr, length, capacity) = self.into_raw_parts();
let vec = Vec::from_raw_parts(ptr.cast(), length, capacity);
let mut hole_vec = HoleVec { vec, hole: None };
for (index, slot) in hole_vec.vec.iter_mut().enumerate() {
hole_vec.hole = Some(index);
let original = mem::ManuallyDrop::take(slot);
let mapped = f(original)?;
*slot = mem::ManuallyDrop::new(mapped);
hole_vec.hole = None;
}
mem::forget(hole_vec);
Ok(Vec::from_raw_parts(ptr, length, capacity))
}
} }
} }