|
1 | | -use crate::raw::{Allocator, Bucket, Global, RawExtractIf}; |
| 1 | +use crate::raw::{Allocator, Bucket, Global}; |
2 | 2 | use crate::{table, DefaultHashBuilder, Equivalent, HashTable, TryReserveError}; |
3 | 3 | use ::alloc::borrow::ToOwned; |
4 | 4 | use core::borrow::Borrow; |
@@ -960,14 +960,10 @@ impl<K, V, S, A: Allocator> HashMap<K, V, S, A> { |
960 | 960 | #[cfg_attr(feature = "inline-more", inline)] |
961 | 961 | pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, K, V, F, A> |
962 | 962 | where |
963 | | - F: FnMut(&K, &mut V) -> bool, |
| 963 | + F: Filter<K, V>, |
964 | 964 | { |
965 | 965 | ExtractIf { |
966 | | - f, |
967 | | - inner: RawExtractIf { |
968 | | - iter: unsafe { self.table.raw.iter() }, |
969 | | - table: &mut self.table.raw, |
970 | | - }, |
| 966 | + inner: self.table.extract_if(KeyVal(f)), |
971 | 967 | } |
972 | 968 | } |
973 | 969 |
|
@@ -2590,6 +2586,29 @@ impl<K, V, A: Allocator> Drain<'_, K, V, A> { |
2590 | 2586 | } |
2591 | 2587 | } |
2592 | 2588 |
|
| 2589 | +/// Adapter between [`map::Filter`](Filter) and [`table::Filter`]. |
| 2590 | +struct KeyVal<F>(F); |
| 2591 | +impl<K, V, F: Filter<K, V>> table::Filter<(K, V)> for KeyVal<F> { |
| 2592 | + #[inline] |
| 2593 | + fn should_extract(&mut self, (ref key, ref mut val): &mut (K, V)) -> bool { |
| 2594 | + self.0.should_extract(key, val) |
| 2595 | + } |
| 2596 | +} |
| 2597 | + |
| 2598 | +/// Filter for [`ExtractIf`]. |
| 2599 | +/// |
| 2600 | +/// Accepts `FnMut(&K, &mut V) -> bool`, but can be implemented directly. |
| 2601 | +pub trait Filter<K, V> { |
| 2602 | + /// Whether the element should be extracted. |
| 2603 | + fn should_extract(&mut self, key: &K, value: &mut V) -> bool; |
| 2604 | +} |
| 2605 | +impl<K, V, F: FnMut(&K, &mut V) -> bool> Filter<K, V> for F { |
| 2606 | + #[inline] |
| 2607 | + fn should_extract(&mut self, key: &K, value: &mut V) -> bool { |
| 2608 | + (self)(key, value) |
| 2609 | + } |
| 2610 | +} |
| 2611 | + |
2593 | 2612 | /// A draining iterator over entries of a `HashMap` which don't satisfy the predicate |
2594 | 2613 | /// `f(&k, &mut v)` in arbitrary order. The iterator element type is `(K, V)`. |
2595 | 2614 | /// |
@@ -2623,25 +2642,24 @@ impl<K, V, A: Allocator> Drain<'_, K, V, A> { |
2623 | 2642 | /// ``` |
2624 | 2643 | #[must_use = "Iterators are lazy unless consumed"] |
2625 | 2644 | pub struct ExtractIf<'a, K, V, F, A: Allocator = Global> { |
2626 | | - f: F, |
2627 | | - inner: RawExtractIf<'a, (K, V), A>, |
| 2645 | + inner: table::ExtractIf<'a, (K, V), KeyVal<F>, A>, |
2628 | 2646 | } |
2629 | 2647 |
|
2630 | 2648 | impl<K, V, F, A> Iterator for ExtractIf<'_, K, V, F, A> |
2631 | 2649 | where |
2632 | | - F: FnMut(&K, &mut V) -> bool, |
| 2650 | + F: Filter<K, V>, |
2633 | 2651 | A: Allocator, |
2634 | 2652 | { |
2635 | 2653 | type Item = (K, V); |
2636 | 2654 |
|
2637 | 2655 | #[cfg_attr(feature = "inline-more", inline)] |
2638 | 2656 | fn next(&mut self) -> Option<Self::Item> { |
2639 | | - self.inner.next(|&mut (ref k, ref mut v)| (self.f)(k, v)) |
| 2657 | + self.inner.next() |
2640 | 2658 | } |
2641 | 2659 |
|
2642 | 2660 | #[inline] |
2643 | 2661 | fn size_hint(&self) -> (usize, Option<usize>) { |
2644 | | - (0, self.inner.iter.size_hint().1) |
| 2662 | + self.inner.size_hint() |
2645 | 2663 | } |
2646 | 2664 | } |
2647 | 2665 |
|
|
0 commit comments