@@ -605,6 +605,24 @@ impl<A: Array> SmallVec<A> {
605
605
}
606
606
}
607
607
}
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
+ }
608
626
}
609
627
610
628
impl < A : Array > SmallVec < A > where A :: Item : Copy {
@@ -1059,6 +1077,10 @@ pub mod tests {
1059
1077
use std:: borrow:: ToOwned ;
1060
1078
#[ cfg( not( feature = "std" ) ) ]
1061
1079
use alloc:: borrow:: ToOwned ;
1080
+ #[ cfg( feature = "std" ) ]
1081
+ use std:: rc:: Rc ;
1082
+ #[ cfg( not( feature = "std" ) ) ]
1083
+ use alloc:: rc:: Rc ;
1062
1084
#[ cfg( not( feature = "std" ) ) ]
1063
1085
use alloc:: boxed:: Box ;
1064
1086
#[ cfg( not( feature = "std" ) ) ]
@@ -1589,6 +1611,41 @@ pub mod tests {
1589
1611
drop ( small_vec) ;
1590
1612
}
1591
1613
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
+
1592
1649
#[ cfg( feature = "std" ) ]
1593
1650
#[ test]
1594
1651
fn test_write ( ) {
0 commit comments