@@ -226,7 +226,7 @@ impl<Sz> ShortHashProxy<Sz>
226
226
/// for ch in "a short treatise on fungi".chars() {
227
227
/// *letters.entry(ch).or_insert(0) += 1;
228
228
/// }
229
- ///
229
+ ///
230
230
/// assert_eq!(letters[&'s'], 2);
231
231
/// assert_eq!(letters[&'t'], 3);
232
232
/// assert_eq!(letters[&'u'], 1);
@@ -930,22 +930,15 @@ impl<K, V, S> OrderMap<K, V, S>
930
930
/// The order the elements are visited is not specified.
931
931
///
932
932
/// Computes in **O(n)** time (average).
933
- pub fn retain < F > ( & mut self , mut keep : F )
934
- where F : FnMut ( & mut K , & mut V ) -> bool ,
933
+ pub fn retain < F > ( & mut self , keep : F ) -> Retain < K , V , S , F >
934
+ where F : FnMut ( & mut K , & mut V ) -> bool
935
935
{
936
936
// We can use either forward or reverse scan, but forward was
937
937
// faster in a microbenchmark
938
- let mut i = 0 ;
939
- while i < self . len ( ) {
940
- {
941
- let entry = & mut self . entries [ i] ;
942
- if keep ( & mut entry. key , & mut entry. value ) {
943
- i += 1 ;
944
- continue ;
945
- }
946
- }
947
- self . swap_remove_index ( i) ;
948
- // skip increment on remove
938
+ Retain {
939
+ i : 0 ,
940
+ map : self ,
941
+ keep : keep,
949
942
}
950
943
}
951
944
}
@@ -975,11 +968,9 @@ impl<K, V, S> OrderMap<K, V, S> {
975
968
///
976
969
/// Computes in **O(1)** time (average).
977
970
pub fn swap_remove_index ( & mut self , index : usize ) -> Option < ( K , V ) > {
978
- let ( probe, found) = match self . entries . get ( index)
979
- . map ( |e| self . find_existing_entry ( e) )
980
- {
971
+ let ( probe, found) = match self . entries . get ( index) {
981
972
None => return None ,
982
- Some ( t ) => t ,
973
+ Some ( e ) => self . find_existing_entry ( e ) ,
983
974
} ;
984
975
Some ( self . remove_found ( probe, found) )
985
976
}
@@ -993,11 +984,9 @@ impl<K, V, S> OrderMap<K, V, S> {
993
984
// However, we should probably not let this show in the public API or docs.
994
985
impl < K , V , S > OrderMap < K , V , S > {
995
986
fn pop_impl ( & mut self ) -> Option < ( K , V ) > {
996
- let ( probe, found) = match self . entries . last ( )
997
- . map ( |e| self . find_existing_entry ( e) )
998
- {
987
+ let ( probe, found) = match self . entries . last ( ) {
999
988
None => return None ,
1000
- Some ( t ) => t ,
989
+ Some ( e ) => self . find_existing_entry ( e ) ,
1001
990
} ;
1002
991
debug_assert_eq ! ( found, self . entries. len( ) - 1 ) ;
1003
992
Some ( self . remove_found ( probe, found) )
@@ -1166,6 +1155,47 @@ impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
1166
1155
}
1167
1156
}
1168
1157
1158
+ pub struct Retain < ' a , K : ' a , V : ' a , S : ' a , F : FnMut ( & mut K , & mut V ) -> bool > {
1159
+ map : & ' a mut OrderMap < K , V , S > ,
1160
+ keep : F ,
1161
+ i : usize ,
1162
+ }
1163
+
1164
+ impl < ' a , K , V , S , F > Drop for Retain < ' a , K , V , S , F >
1165
+ where F : FnMut ( & mut K , & mut V ) -> bool
1166
+ {
1167
+ fn drop ( & mut self ) {
1168
+ for _ in self { }
1169
+ }
1170
+ }
1171
+
1172
+
1173
+ impl < ' a , K , V , S , F > Iterator for Retain < ' a , K , V , S , F >
1174
+ where F : FnMut ( & mut K , & mut V ) -> bool
1175
+ {
1176
+ type Item = ( K , V ) ;
1177
+
1178
+ fn next ( & mut self ) -> Option < Self :: Item > {
1179
+ while self . i < self . map . len ( ) {
1180
+ let keep = {
1181
+ let entry = & mut self . map . entries [ self . i ] ;
1182
+ ( self . keep ) ( & mut entry. key , & mut entry. value )
1183
+ } ;
1184
+ if keep {
1185
+ self . i += 1 ;
1186
+ } else {
1187
+ // skip increment on remove
1188
+ return self . map . swap_remove_index ( self . i ) ;
1189
+ }
1190
+ }
1191
+ None
1192
+ }
1193
+
1194
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1195
+ ( 0 , Some ( self . map . len ( ) - self . i ) )
1196
+ }
1197
+ }
1198
+
1169
1199
pub struct Iter < ' a , K : ' a , V : ' a > {
1170
1200
iter : SliceIter < ' a , Bucket < K , V > > ,
1171
1201
}
@@ -1214,7 +1244,7 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1214
1244
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1215
1245
self . iter . size_hint ( )
1216
1246
}
1217
-
1247
+
1218
1248
fn count ( self ) -> usize {
1219
1249
self . iter . len ( )
1220
1250
}
@@ -1492,6 +1522,51 @@ mod tests {
1492
1522
}
1493
1523
}
1494
1524
1525
+ #[ test]
1526
+ fn retain ( ) {
1527
+ let mut insert = vec ! [ 0 , 4 , 2 , 12 , 8 , 7 , 11 , 5 , 3 , 17 , 19 , 22 , 23 ] ;
1528
+ let mut map = OrderMap :: new ( ) ;
1529
+
1530
+ for & elt in & insert {
1531
+ map. insert ( elt, elt) ;
1532
+ }
1533
+
1534
+ assert_eq ! ( map. keys( ) . count( ) , map. len( ) ) ;
1535
+ assert_eq ! ( map. keys( ) . count( ) , insert. len( ) ) ;
1536
+ for ( a, b) in insert. iter ( ) . zip ( map. keys ( ) ) {
1537
+ assert_eq ! ( a, b) ;
1538
+ }
1539
+
1540
+ let mut removed_ex = Vec :: new ( ) ;
1541
+ for i in 0 .. {
1542
+ while insert. get ( i) . iter ( ) . filter ( |& v| * * v >= 10 ) . next ( ) . is_some ( ) {
1543
+ removed_ex. push ( insert. swap_remove ( i) ) ;
1544
+ }
1545
+ if i > insert. len ( ) {
1546
+ break ;
1547
+ }
1548
+ }
1549
+ println ! ( "{:?}" , removed_ex) ;
1550
+
1551
+ {
1552
+ let removed: Vec < _ > = map. retain ( |k, _| * k < 10 ) . collect ( ) ;
1553
+ assert_eq ! ( removed. len( ) , removed_ex. len( ) ) ;
1554
+ for ( & a, ( b, _) ) in removed_ex. iter ( ) . zip ( removed) {
1555
+ assert_eq ! ( a, b) ;
1556
+ }
1557
+ }
1558
+
1559
+ println ! ( "{:?}" , insert) ;
1560
+ println ! ( "{:?}" , map) ;
1561
+
1562
+ assert_eq ! ( map. keys( ) . count( ) , insert. len( ) ) ;
1563
+ assert_eq ! ( map. keys( ) . count( ) , insert. len( ) ) ;
1564
+
1565
+ for ( & a, & b) in insert. iter ( ) . zip ( map. keys ( ) ) {
1566
+ assert_eq ! ( a, b) ;
1567
+ }
1568
+ }
1569
+
1495
1570
#[ test]
1496
1571
fn remove ( ) {
1497
1572
let insert = [ 0 , 4 , 2 , 12 , 8 , 7 , 11 , 5 , 3 , 17 , 19 , 22 , 23 ] ;
0 commit comments