From 6a8c2fd7baf850d59dc335ffb0c51ef98ab6040f Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Tue, 25 Mar 2025 14:06:06 +0000 Subject: [PATCH] feat(allocator/vec2): align the `retain` method with the standard implementation (#9752) The documentation and the implementation are copied from https://doc.rust-lang.org/src/alloc/vec/mod.rs.html#2095-209. ~~After this change, `drain_filter` is no longer needed, so remove it.~~ --- crates/oxc_allocator/src/vec2/mod.rs | 30 ++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/crates/oxc_allocator/src/vec2/mod.rs b/crates/oxc_allocator/src/vec2/mod.rs index b1b8d83b0bbe3..6dbf2116f2e72 100644 --- a/crates/oxc_allocator/src/vec2/mod.rs +++ b/crates/oxc_allocator/src/vec2/mod.rs @@ -1297,26 +1297,37 @@ impl<'bump, T: 'bump> Vec<'bump, T> { /// Retains only the elements specified by the predicate. /// - /// In other words, remove all elements `e` such that `f(&e)` returns `false`. - /// This method operates in place and preserves the order of the retained - /// elements. + /// In other words, remove all elements `e` for which `f(&e)` returns `false`. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. /// /// # Examples /// + /// ```ignore + /// use bumpalo::Bump; + /// let bump = Bump::new(); + /// let mut vec = Vec::from_iter_in([1, 2, 3, 4], &bump); + /// vec.retain(|&x| x % 2 == 0); + /// assert_eq!(vec, [2, 4]); /// ``` - /// use bumpalo::{Bump, collections::Vec}; /// - /// let b = Bump::new(); + /// Because the elements are visited exactly once in the original order, + /// external state may be used to decide which elements to keep. /// - /// let mut vec = bumpalo::vec![in &b; 1, 2, 3, 4]; - /// vec.retain(|&x| x % 2 == 0); - /// assert_eq!(vec, [2, 4]); + /// ```ignore + /// use bumpalo::Bump; + /// let bump = Bump::new(); + /// let mut vec = Vec::from_iter_in([1, 2, 3, 4, 5], &bump); + /// let keep = [false, true, true, false, true]; + /// let mut iter = keep.iter(); + /// vec.retain(|_| *iter.next().unwrap()); + /// assert_eq!(vec, [2, 3, 5]); /// ``` pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool, { - self.drain_filter(|x| !f(x)); + self.retain_mut(|x| f(x)); } /// Retains only the elements specified by the predicate, passing a mutable reference to it. @@ -2244,7 +2255,6 @@ impl<'bump, T: 'bump> IntoIterator for Vec<'bump, T> { } else { begin.add(self.len()) as *const T }; - // Don't need `mem::forget(self)` here, because `Vec` does not implement `Drop`. IntoIter { phantom: PhantomData, ptr: begin, end } } }