@@ -605,6 +605,24 @@ impl<A: Array> SmallVec<A> {
605605 }
606606 }
607607 }
608+
609+ /// Retains only the elements specified by the predicate.
610+ ///
611+ /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
612+ /// This method operates in place and preserves the order of the retained
613+ /// elements.
614+ pub fn retain < F : FnMut ( & A :: Item ) -> bool > ( & mut self , mut f : F ) {
615+ let mut del = 0 ;
616+ let len = self . len ;
617+ for i in 0 ..len {
618+ if !f ( & self [ i] ) {
619+ del += 1 ;
620+ } else if del > 0 {
621+ self . swap ( i - del, i) ;
622+ }
623+ }
624+ self . truncate ( len - del) ;
625+ }
608626}
609627
610628impl < A : Array > SmallVec < A > where A :: Item : Copy {
@@ -1059,6 +1077,10 @@ pub mod tests {
10591077 use std:: borrow:: ToOwned ;
10601078 #[ cfg( not( feature = "std" ) ) ]
10611079 use alloc:: borrow:: ToOwned ;
1080+ #[ cfg( feature = "std" ) ]
1081+ use std:: rc:: Rc ;
1082+ #[ cfg( not( feature = "std" ) ) ]
1083+ use alloc:: rc:: Rc ;
10621084 #[ cfg( not( feature = "std" ) ) ]
10631085 use alloc:: boxed:: Box ;
10641086 #[ cfg( not( feature = "std" ) ) ]
@@ -1589,6 +1611,41 @@ pub mod tests {
15891611 drop ( small_vec) ;
15901612 }
15911613
1614+ #[ test]
1615+ fn test_retain ( ) {
1616+ // Test inline data storate
1617+ let mut sv: SmallVec < [ i32 ; 5 ] > = SmallVec :: from_slice ( & [ 1 , 2 , 3 , 3 , 4 ] ) ;
1618+ sv. retain ( |& i| i != 3 ) ;
1619+ assert_eq ! ( sv. pop( ) , Some ( 4 ) ) ;
1620+ assert_eq ! ( sv. pop( ) , Some ( 2 ) ) ;
1621+ assert_eq ! ( sv. pop( ) , Some ( 1 ) ) ;
1622+ assert_eq ! ( sv. pop( ) , None ) ;
1623+
1624+ // Test spilled data storage
1625+ let mut sv: SmallVec < [ i32 ; 3 ] > = SmallVec :: from_slice ( & [ 1 , 2 , 3 , 3 , 4 ] ) ;
1626+ sv. retain ( |& i| i != 3 ) ;
1627+ assert_eq ! ( sv. pop( ) , Some ( 4 ) ) ;
1628+ assert_eq ! ( sv. pop( ) , Some ( 2 ) ) ;
1629+ assert_eq ! ( sv. pop( ) , Some ( 1 ) ) ;
1630+ assert_eq ! ( sv. pop( ) , None ) ;
1631+
1632+ // Test that drop implementations are called for inline.
1633+ let one = Rc :: new ( 1 ) ;
1634+ let mut sv: SmallVec < [ Rc < i32 > ; 3 ] > = SmallVec :: new ( ) ;
1635+ sv. push ( Rc :: clone ( & one) ) ;
1636+ assert_eq ! ( Rc :: strong_count( & one) , 2 ) ;
1637+ sv. retain ( |_| false ) ;
1638+ assert_eq ! ( Rc :: strong_count( & one) , 1 ) ;
1639+
1640+ // Test that drop implementations are called for spilled data.
1641+ let mut sv: SmallVec < [ Rc < i32 > ; 1 ] > = SmallVec :: new ( ) ;
1642+ sv. push ( Rc :: clone ( & one) ) ;
1643+ sv. push ( Rc :: new ( 2 ) ) ;
1644+ assert_eq ! ( Rc :: strong_count( & one) , 2 ) ;
1645+ sv. retain ( |_| false ) ;
1646+ assert_eq ! ( Rc :: strong_count( & one) , 1 ) ;
1647+ }
1648+
15921649 #[ cfg( feature = "std" ) ]
15931650 #[ test]
15941651 fn test_write ( ) {
0 commit comments