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:
commit
becc24a23a
@ -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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user