update hashbrown and replace Hash{Set,Map}::DrainFilter with ExtractIf
This commit is contained in:
parent
18c9a12d13
commit
479be6ac43
17
Cargo.lock
17
Cargo.lock
@ -65,6 +65,12 @@ dependencies = [
|
|||||||
"rand_xorshift",
|
"rand_xorshift",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "allocator-api2"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4f263788a35611fba42eb41ff811c5d0360c58b97402570312a350736e2542e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ammonia"
|
name = "ammonia"
|
||||||
version = "3.2.0"
|
version = "3.2.0"
|
||||||
@ -1522,6 +1528,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038"
|
checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash 0.8.2",
|
"ahash 0.8.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
|
||||||
|
dependencies = [
|
||||||
|
"allocator-api2",
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"rustc-std-workspace-alloc",
|
"rustc-std-workspace-alloc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
@ -4633,7 +4648,7 @@ dependencies = [
|
|||||||
"core",
|
"core",
|
||||||
"dlmalloc",
|
"dlmalloc",
|
||||||
"fortanix-sgx-abi",
|
"fortanix-sgx-abi",
|
||||||
"hashbrown 0.13.1",
|
"hashbrown 0.14.0",
|
||||||
"hermit-abi 0.3.0",
|
"hermit-abi 0.3.0",
|
||||||
"libc",
|
"libc",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
|
@ -21,7 +21,7 @@ libc = { version = "0.2.146", default-features = false, features = ['rustc-dep-o
|
|||||||
compiler_builtins = { version = "0.1.92" }
|
compiler_builtins = { version = "0.1.92" }
|
||||||
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
||||||
unwind = { path = "../unwind" }
|
unwind = { path = "../unwind" }
|
||||||
hashbrown = { version = "0.13", default-features = false, features = ['rustc-dep-of-std'] }
|
hashbrown = { version = "0.14", default-features = false, features = ['rustc-dep-of-std'] }
|
||||||
std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = ['rustc-dep-of-std'] }
|
std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = ['rustc-dep-of-std'] }
|
||||||
|
|
||||||
# Dependencies of the `backtrace` crate
|
# Dependencies of the `backtrace` crate
|
||||||
|
@ -623,28 +623,27 @@ impl<K, V, S> HashMap<K, V, S> {
|
|||||||
/// If the closure returns false, or panics, the element remains in the map and will not be
|
/// If the closure returns false, or panics, the element remains in the map and will not be
|
||||||
/// yielded.
|
/// yielded.
|
||||||
///
|
///
|
||||||
/// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of
|
/// Note that `extract_if` lets you mutate every value in the filter closure, regardless of
|
||||||
/// whether you choose to keep or remove it.
|
/// whether you choose to keep or remove it.
|
||||||
///
|
///
|
||||||
/// If the iterator is only partially consumed or not consumed at all, each of the remaining
|
/// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
|
||||||
/// elements will still be subjected to the closure and removed and dropped if it returns true.
|
/// or the iteration short-circuits, then the remaining elements will be retained.
|
||||||
|
/// Use [`retain`] with a negated predicate if you do not need the returned iterator.
|
||||||
///
|
///
|
||||||
/// It is unspecified how many more elements will be subjected to the closure
|
/// [`retain`]: HashMap::retain
|
||||||
/// if a panic occurs in the closure, or a panic occurs while dropping an element,
|
|
||||||
/// or if the `DrainFilter` value is leaked.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Splitting a map into even and odd keys, reusing the original map:
|
/// Splitting a map into even and odd keys, reusing the original map:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(hash_drain_filter)]
|
/// #![feature(hash_extract_if)]
|
||||||
/// use std::collections::HashMap;
|
/// use std::collections::HashMap;
|
||||||
///
|
///
|
||||||
/// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
|
/// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
|
||||||
/// let drained: HashMap<i32, i32> = map.drain_filter(|k, _v| k % 2 == 0).collect();
|
/// let extracted: HashMap<i32, i32> = map.extract_if(|k, _v| k % 2 == 0).collect();
|
||||||
///
|
///
|
||||||
/// let mut evens = drained.keys().copied().collect::<Vec<_>>();
|
/// let mut evens = extracted.keys().copied().collect::<Vec<_>>();
|
||||||
/// let mut odds = map.keys().copied().collect::<Vec<_>>();
|
/// let mut odds = map.keys().copied().collect::<Vec<_>>();
|
||||||
/// evens.sort();
|
/// evens.sort();
|
||||||
/// odds.sort();
|
/// odds.sort();
|
||||||
@ -654,12 +653,12 @@ impl<K, V, S> HashMap<K, V, S> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[rustc_lint_query_instability]
|
#[rustc_lint_query_instability]
|
||||||
#[unstable(feature = "hash_drain_filter", issue = "59618")]
|
#[unstable(feature = "hash_extract_if", issue = "59618")]
|
||||||
pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, K, V, F>
|
pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, K, V, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&K, &mut V) -> bool,
|
F: FnMut(&K, &mut V) -> bool,
|
||||||
{
|
{
|
||||||
DrainFilter { base: self.base.drain_filter(pred) }
|
ExtractIf { base: self.base.extract_if(pred) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retains only the elements specified by the predicate.
|
/// Retains only the elements specified by the predicate.
|
||||||
@ -1578,28 +1577,29 @@ impl<'a, K, V> Drain<'a, K, V> {
|
|||||||
|
|
||||||
/// A draining, filtering iterator over the entries of a `HashMap`.
|
/// A draining, filtering iterator over the entries of a `HashMap`.
|
||||||
///
|
///
|
||||||
/// This `struct` is created by the [`drain_filter`] method on [`HashMap`].
|
/// This `struct` is created by the [`extract_if`] method on [`HashMap`].
|
||||||
///
|
///
|
||||||
/// [`drain_filter`]: HashMap::drain_filter
|
/// [`extract_if`]: HashMap::extract_if
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(hash_drain_filter)]
|
/// #![feature(hash_extract_if)]
|
||||||
///
|
///
|
||||||
/// use std::collections::HashMap;
|
/// use std::collections::HashMap;
|
||||||
///
|
///
|
||||||
/// let mut map = HashMap::from([
|
/// let mut map = HashMap::from([
|
||||||
/// ("a", 1),
|
/// ("a", 1),
|
||||||
/// ]);
|
/// ]);
|
||||||
/// let iter = map.drain_filter(|_k, v| *v % 2 == 0);
|
/// let iter = map.extract_if(|_k, v| *v % 2 == 0);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "hash_drain_filter", issue = "59618")]
|
#[unstable(feature = "hash_extract_if", issue = "59618")]
|
||||||
pub struct DrainFilter<'a, K, V, F>
|
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||||
|
pub struct ExtractIf<'a, K, V, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&K, &mut V) -> bool,
|
F: FnMut(&K, &mut V) -> bool,
|
||||||
{
|
{
|
||||||
base: base::DrainFilter<'a, K, V, F>,
|
base: base::ExtractIf<'a, K, V, F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mutable iterator over the values of a `HashMap`.
|
/// A mutable iterator over the values of a `HashMap`.
|
||||||
@ -2479,8 +2479,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "hash_drain_filter", issue = "59618")]
|
#[unstable(feature = "hash_extract_if", issue = "59618")]
|
||||||
impl<K, V, F> Iterator for DrainFilter<'_, K, V, F>
|
impl<K, V, F> Iterator for ExtractIf<'_, K, V, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&K, &mut V) -> bool,
|
F: FnMut(&K, &mut V) -> bool,
|
||||||
{
|
{
|
||||||
@ -2496,16 +2496,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "hash_drain_filter", issue = "59618")]
|
#[unstable(feature = "hash_extract_if", issue = "59618")]
|
||||||
impl<K, V, F> FusedIterator for DrainFilter<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {}
|
impl<K, V, F> FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {}
|
||||||
|
|
||||||
#[unstable(feature = "hash_drain_filter", issue = "59618")]
|
#[unstable(feature = "hash_extract_if", issue = "59618")]
|
||||||
impl<'a, K, V, F> fmt::Debug for DrainFilter<'a, K, V, F>
|
impl<'a, K, V, F> fmt::Debug for ExtractIf<'a, K, V, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&K, &mut V) -> bool,
|
F: FnMut(&K, &mut V) -> bool,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("DrainFilter").finish_non_exhaustive()
|
f.debug_struct("ExtractIf").finish_non_exhaustive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -944,7 +944,7 @@ fn test_raw_entry() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test_drain_filter {
|
mod test_extract_if {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::panic::{catch_unwind, AssertUnwindSafe};
|
use crate::panic::{catch_unwind, AssertUnwindSafe};
|
||||||
@ -968,7 +968,7 @@ mod test_drain_filter {
|
|||||||
#[test]
|
#[test]
|
||||||
fn empty() {
|
fn empty() {
|
||||||
let mut map: HashMap<i32, i32> = HashMap::new();
|
let mut map: HashMap<i32, i32> = HashMap::new();
|
||||||
map.drain_filter(|_, _| unreachable!("there's nothing to decide on"));
|
map.extract_if(|_, _| unreachable!("there's nothing to decide on")).for_each(drop);
|
||||||
assert!(map.is_empty());
|
assert!(map.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -976,7 +976,7 @@ mod test_drain_filter {
|
|||||||
fn consuming_nothing() {
|
fn consuming_nothing() {
|
||||||
let pairs = (0..3).map(|i| (i, i));
|
let pairs = (0..3).map(|i| (i, i));
|
||||||
let mut map: HashMap<_, _> = pairs.collect();
|
let mut map: HashMap<_, _> = pairs.collect();
|
||||||
assert!(map.drain_filter(|_, _| false).eq_sorted(crate::iter::empty()));
|
assert!(map.extract_if(|_, _| false).eq_sorted(crate::iter::empty()));
|
||||||
assert_eq!(map.len(), 3);
|
assert_eq!(map.len(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -984,7 +984,7 @@ mod test_drain_filter {
|
|||||||
fn consuming_all() {
|
fn consuming_all() {
|
||||||
let pairs = (0..3).map(|i| (i, i));
|
let pairs = (0..3).map(|i| (i, i));
|
||||||
let mut map: HashMap<_, _> = pairs.clone().collect();
|
let mut map: HashMap<_, _> = pairs.clone().collect();
|
||||||
assert!(map.drain_filter(|_, _| true).eq_sorted(pairs));
|
assert!(map.extract_if(|_, _| true).eq_sorted(pairs));
|
||||||
assert!(map.is_empty());
|
assert!(map.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -993,7 +993,7 @@ mod test_drain_filter {
|
|||||||
let pairs = (0..3).map(|i| (i, i));
|
let pairs = (0..3).map(|i| (i, i));
|
||||||
let mut map: HashMap<_, _> = pairs.collect();
|
let mut map: HashMap<_, _> = pairs.collect();
|
||||||
assert!(
|
assert!(
|
||||||
map.drain_filter(|_, v| {
|
map.extract_if(|_, v| {
|
||||||
*v += 6;
|
*v += 6;
|
||||||
false
|
false
|
||||||
})
|
})
|
||||||
@ -1008,7 +1008,7 @@ mod test_drain_filter {
|
|||||||
let pairs = (0..3).map(|i| (i, i));
|
let pairs = (0..3).map(|i| (i, i));
|
||||||
let mut map: HashMap<_, _> = pairs.collect();
|
let mut map: HashMap<_, _> = pairs.collect();
|
||||||
assert!(
|
assert!(
|
||||||
map.drain_filter(|_, v| {
|
map.extract_if(|_, v| {
|
||||||
*v += 6;
|
*v += 6;
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
@ -1034,14 +1034,15 @@ mod test_drain_filter {
|
|||||||
let mut map = (0..3).map(|i| (i, D)).collect::<HashMap<_, _>>();
|
let mut map = (0..3).map(|i| (i, D)).collect::<HashMap<_, _>>();
|
||||||
|
|
||||||
catch_unwind(move || {
|
catch_unwind(move || {
|
||||||
drop(map.drain_filter(|_, _| {
|
map.extract_if(|_, _| {
|
||||||
PREDS.fetch_add(1, Ordering::SeqCst);
|
PREDS.fetch_add(1, Ordering::SeqCst);
|
||||||
true
|
true
|
||||||
}))
|
})
|
||||||
|
.for_each(drop)
|
||||||
})
|
})
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
assert_eq!(PREDS.load(Ordering::SeqCst), 3);
|
assert_eq!(PREDS.load(Ordering::SeqCst), 2);
|
||||||
assert_eq!(DROPS.load(Ordering::SeqCst), 3);
|
assert_eq!(DROPS.load(Ordering::SeqCst), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,10 +1061,11 @@ mod test_drain_filter {
|
|||||||
let mut map = (0..3).map(|i| (i, D)).collect::<HashMap<_, _>>();
|
let mut map = (0..3).map(|i| (i, D)).collect::<HashMap<_, _>>();
|
||||||
|
|
||||||
catch_unwind(AssertUnwindSafe(|| {
|
catch_unwind(AssertUnwindSafe(|| {
|
||||||
drop(map.drain_filter(|_, _| match PREDS.fetch_add(1, Ordering::SeqCst) {
|
map.extract_if(|_, _| match PREDS.fetch_add(1, Ordering::SeqCst) {
|
||||||
0 => true,
|
0 => true,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}))
|
})
|
||||||
|
.for_each(drop)
|
||||||
}))
|
}))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
@ -1088,7 +1090,7 @@ mod test_drain_filter {
|
|||||||
let mut map = (0..3).map(|i| (i, D)).collect::<HashMap<_, _>>();
|
let mut map = (0..3).map(|i| (i, D)).collect::<HashMap<_, _>>();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut it = map.drain_filter(|_, _| match PREDS.fetch_add(1, Ordering::SeqCst) {
|
let mut it = map.extract_if(|_, _| match PREDS.fetch_add(1, Ordering::SeqCst) {
|
||||||
0 => true,
|
0 => true,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
});
|
});
|
||||||
|
@ -262,25 +262,24 @@ impl<T, S> HashSet<T, S> {
|
|||||||
/// If the closure returns false, the value will remain in the list and will not be yielded
|
/// If the closure returns false, the value will remain in the list and will not be yielded
|
||||||
/// by the iterator.
|
/// by the iterator.
|
||||||
///
|
///
|
||||||
/// If the iterator is only partially consumed or not consumed at all, each of the remaining
|
/// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
|
||||||
/// values will still be subjected to the closure and removed and dropped if it returns true.
|
/// or the iteration short-circuits, then the remaining elements will be retained.
|
||||||
|
/// Use [`retain`] with a negated predicate if you do not need the returned iterator.
|
||||||
///
|
///
|
||||||
/// It is unspecified how many more values will be subjected to the closure
|
/// [`retain`]: HashSet::retain
|
||||||
/// if a panic occurs in the closure, or if a panic occurs while dropping a value, or if the
|
|
||||||
/// `DrainFilter` itself is leaked.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Splitting a set into even and odd values, reusing the original set:
|
/// Splitting a set into even and odd values, reusing the original set:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(hash_drain_filter)]
|
/// #![feature(hash_extract_if)]
|
||||||
/// use std::collections::HashSet;
|
/// use std::collections::HashSet;
|
||||||
///
|
///
|
||||||
/// let mut set: HashSet<i32> = (0..8).collect();
|
/// let mut set: HashSet<i32> = (0..8).collect();
|
||||||
/// let drained: HashSet<i32> = set.drain_filter(|v| v % 2 == 0).collect();
|
/// let extracted: HashSet<i32> = set.extract_if(|v| v % 2 == 0).collect();
|
||||||
///
|
///
|
||||||
/// let mut evens = drained.into_iter().collect::<Vec<_>>();
|
/// let mut evens = extracted.into_iter().collect::<Vec<_>>();
|
||||||
/// let mut odds = set.into_iter().collect::<Vec<_>>();
|
/// let mut odds = set.into_iter().collect::<Vec<_>>();
|
||||||
/// evens.sort();
|
/// evens.sort();
|
||||||
/// odds.sort();
|
/// odds.sort();
|
||||||
@ -290,12 +289,12 @@ impl<T, S> HashSet<T, S> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[rustc_lint_query_instability]
|
#[rustc_lint_query_instability]
|
||||||
#[unstable(feature = "hash_drain_filter", issue = "59618")]
|
#[unstable(feature = "hash_extract_if", issue = "59618")]
|
||||||
pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, T, F>
|
pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, T, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&T) -> bool,
|
F: FnMut(&T) -> bool,
|
||||||
{
|
{
|
||||||
DrainFilter { base: self.base.drain_filter(pred) }
|
ExtractIf { base: self.base.extract_if(pred) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retains only the elements specified by the predicate.
|
/// Retains only the elements specified by the predicate.
|
||||||
@ -1310,27 +1309,27 @@ pub struct Drain<'a, K: 'a> {
|
|||||||
|
|
||||||
/// A draining, filtering iterator over the items of a `HashSet`.
|
/// A draining, filtering iterator over the items of a `HashSet`.
|
||||||
///
|
///
|
||||||
/// This `struct` is created by the [`drain_filter`] method on [`HashSet`].
|
/// This `struct` is created by the [`extract_if`] method on [`HashSet`].
|
||||||
///
|
///
|
||||||
/// [`drain_filter`]: HashSet::drain_filter
|
/// [`extract_if`]: HashSet::extract_if
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(hash_drain_filter)]
|
/// #![feature(hash_extract_if)]
|
||||||
///
|
///
|
||||||
/// use std::collections::HashSet;
|
/// use std::collections::HashSet;
|
||||||
///
|
///
|
||||||
/// let mut a = HashSet::from([1, 2, 3]);
|
/// let mut a = HashSet::from([1, 2, 3]);
|
||||||
///
|
///
|
||||||
/// let mut drain_filtered = a.drain_filter(|v| v % 2 == 0);
|
/// let mut extract_ifed = a.extract_if(|v| v % 2 == 0);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "hash_drain_filter", issue = "59618")]
|
#[unstable(feature = "hash_extract_if", issue = "59618")]
|
||||||
pub struct DrainFilter<'a, K, F>
|
pub struct ExtractIf<'a, K, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&K) -> bool,
|
F: FnMut(&K) -> bool,
|
||||||
{
|
{
|
||||||
base: base::DrainFilter<'a, K, F>,
|
base: base::ExtractIf<'a, K, F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A lazy iterator producing elements in the intersection of `HashSet`s.
|
/// A lazy iterator producing elements in the intersection of `HashSet`s.
|
||||||
@ -1576,8 +1575,8 @@ impl<K: fmt::Debug> fmt::Debug for Drain<'_, K> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "hash_drain_filter", issue = "59618")]
|
#[unstable(feature = "hash_extract_if", issue = "59618")]
|
||||||
impl<K, F> Iterator for DrainFilter<'_, K, F>
|
impl<K, F> Iterator for ExtractIf<'_, K, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&K) -> bool,
|
F: FnMut(&K) -> bool,
|
||||||
{
|
{
|
||||||
@ -1593,16 +1592,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "hash_drain_filter", issue = "59618")]
|
#[unstable(feature = "hash_extract_if", issue = "59618")]
|
||||||
impl<K, F> FusedIterator for DrainFilter<'_, K, F> where F: FnMut(&K) -> bool {}
|
impl<K, F> FusedIterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool {}
|
||||||
|
|
||||||
#[unstable(feature = "hash_drain_filter", issue = "59618")]
|
#[unstable(feature = "hash_extract_if", issue = "59618")]
|
||||||
impl<'a, K, F> fmt::Debug for DrainFilter<'a, K, F>
|
impl<'a, K, F> fmt::Debug for ExtractIf<'a, K, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&K) -> bool,
|
F: FnMut(&K) -> bool,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("DrainFilter").finish_non_exhaustive()
|
f.debug_struct("ExtractIf").finish_non_exhaustive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,18 +418,18 @@ fn test_retain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_drain_filter() {
|
fn test_extract_if() {
|
||||||
let mut x: HashSet<_> = [1].iter().copied().collect();
|
let mut x: HashSet<_> = [1].iter().copied().collect();
|
||||||
let mut y: HashSet<_> = [1].iter().copied().collect();
|
let mut y: HashSet<_> = [1].iter().copied().collect();
|
||||||
|
|
||||||
x.drain_filter(|_| true);
|
x.extract_if(|_| true).for_each(drop);
|
||||||
y.drain_filter(|_| false);
|
y.extract_if(|_| false).for_each(drop);
|
||||||
assert_eq!(x.len(), 0);
|
assert_eq!(x.len(), 0);
|
||||||
assert_eq!(y.len(), 1);
|
assert_eq!(y.len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_drain_filter_drop_panic_leak() {
|
fn test_extract_if_drop_panic_leak() {
|
||||||
static PREDS: AtomicU32 = AtomicU32::new(0);
|
static PREDS: AtomicU32 = AtomicU32::new(0);
|
||||||
static DROPS: AtomicU32 = AtomicU32::new(0);
|
static DROPS: AtomicU32 = AtomicU32::new(0);
|
||||||
|
|
||||||
@ -446,19 +446,20 @@ fn test_drain_filter_drop_panic_leak() {
|
|||||||
let mut set = (0..3).map(|i| D(i)).collect::<HashSet<_>>();
|
let mut set = (0..3).map(|i| D(i)).collect::<HashSet<_>>();
|
||||||
|
|
||||||
catch_unwind(move || {
|
catch_unwind(move || {
|
||||||
drop(set.drain_filter(|_| {
|
set.extract_if(|_| {
|
||||||
PREDS.fetch_add(1, Ordering::SeqCst);
|
PREDS.fetch_add(1, Ordering::SeqCst);
|
||||||
true
|
true
|
||||||
}))
|
})
|
||||||
|
.for_each(drop)
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
assert_eq!(PREDS.load(Ordering::SeqCst), 3);
|
assert_eq!(PREDS.load(Ordering::SeqCst), 2);
|
||||||
assert_eq!(DROPS.load(Ordering::SeqCst), 3);
|
assert_eq!(DROPS.load(Ordering::SeqCst), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_drain_filter_pred_panic_leak() {
|
fn test_extract_if_pred_panic_leak() {
|
||||||
static PREDS: AtomicU32 = AtomicU32::new(0);
|
static PREDS: AtomicU32 = AtomicU32::new(0);
|
||||||
static DROPS: AtomicU32 = AtomicU32::new(0);
|
static DROPS: AtomicU32 = AtomicU32::new(0);
|
||||||
|
|
||||||
@ -473,10 +474,11 @@ fn test_drain_filter_pred_panic_leak() {
|
|||||||
let mut set: HashSet<_> = (0..3).map(|_| D).collect();
|
let mut set: HashSet<_> = (0..3).map(|_| D).collect();
|
||||||
|
|
||||||
catch_unwind(AssertUnwindSafe(|| {
|
catch_unwind(AssertUnwindSafe(|| {
|
||||||
drop(set.drain_filter(|_| match PREDS.fetch_add(1, Ordering::SeqCst) {
|
set.extract_if(|_| match PREDS.fetch_add(1, Ordering::SeqCst) {
|
||||||
0 => true,
|
0 => true,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}))
|
})
|
||||||
|
.for_each(drop)
|
||||||
}))
|
}))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||||||
"adler",
|
"adler",
|
||||||
"ahash",
|
"ahash",
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
|
"allocator-api2", // FIXME: only appears in Cargo.lock due to https://github.com/rust-lang/cargo/issues/10801
|
||||||
"annotate-snippets",
|
"annotate-snippets",
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
"ar_archive_writer",
|
"ar_archive_writer",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user