@@ -3615,12 +3615,15 @@ impl<T, A: Allocator> Vec<T, A> {
3615
3615
Splice { drain : self . drain ( range) , replace_with : replace_with. into_iter ( ) }
3616
3616
}
3617
3617
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.
3619
3619
///
3620
3620
/// If the closure returns true, then the element is removed and yielded.
3621
3621
/// If the closure returns false, the element will remain in the vector and will not be yielded
3622
3622
/// by the iterator.
3623
3623
///
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
+ ///
3624
3627
/// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
3625
3628
/// or the iteration short-circuits, then the remaining elements will be retained.
3626
3629
/// 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> {
3630
3633
/// Using this method is equivalent to the following code:
3631
3634
///
3632
3635
/// ```
3636
+ /// # use std::cmp::min;
3633
3637
/// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };
3634
3638
/// # 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) {
3637
3642
/// if some_predicate(&mut vec[i]) {
3638
3643
/// let val = vec.remove(i);
3639
3644
/// // your code here
@@ -3648,8 +3653,12 @@ impl<T, A: Allocator> Vec<T, A> {
3648
3653
/// But `extract_if` is easier to use. `extract_if` is also more efficient,
3649
3654
/// because it can backshift the elements of the array in bulk.
3650
3655
///
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.
3653
3662
///
3654
3663
/// # Examples
3655
3664
///
@@ -3659,25 +3668,29 @@ impl<T, A: Allocator> Vec<T, A> {
3659
3668
/// #![feature(extract_if)]
3660
3669
/// let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
3661
3670
///
3662
- /// let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
3671
+ /// let evens = numbers.extract_if(.., |x| *x % 2 == 0).collect::<Vec<_>>();
3663
3672
/// let odds = numbers;
3664
3673
///
3665
3674
/// assert_eq!(evens, vec![2, 4, 6, 8, 14]);
3666
3675
/// assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
3667
3676
/// ```
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
+ /// ```
3668
3687
#[ 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 >
3670
3689
where
3671
3690
F : FnMut ( & mut T ) -> bool ,
3691
+ R : RangeBounds < usize > ,
3672
3692
{
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)
3681
3694
}
3682
3695
}
3683
3696
0 commit comments