Skip to content

Commit 8b60594

Browse files
committed
Add HashTable::iter_hash_mut variant of HashTable::iter_hash
1 parent f40a539 commit 8b60594

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

src/table.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,59 @@ where
780780
}
781781
}
782782

783+
/// A mutable iterator visiting all elements which may match a hash.
784+
/// The iterator element type is `&'a mut T`.
785+
///
786+
/// This iterator may return elements from the table that have a hash value
787+
/// different than the one provided. You should always validate the returned
788+
/// values before using them.
789+
///
790+
/// # Examples
791+
///
792+
/// ```
793+
/// # #[cfg(feature = "nightly")]
794+
/// # fn test() {
795+
/// use hashbrown::{HashTable, DefaultHashBuilder};
796+
/// use std::hash::BuildHasher;
797+
///
798+
/// let mut table = HashTable::new();
799+
/// let hasher = DefaultHashBuilder::default();
800+
/// let hasher = |val: &_| hasher.hash_one(val);
801+
/// table.insert_unique(hasher(&1), 2, hasher);
802+
/// table.insert_unique(hasher(&1), 3, hasher);
803+
/// table.insert_unique(hasher(&2), 5, hasher);
804+
///
805+
/// // Update matching values
806+
/// for val in table.iter_hash_mut(hasher(&1)) {
807+
/// *val *= 2;
808+
/// }
809+
///
810+
/// assert_eq!(table.len(), 3);
811+
/// let mut vec: Vec<i32> = Vec::new();
812+
///
813+
/// for val in &table {
814+
/// println!("val: {}", val);
815+
/// vec.push(*val);
816+
/// }
817+
///
818+
/// // The values will contain 4 and 6 and may contain either 5 or 10.
819+
/// assert!(vec.contains(&4));
820+
/// assert!(vec.contains(&6));
821+
///
822+
/// assert_eq!(table.len(), 3);
823+
/// # }
824+
/// # fn main() {
825+
/// # #[cfg(feature = "nightly")]
826+
/// # test()
827+
/// # }
828+
/// ```
829+
pub fn iter_hash_mut(&mut self, hash: u64) -> IterHashMut<'_, T> {
830+
IterHashMut {
831+
inner: unsafe { self.raw.iter_hash(hash) },
832+
_marker: PhantomData,
833+
}
834+
}
835+
783836
/// Retains only the elements specified by the predicate.
784837
///
785838
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
@@ -1996,6 +2049,31 @@ impl<'a, T> Iterator for IterHash<'a, T> {
19962049
}
19972050
}
19982051

2052+
/// A mutable iterator over the entries of a `HashTable` that could match a given hash.
2053+
/// The iterator element type is `&'a mut T`.
2054+
///
2055+
/// This `struct` is created by the [`iter_hash_mut`] method on [`HashTable`]. See its
2056+
/// documentation for more.
2057+
///
2058+
/// [`iter_hash_mut`]: struct.HashTable.html#method.iter_hash_mut
2059+
/// [`HashTable`]: struct.HashTable.html
2060+
pub struct IterHashMut<'a, T> {
2061+
inner: RawIterHash<T>,
2062+
_marker: PhantomData<&'a mut T>,
2063+
}
2064+
2065+
impl<'a, T> Iterator for IterHashMut<'a, T> {
2066+
type Item = &'a mut T;
2067+
2068+
fn next(&mut self) -> Option<Self::Item> {
2069+
// Avoid `Option::map` because it bloats LLVM IR.
2070+
match self.inner.next() {
2071+
Some(bucket) => Some(unsafe { bucket.as_mut() }),
2072+
None => None,
2073+
}
2074+
}
2075+
}
2076+
19992077
/// An owning iterator over the entries of a `HashTable` in arbitrary order.
20002078
/// The iterator element type is `T`.
20012079
///

0 commit comments

Comments
 (0)