Skip to content

Commit 4c8149a

Browse files
authored
Merge pull request bluss#200 from niklasf/follow-vec-retain
Follow optimization of std::Vec::retain (rust-lang/rust#88060)
2 parents e209a50 + bc21f19 commit 4c8149a

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

src/arrayvec.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -493,21 +493,38 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
493493

494494
let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len };
495495

496-
while g.processed_len < original_len {
496+
#[inline(always)]
497+
fn process_one<F: FnMut(&mut T) -> bool, T, const CAP: usize, const DELETED: bool>(
498+
f: &mut F,
499+
g: &mut BackshiftOnDrop<'_, T, CAP>
500+
) -> bool {
497501
let cur = unsafe { g.v.as_mut_ptr().add(g.processed_len) };
498502
if !f(unsafe { &mut *cur }) {
499503
g.processed_len += 1;
500504
g.deleted_cnt += 1;
501505
unsafe { ptr::drop_in_place(cur) };
502-
continue;
506+
return false;
503507
}
504-
if g.deleted_cnt > 0 {
508+
if DELETED {
505509
unsafe {
506510
let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt);
507511
ptr::copy_nonoverlapping(cur, hole_slot, 1);
508512
}
509513
}
510514
g.processed_len += 1;
515+
true
516+
}
517+
518+
// Stage 1: Nothing was deleted.
519+
while g.processed_len != original_len {
520+
if !process_one::<F, T, CAP, false>(&mut f, &mut g) {
521+
break;
522+
}
523+
}
524+
525+
// Stage 2: Some elements were deleted.
526+
while g.processed_len != original_len {
527+
process_one::<F, T, CAP, true>(&mut f, &mut g);
511528
}
512529

513530
drop(g);

0 commit comments

Comments
 (0)