@@ -786,14 +786,39 @@ impl<T> ThinVec<T> {
786786 pub fn retain < F > ( & mut self , mut f : F )
787787 where
788788 F : FnMut ( & T ) -> bool ,
789+ {
790+ self . retain_mut ( |x| f ( & * x) ) ;
791+ }
792+
793+ /// Retains only the elements specified by the predicate, passing a mutable reference to it.
794+ ///
795+ /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
796+ /// This method operates in place and preserves the order of the retained
797+ /// elements.
798+ ///
799+ /// # Examples
800+ ///
801+ // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
802+ #[ cfg_attr( not( feature = "gecko-ffi" ) , doc = "```" ) ]
803+ #[ cfg_attr( feature = "gecko-ffi" , doc = "```ignore" ) ]
804+ /// # #[macro_use] extern crate thin_vec;
805+ /// # fn main() {
806+ /// let mut vec = thin_vec![1, 2, 3, 4];
807+ /// vec.retain(|&x| x%2 == 0);
808+ /// assert_eq!(vec, [2, 4]);
809+ /// # }
810+ /// ```
811+ pub fn retain_mut < F > ( & mut self , mut f : F )
812+ where
813+ F : FnMut ( & mut T ) -> bool ,
789814 {
790815 let len = self . len ( ) ;
791816 let mut del = 0 ;
792817 {
793818 let v = & mut self [ ..] ;
794819
795820 for i in 0 ..len {
796- if !f ( & v[ i] ) {
821+ if !f ( & mut v[ i] ) {
797822 del += 1 ;
798823 } else if del > 0 {
799824 v. swap ( i - del, i) ;
@@ -1824,6 +1849,15 @@ mod tests {
18241849 assert_eq ! ( & v[ ..] , & [ ] ) ;
18251850 }
18261851
1852+ {
1853+ let mut v = ThinVec :: < i32 > :: new ( ) ;
1854+ v. retain_mut ( |_| unreachable ! ( ) ) ;
1855+
1856+ assert_eq ! ( v. len( ) , 0 ) ;
1857+ assert_eq ! ( v. capacity( ) , 0 ) ;
1858+ assert_eq ! ( & v[ ..] , & [ ] ) ;
1859+ }
1860+
18271861 {
18281862 let mut v = ThinVec :: < i32 > :: new ( ) ;
18291863 v. dedup_by_key ( |x| * x) ;
@@ -2101,6 +2135,18 @@ mod std_tests {
21012135 assert_eq ! ( vec, [ 2 , 4 ] ) ;
21022136 }
21032137
2138+ #[ test]
2139+ fn test_retain_mut ( ) {
2140+ let mut vec = thin_vec ! [ 9 , 9 , 9 , 9 ] ;
2141+ let mut i = 0 ;
2142+ vec. retain_mut ( |x| {
2143+ i += 1 ;
2144+ * x = i;
2145+ i != 4
2146+ } ) ;
2147+ assert_eq ! ( vec, [ 1 , 2 , 3 ] ) ;
2148+ }
2149+
21042150 #[ test]
21052151 fn test_dedup ( ) {
21062152 fn case ( a : ThinVec < i32 > , b : ThinVec < i32 > ) {
0 commit comments