@@ -3,7 +3,7 @@ use core::{fmt, iter::FusedIterator, marker::PhantomData};
3
3
use crate :: {
4
4
raw:: {
5
5
Allocator , Bucket , Global , InsertSlot , RawDrain , RawExtractIf , RawIntoIter , RawIter ,
6
- RawTable ,
6
+ RawIterHash , RawTable ,
7
7
} ,
8
8
TryReserveError ,
9
9
} ;
@@ -741,6 +741,98 @@ where
741
741
}
742
742
}
743
743
744
+ /// An iterator visiting all elements which may match a hash.
745
+ /// The iterator element type is `&'a T`.
746
+ ///
747
+ /// This iterator may return elements from the table that have a hash value
748
+ /// different than the one provided. You should always validate the returned
749
+ /// values before using them.
750
+ ///
751
+ /// # Examples
752
+ ///
753
+ /// ```
754
+ /// # #[cfg(feature = "nightly")]
755
+ /// # fn test() {
756
+ /// use hashbrown::{HashTable, DefaultHashBuilder};
757
+ /// use std::hash::BuildHasher;
758
+ ///
759
+ /// let mut table = HashTable::new();
760
+ /// let hasher = DefaultHashBuilder::default();
761
+ /// let hasher = |val: &_| hasher.hash_one(val);
762
+ /// table.insert_unique(hasher(&"a"), "a", hasher);
763
+ /// table.insert_unique(hasher(&"a"), "b", hasher);
764
+ /// table.insert_unique(hasher(&"b"), "c", hasher);
765
+ ///
766
+ /// // Will print "a" and "b" (and possibly "c") in an arbitrary order.
767
+ /// for x in table.iter_hash(hasher(&"a")) {
768
+ /// println!("{}", x);
769
+ /// }
770
+ /// # }
771
+ /// # fn main() {
772
+ /// # #[cfg(feature = "nightly")]
773
+ /// # test()
774
+ /// # }
775
+ /// ```
776
+ pub fn iter_hash ( & self , hash : u64 ) -> IterHash < ' _ , T > {
777
+ IterHash {
778
+ inner : unsafe { self . raw . iter_hash ( hash) } ,
779
+ _marker : PhantomData ,
780
+ }
781
+ }
782
+
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
+
744
836
/// Retains only the elements specified by the predicate.
745
837
///
746
838
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
@@ -1932,6 +2024,56 @@ impl<T> ExactSizeIterator for IterMut<'_, T> {
1932
2024
1933
2025
impl < T > FusedIterator for IterMut < ' _ , T > { }
1934
2026
2027
+ /// An iterator over the entries of a `HashTable` that could match a given hash.
2028
+ /// The iterator element type is `&'a T`.
2029
+ ///
2030
+ /// This `struct` is created by the [`iter_hash`] method on [`HashTable`]. See its
2031
+ /// documentation for more.
2032
+ ///
2033
+ /// [`iter_hash`]: struct.HashTable.html#method.iter_hash
2034
+ /// [`HashTable`]: struct.HashTable.html
2035
+ pub struct IterHash < ' a , T > {
2036
+ inner : RawIterHash < T > ,
2037
+ _marker : PhantomData < & ' a T > ,
2038
+ }
2039
+
2040
+ impl < ' a , T > Iterator for IterHash < ' a , T > {
2041
+ type Item = & ' a T ;
2042
+
2043
+ fn next ( & mut self ) -> Option < Self :: Item > {
2044
+ // Avoid `Option::map` because it bloats LLVM IR.
2045
+ match self . inner . next ( ) {
2046
+ Some ( bucket) => Some ( unsafe { bucket. as_ref ( ) } ) ,
2047
+ None => None ,
2048
+ }
2049
+ }
2050
+ }
2051
+
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
+
1935
2077
/// An owning iterator over the entries of a `HashTable` in arbitrary order.
1936
2078
/// The iterator element type is `T`.
1937
2079
///
0 commit comments