@@ -186,15 +186,8 @@ pub enum DefaultHashBuilder {}
186
186
/// // use the values stored in map
187
187
/// ```
188
188
pub struct HashMap < K , V , S = DefaultHashBuilder , A : Allocator + Clone = Global > {
189
- #[ cfg( any( feature = "rustc-internal-api" , not( feature = "map-inner" ) ) ) ]
190
189
pub ( crate ) hash_builder : S ,
191
- #[ cfg( any( feature = "rustc-internal-api" , not( feature = "map-inner" ) ) ) ]
192
190
pub ( crate ) table : RawTable < ( K , V ) , A > ,
193
-
194
- #[ cfg( all( feature = "map-inner" , not( feature = "rustc-internal-api" ) ) ) ]
195
- pub hash_builder : S ,
196
- #[ cfg( all( feature = "map-inner" , not( feature = "rustc-internal-api" ) ) ) ]
197
- pub table : RawTable < ( K , V ) , A > ,
198
191
}
199
192
200
193
impl < K : Clone , V : Clone , S : Clone , A : Allocator + Clone > Clone for HashMap < K , V , S , A > {
@@ -2019,6 +2012,67 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
2019
2012
pub fn raw_entry ( & self ) -> RawEntryBuilder < ' _ , K , V , S , A > {
2020
2013
RawEntryBuilder { map : self }
2021
2014
}
2015
+
2016
+ /// Returns a mutable reference to the [`RawTable`] used underneath [`HashMap`].
2017
+ /// This function is only available if the `raw` feature of the crate is enabled.
2018
+ ///
2019
+ /// # Note
2020
+ ///
2021
+ /// Calling the function safe, but using raw hash table API's may require
2022
+ /// unsafe functions or blocks.
2023
+ ///
2024
+ /// `RawTable` API gives the lowest level of control under the map that can be useful
2025
+ /// for extending the HashMap's API, but may lead to *[undefined behavior]*.
2026
+ ///
2027
+ /// [`HashMap`]: struct.HashMap.html
2028
+ /// [`RawTable`]: raw/struct.RawTable.html
2029
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2030
+ ///
2031
+ /// # Examples
2032
+ ///
2033
+ /// ```
2034
+ /// use core::hash::{BuildHasher, Hash};
2035
+ /// use hashbrown::HashMap;
2036
+ ///
2037
+ /// let mut map = HashMap::new();
2038
+ /// map.extend([("a", 10), ("b", 20), ("c", 30)]);
2039
+ /// assert_eq!(map.len(), 3);
2040
+ ///
2041
+ /// // Let's imagine that we have a value and a hash of the key, but not the key itself.
2042
+ /// // However, if you want to remove the value from the map by hash and value, and you
2043
+ /// // know exactly that the value is unique, then you can create a function like this:
2044
+ /// fn remove_by_hash<K, V, S, F>(
2045
+ /// map: &mut HashMap<K, V, S>,
2046
+ /// hash: u64,
2047
+ /// is_match: F,
2048
+ /// ) -> Option<(K, V)>
2049
+ /// where
2050
+ /// F: Fn(&K, &V) -> bool,
2051
+ /// {
2052
+ /// let raw_table = map.raw_table();
2053
+ /// match raw_table.find(hash, |(k, v)| is_match(k, v)) {
2054
+ /// Some(bucket) => Some(unsafe { raw_table.remove(bucket) }),
2055
+ /// None => None,
2056
+ /// }
2057
+ /// }
2058
+ ///
2059
+ /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
2060
+ /// use core::hash::Hasher;
2061
+ /// let mut state = hash_builder.build_hasher();
2062
+ /// key.hash(&mut state);
2063
+ /// state.finish()
2064
+ /// }
2065
+ ///
2066
+ /// let hash = compute_hash(map.hasher(), "a");
2067
+ /// assert_eq!(remove_by_hash(&mut map, hash, |_, v| *v == 10), Some(("a", 10)));
2068
+ /// assert_eq!(map.get(&"a"), None);
2069
+ /// assert_eq!(map.len(), 2);
2070
+ /// ```
2071
+ #[ cfg( feature = "raw" ) ]
2072
+ #[ cfg_attr( feature = "inline-more" , inline) ]
2073
+ pub fn raw_table ( & mut self ) -> & mut RawTable < ( K , V ) , A > {
2074
+ & mut self . table
2075
+ }
2022
2076
}
2023
2077
2024
2078
impl < K , V , S , A > PartialEq for HashMap < K , V , S , A >
0 commit comments