@@ -3615,12 +3615,15 @@ impl<T, A: Allocator> Vec<T, A> {
36153615 Splice { drain : self . drain ( range) , replace_with : replace_with. into_iter ( ) }
36163616 }
36173617
3618- /// Creates an iterator which uses a closure to determine if an element should be removed.
3618+ /// Creates an iterator which uses a closure to determine if element in the range should be removed.
36193619 ///
36203620 /// If the closure returns true, then the element is removed and yielded.
36213621 /// If the closure returns false, the element will remain in the vector and will not be yielded
36223622 /// by the iterator.
36233623 ///
3624+ /// Only elements that fall in the provided range are considered for extraction, but any elements
3625+ /// after the range will still have to be moved if any element has been extracted.
3626+ ///
36243627 /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
36253628 /// or the iteration short-circuits, then the remaining elements will be retained.
36263629 /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
@@ -3630,10 +3633,12 @@ impl<T, A: Allocator> Vec<T, A> {
36303633 /// Using this method is equivalent to the following code:
36313634 ///
36323635 /// ```
3636+ /// # use std::cmp::min;
36333637 /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };
36343638 /// # let mut vec = vec![1, 2, 3, 4, 5, 6];
3635- /// let mut i = 0;
3636- /// while i < vec.len() {
3639+ /// # let range = 1..4;
3640+ /// let mut i = range.start;
3641+ /// while i < min(vec.len(), range.end) {
36373642 /// if some_predicate(&mut vec[i]) {
36383643 /// let val = vec.remove(i);
36393644 /// // your code here
@@ -3648,8 +3653,12 @@ impl<T, A: Allocator> Vec<T, A> {
36483653 /// But `extract_if` is easier to use. `extract_if` is also more efficient,
36493654 /// because it can backshift the elements of the array in bulk.
36503655 ///
3651- /// Note that `extract_if` also lets you mutate every element in the filter closure,
3652- /// regardless of whether you choose to keep or remove it.
3656+ /// Note that `extract_if` also lets you mutate the elements passed to the filter closure,
3657+ /// regardless of whether you choose to keep or remove them.
3658+ ///
3659+ /// # Panics
3660+ ///
3661+ /// If `range` is out of bounds.
36533662 ///
36543663 /// # Examples
36553664 ///
@@ -3659,25 +3668,29 @@ impl<T, A: Allocator> Vec<T, A> {
36593668 /// #![feature(extract_if)]
36603669 /// let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
36613670 ///
3662- /// let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
3671+ /// let evens = numbers.extract_if(.., |x| *x % 2 == 0).collect::<Vec<_>>();
36633672 /// let odds = numbers;
36643673 ///
36653674 /// assert_eq!(evens, vec![2, 4, 6, 8, 14]);
36663675 /// assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
36673676 /// ```
3677+ ///
3678+ /// Using the range argument to only process a part of the vector:
3679+ ///
3680+ /// ```
3681+ /// #![feature(extract_if)]
3682+ /// let mut items = vec![0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2];
3683+ /// let ones = items.extract_if(7.., |x| *x == 1).collect::<Vec<_>>();
3684+ /// assert_eq!(items, vec![0, 0, 0, 0, 0, 0, 0, 2, 2, 2]);
3685+ /// assert_eq!(ones.len(), 3);
3686+ /// ```
36683687 #[ unstable( feature = "extract_if" , reason = "recently added" , issue = "43244" ) ]
3669- pub fn extract_if < F > ( & mut self , filter : F ) -> ExtractIf < ' _ , T , F , A >
3688+ pub fn extract_if < F , R > ( & mut self , range : R , filter : F ) -> ExtractIf < ' _ , T , F , A >
36703689 where
36713690 F : FnMut ( & mut T ) -> bool ,
3691+ R : RangeBounds < usize > ,
36723692 {
3673- let old_len = self . len ( ) ;
3674-
3675- // Guard against us getting leaked (leak amplification)
3676- unsafe {
3677- self . set_len ( 0 ) ;
3678- }
3679-
3680- ExtractIf { vec : self , idx : 0 , del : 0 , old_len, pred : filter }
3693+ ExtractIf :: new ( self , filter, range)
36813694 }
36823695}
36833696
0 commit comments