| 1 | #[cfg (feature = "default-hasher" )] |
| 2 | use { |
| 3 | core::hash::{BuildHasher, Hasher}, |
| 4 | foldhash::fast::RandomState, |
| 5 | }; |
| 6 | |
| 7 | /// Default hash builder for the `S` type parameter of |
| 8 | /// [`HashMap`](crate::HashMap) and [`HashSet`](crate::HashSet). |
| 9 | /// |
| 10 | /// This only implements `BuildHasher` when the "default-hasher" crate feature |
| 11 | /// is enabled; otherwise it just serves as a placeholder, and a custom `S` type |
| 12 | /// must be used to have a fully functional `HashMap` or `HashSet`. |
| 13 | #[derive (Clone, Debug, Default)] |
| 14 | pub struct DefaultHashBuilder { |
| 15 | #[cfg (feature = "default-hasher" )] |
| 16 | inner: RandomState, |
| 17 | } |
| 18 | |
| 19 | #[cfg (feature = "default-hasher" )] |
| 20 | impl BuildHasher for DefaultHashBuilder { |
| 21 | type Hasher = DefaultHasher; |
| 22 | |
| 23 | #[inline (always)] |
| 24 | fn build_hasher(&self) -> Self::Hasher { |
| 25 | DefaultHasher { |
| 26 | inner: self.inner.build_hasher(), |
| 27 | } |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | /// Default hasher for [`HashMap`](crate::HashMap) and [`HashSet`](crate::HashSet). |
| 32 | #[cfg (feature = "default-hasher" )] |
| 33 | #[derive (Clone)] |
| 34 | pub struct DefaultHasher { |
| 35 | inner: <RandomState as BuildHasher>::Hasher, |
| 36 | } |
| 37 | |
| 38 | #[cfg (feature = "default-hasher" )] |
| 39 | macro_rules! forward_writes { |
| 40 | ($( $write:ident ( $ty:ty ) , )*) => {$( |
| 41 | #[inline(always)] |
| 42 | fn $write(&mut self, arg: $ty) { |
| 43 | self.inner.$write(arg); |
| 44 | } |
| 45 | )*} |
| 46 | } |
| 47 | |
| 48 | #[cfg (feature = "default-hasher" )] |
| 49 | impl Hasher for DefaultHasher { |
| 50 | forward_writes! { |
| 51 | write(&[u8]), |
| 52 | write_u8(u8), |
| 53 | write_u16(u16), |
| 54 | write_u32(u32), |
| 55 | write_u64(u64), |
| 56 | write_u128(u128), |
| 57 | write_usize(usize), |
| 58 | write_i8(i8), |
| 59 | write_i16(i16), |
| 60 | write_i32(i32), |
| 61 | write_i64(i64), |
| 62 | write_i128(i128), |
| 63 | write_isize(isize), |
| 64 | } |
| 65 | |
| 66 | // feature(hasher_prefixfree_extras) |
| 67 | #[cfg (feature = "nightly" )] |
| 68 | forward_writes! { |
| 69 | write_length_prefix(usize), |
| 70 | write_str(&str), |
| 71 | } |
| 72 | |
| 73 | #[inline (always)] |
| 74 | fn finish(&self) -> u64 { |
| 75 | self.inner.finish() |
| 76 | } |
| 77 | } |
| 78 | |