| { | ||
| "git": { | ||
| "sha1": "db36e4c4f0606b786bc617eefaffbe4ae9100762" | ||
| "sha1": "9aa1ba20f05ed582eda04ea625d5658c92195a57" | ||
| }, | ||
| "path_in_vcs": "" | ||
| } |
+4
-2
@@ -7,6 +7,8 @@ #![deny(warnings)] | ||
| println!("cargo:rerun-if-changed=build.rs"); | ||
| println!("cargo:rustc-check-cfg=cfg(specialize)"); | ||
| if let Some(true) = version_check::supports_feature("specialize") { | ||
| println!("cargo:rustc-cfg=feature=\"specialize\""); | ||
| println!("cargo:rustc-cfg=specialize"); | ||
| } | ||
| let arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH was not set"); | ||
| println!("cargo:rustc-check-cfg=cfg(folded_multiply)"); | ||
| if arch.eq_ignore_ascii_case("x86_64") | ||
@@ -19,4 +21,4 @@ || arch.eq_ignore_ascii_case("aarch64") | ||
| { | ||
| println!("cargo:rustc-cfg=feature=\"folded_multiply\""); | ||
| println!("cargo:rustc-cfg=folded_multiply"); | ||
| } | ||
| } |
+27
-11
@@ -16,5 +16,5 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| name = "ahash" | ||
| version = "0.8.11" | ||
| version = "0.8.12" | ||
| authors = ["Tom Kaitchuck <Tom.Kaitchuck@gmail.com>"] | ||
| build = "./build.rs" | ||
| build = "build.rs" | ||
| exclude = [ | ||
@@ -24,2 +24,6 @@ "/smhasher", | ||
| ] | ||
| autobins = false | ||
| autoexamples = false | ||
| autotests = false | ||
| autobenches = false | ||
| description = "A non-cryptographic hash function using AES-NI for high performance" | ||
@@ -80,2 +84,14 @@ documentation = "https://docs.rs/ahash" | ||
| [[test]] | ||
| name = "bench" | ||
| path = "tests/bench.rs" | ||
| [[test]] | ||
| name = "map_tests" | ||
| path = "tests/map_tests.rs" | ||
| [[test]] | ||
| name = "nopanic" | ||
| path = "tests/nopanic.rs" | ||
| [[bench]] | ||
@@ -91,6 +107,2 @@ name = "ahash" | ||
| [dependencies.atomic-polyfill] | ||
| version = "1.0.1" | ||
| optional = true | ||
| [dependencies.cfg-if] | ||
@@ -104,5 +116,9 @@ version = "1.0" | ||
| [dependencies.getrandom] | ||
| version = "0.2.7" | ||
| version = "0.3.1" | ||
| optional = true | ||
| [dependencies.portable-atomic] | ||
| version = "1.0.0" | ||
| optional = true | ||
| [dependencies.serde] | ||
@@ -113,3 +129,3 @@ version = "1.0.117" | ||
| [dependencies.zerocopy] | ||
| version = "0.7.31" | ||
| version = "0.8.24" | ||
| features = ["simd"] | ||
@@ -157,4 +173,4 @@ default-features = false | ||
| atomic-polyfill = [ | ||
| "dep:atomic-polyfill", | ||
| "once_cell/atomic-polyfill", | ||
| "dep:portable-atomic", | ||
| "once_cell/critical-section", | ||
| ] | ||
@@ -171,5 +187,5 @@ compile-time-rng = ["const-random"] | ||
| [target."cfg(not(all(target_arch = \"arm\", target_os = \"none\")))".dependencies.once_cell] | ||
| [target.'cfg(not(all(target_arch = "arm", target_os = "none")))'.dependencies.once_cell] | ||
| version = "1.18.0" | ||
| features = ["alloc"] | ||
| default-features = false |
+8
-15
@@ -37,3 +37,3 @@ use crate::convert::*; | ||
| /// | ||
| /// ``` | ||
| /// ```no_build | ||
| /// use std::hash::Hasher; | ||
@@ -98,3 +98,3 @@ /// use ahash::AHasher; | ||
| #[inline] | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| fn short_finish(&self) -> u64 { | ||
@@ -219,3 +219,3 @@ let combined = aesenc(self.sum, self.enc); | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| pub(crate) struct AHasherU64 { | ||
@@ -227,3 +227,3 @@ pub(crate) buffer: u64, | ||
| /// A specialized hasher for only primitives under 64 bits. | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl Hasher for AHasherU64 { | ||
@@ -271,7 +271,7 @@ #[inline] | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| pub(crate) struct AHasherFixed(pub AHasher); | ||
| /// A specialized hasher for fixed size primitives larger than 64 bits. | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl Hasher for AHasherFixed { | ||
@@ -319,3 +319,3 @@ #[inline] | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| pub(crate) struct AHasherStr(pub AHasher); | ||
@@ -325,3 +325,3 @@ | ||
| /// Note that the other types don't panic because the hash impl for String tacks on an unneeded call. (As does vec) | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl Hasher for AHasherStr { | ||
@@ -433,9 +433,2 @@ #[inline] | ||
| } | ||
| #[test] | ||
| fn test_conversion() { | ||
| let input: &[u8] = "dddddddd".as_bytes(); | ||
| let bytes: u64 = as_array!(input, 8).convert(); | ||
| assert_eq!(bytes, 0x6464646464646464); | ||
| } | ||
| } |
+22
-33
@@ -22,43 +22,32 @@ pub(crate) trait Convert<To> { | ||
| convert!([u128; 4], [u64; 8]); | ||
| convert!([u128; 4], [u32; 16]); | ||
| convert!([u128; 4], [u16; 32]); | ||
| macro_rules! convert_primitive_bytes { | ||
| ($a:ty, $b:ty) => { | ||
| impl Convert<$b> for $a { | ||
| #[inline(always)] | ||
| fn convert(self) -> $b { | ||
| self.to_ne_bytes() | ||
| } | ||
| } | ||
| impl Convert<$a> for $b { | ||
| #[inline(always)] | ||
| fn convert(self) -> $a { | ||
| <$a>::from_ne_bytes(self) | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| convert!([u128; 4], [u8; 64]); | ||
| convert!([u128; 2], [u64; 4]); | ||
| convert!([u128; 2], [u32; 8]); | ||
| convert!([u128; 2], [u16; 16]); | ||
| convert!([u128; 2], [u8; 32]); | ||
| convert!(u128, [u64; 2]); | ||
| convert!(u128, [u32; 4]); | ||
| convert!(u128, [u16; 8]); | ||
| convert!(u128, [u8; 16]); | ||
| convert!([u64; 8], [u32; 16]); | ||
| convert!([u64; 8], [u16; 32]); | ||
| convert!([u64; 8], [u8; 64]); | ||
| convert!([u64; 4], [u32; 8]); | ||
| convert!([u64; 4], [u16; 16]); | ||
| convert!([u64; 4], [u8; 32]); | ||
| convert_primitive_bytes!(u128, [u8; 16]); | ||
| convert!([u64; 2], [u32; 4]); | ||
| convert!([u64; 2], [u16; 8]); | ||
| #[cfg(test)] | ||
| convert!([u64; 2], [u8; 16]); | ||
| convert!([u32; 4], [u16; 8]); | ||
| convert!([u32; 4], [u8; 16]); | ||
| convert!([u16; 8], [u8; 16]); | ||
| convert!(u64, [u32; 2]); | ||
| convert!(u64, [u16; 4]); | ||
| convert!(u64, [u8; 8]); | ||
| convert!([u32; 2], [u16; 4]); | ||
| convert!([u32; 2], [u8; 8]); | ||
| convert!(u32, [u16; 2]); | ||
| convert!(u32, [u8; 4]); | ||
| convert!([u16; 2], [u8; 4]); | ||
| convert!(u16, [u8; 2]); | ||
| convert_primitive_bytes!(u64, [u8; 8]); | ||
| convert_primitive_bytes!(u32, [u8; 4]); | ||
| convert_primitive_bytes!(u16, [u8; 2]); | ||
| convert!([[u64; 4]; 2], [u8; 64]); | ||
| convert!([f64; 2], [u8; 16]); | ||
| convert!([f32; 4], [u8; 16]); | ||
| convert!(f64, [u8; 8]); | ||
| convert!([f32; 2], [u8; 8]); | ||
| convert!(f32, [u8; 4]); | ||
| macro_rules! as_array { | ||
@@ -65,0 +54,0 @@ ($input:expr, $len:expr) => {{ |
+7
-14
@@ -118,3 +118,3 @@ use crate::convert::*; | ||
| #[inline] | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| fn short_finish(&self) -> u64 { | ||
@@ -203,3 +203,3 @@ folded_multiply(self.buffer, self.pad) | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| pub(crate) struct AHasherU64 { | ||
@@ -211,3 +211,3 @@ pub(crate) buffer: u64, | ||
| /// A specialized hasher for only primitives under 64 bits. | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl Hasher for AHasherU64 { | ||
@@ -256,7 +256,7 @@ #[inline] | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| pub(crate) struct AHasherFixed(pub AHasher); | ||
| /// A specialized hasher for fixed size primitives larger than 64 bits. | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl Hasher for AHasherFixed { | ||
@@ -304,3 +304,3 @@ #[inline] | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| pub(crate) struct AHasherStr(pub AHasher); | ||
@@ -310,3 +310,3 @@ | ||
| /// Note that the other types don't panic because the hash impl for String tacks on an unneeded call. (As does vec) | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl Hasher for AHasherStr { | ||
@@ -366,9 +366,2 @@ #[inline] | ||
| } | ||
| #[test] | ||
| fn test_conversion() { | ||
| let input: &[u8] = "dddddddd".as_bytes(); | ||
| let bytes: u64 = as_array!(input, 8).convert(); | ||
| assert_eq!(bytes, 0x6464646464646464); | ||
| } | ||
| } |
+4
-4
@@ -54,3 +54,3 @@ use std::borrow::Borrow; | ||
| impl<K, V> AHashMap<K, V, RandomState> { | ||
| /// This crates a hashmap using [RandomState::new] which obtains its keys from [RandomSource]. | ||
| /// This creates a hashmap using [RandomState::new] which obtains its keys from [RandomSource]. | ||
| /// See the documentation in [RandomSource] for notes about key strength. | ||
@@ -61,3 +61,3 @@ pub fn new() -> Self { | ||
| /// This crates a hashmap with the specified capacity using [RandomState::new]. | ||
| /// This creates a hashmap with the specified capacity using [RandomState::new]. | ||
| /// See the documentation in [RandomSource] for notes about key strength. | ||
@@ -353,3 +353,3 @@ pub fn with_capacity(capacity: usize) -> Self { | ||
| { | ||
| /// This crates a hashmap from the provided iterator using [RandomState::new]. | ||
| /// This creates a hashmap from the provided iterator using [RandomState::new]. | ||
| /// See the documentation in [RandomSource] for notes about key strength. | ||
@@ -410,3 +410,3 @@ fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self { | ||
| /// NOTE: For safety this trait impl is only available available if either of the flags `runtime-rng` (on by default) or | ||
| /// NOTE: For safety this trait impl is only available if either of the flags `runtime-rng` (on by default) or | ||
| /// `compile-time-rng` are enabled. This is to prevent weakly keyed maps from being accidentally created. Instead one of | ||
@@ -413,0 +413,0 @@ /// constructors for [RandomState] must be used. |
@@ -73,4 +73,4 @@ use core::hash::{Hash, Hasher}; | ||
| for combination in combinations { | ||
| use zerocopy::AsBytes; | ||
| let array = combination.as_slice().as_bytes().to_vec(); | ||
| use zerocopy::IntoBytes; | ||
| let array = combination.as_bytes().to_vec(); | ||
| let mut hasher = gen_hash(); | ||
@@ -411,3 +411,3 @@ hasher.write(&array); | ||
| //For fallback second key is not used in every hash. | ||
| #[cfg(all(not(feature = "specialize"), feature = "folded_multiply"))] | ||
| #[cfg(all(not(specialize), folded_multiply))] | ||
| test_keys_affect_every_byte(0, |a, b| AHasher::new_with_keys(a ^ b, a)); | ||
@@ -446,3 +446,3 @@ test_keys_affect_every_byte("", |a, b| AHasher::new_with_keys(a ^ b, a)); | ||
| all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)), | ||
| all(target_arch = "aarch64", target_feature = "aes", not(miri)), | ||
| all(feature = "nightly-arm-aes", target_arch = "aarch64", target_feature = "aes", not(miri)), | ||
| all(feature = "nightly-arm-aes", target_arch = "arm", target_feature = "aes", not(miri)), | ||
@@ -510,3 +510,3 @@ ))] | ||
| fn aes_keys_affect_every_byte() { | ||
| #[cfg(not(feature = "specialize"))] | ||
| #[cfg(not(specialize))] | ||
| test_keys_affect_every_byte(0, AHasher::test_with_keys); | ||
@@ -513,0 +513,0 @@ test_keys_affect_every_byte("", AHasher::test_with_keys); |
+3
-3
@@ -50,3 +50,3 @@ use crate::RandomState; | ||
| impl<T> AHashSet<T, RandomState> { | ||
| /// This crates a hashset using [RandomState::new]. | ||
| /// This creates a hashset using [RandomState::new]. | ||
| /// See the documentation in [RandomSource] for notes about key strength. | ||
@@ -57,3 +57,3 @@ pub fn new() -> Self { | ||
| /// This crates a hashset with the specified capacity using [RandomState::new]. | ||
| /// This craetes a hashset with the specified capacity using [RandomState::new]. | ||
| /// See the documentation in [RandomSource] for notes about key strength. | ||
@@ -250,3 +250,3 @@ pub fn with_capacity(capacity: usize) -> Self { | ||
| { | ||
| /// This crates a hashset from the provided iterator using [RandomState::new]. | ||
| /// This creates a hashset from the provided iterator using [RandomState::new]. | ||
| /// See the documentation in [RandomSource] for notes about key strength. | ||
@@ -253,0 +253,0 @@ #[inline] |
+23
-61
@@ -37,3 +37,3 @@ //! AHash is a high performance keyed hash function. | ||
| ### If randomess is not available | ||
| ### If randomness is not available | ||
@@ -101,3 +101,3 @@ [AHasher::default()] can be used to hash using fixed keys. This works with | ||
| #![cfg_attr(all(not(test), not(feature = "std")), no_std)] | ||
| #![cfg_attr(feature = "specialize", feature(min_specialization))] | ||
| #![cfg_attr(specialize, feature(min_specialization))] | ||
| #![cfg_attr(feature = "nightly-arm-aes", feature(stdarch_arm_neon_intrinsics))] | ||
@@ -151,4 +151,2 @@ | ||
| use core::hash::BuildHasher; | ||
| use core::hash::Hash; | ||
| use core::hash::Hasher; | ||
@@ -254,59 +252,2 @@ #[cfg(feature = "std")] | ||
| /// Used for specialization. (Sealed) | ||
| pub(crate) trait BuildHasherExt: BuildHasher { | ||
| #[doc(hidden)] | ||
| fn hash_as_u64<T: Hash + ?Sized>(&self, value: &T) -> u64; | ||
| #[doc(hidden)] | ||
| fn hash_as_fixed_length<T: Hash + ?Sized>(&self, value: &T) -> u64; | ||
| #[doc(hidden)] | ||
| fn hash_as_str<T: Hash + ?Sized>(&self, value: &T) -> u64; | ||
| } | ||
| impl<B: BuildHasher> BuildHasherExt for B { | ||
| #[inline] | ||
| #[cfg(feature = "specialize")] | ||
| default fn hash_as_u64<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| let mut hasher = self.build_hasher(); | ||
| value.hash(&mut hasher); | ||
| hasher.finish() | ||
| } | ||
| #[inline] | ||
| #[cfg(not(feature = "specialize"))] | ||
| fn hash_as_u64<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| let mut hasher = self.build_hasher(); | ||
| value.hash(&mut hasher); | ||
| hasher.finish() | ||
| } | ||
| #[inline] | ||
| #[cfg(feature = "specialize")] | ||
| default fn hash_as_fixed_length<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| let mut hasher = self.build_hasher(); | ||
| value.hash(&mut hasher); | ||
| hasher.finish() | ||
| } | ||
| #[inline] | ||
| #[cfg(not(feature = "specialize"))] | ||
| fn hash_as_fixed_length<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| let mut hasher = self.build_hasher(); | ||
| value.hash(&mut hasher); | ||
| hasher.finish() | ||
| } | ||
| #[inline] | ||
| #[cfg(feature = "specialize")] | ||
| default fn hash_as_str<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| let mut hasher = self.build_hasher(); | ||
| value.hash(&mut hasher); | ||
| hasher.finish() | ||
| } | ||
| #[inline] | ||
| #[cfg(not(feature = "specialize"))] | ||
| fn hash_as_str<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| let mut hasher = self.build_hasher(); | ||
| value.hash(&mut hasher); | ||
| hasher.finish() | ||
| } | ||
| } | ||
| // #[inline(never)] | ||
@@ -325,2 +266,4 @@ // #[doc(hidden)] | ||
| use crate::*; | ||
| use core::hash::Hash; | ||
| use core::hash::Hasher; | ||
| use std::collections::HashMap; | ||
@@ -401,2 +344,21 @@ | ||
| } | ||
| #[test] | ||
| fn test_specialize_reference_hash() { | ||
| let hasher_build = RandomState::with_seeds(0, 0, 0, 0); | ||
| let h1 = hasher_build.hash_one(1u64); | ||
| let h2 = hasher_build.hash_one(&1u64); | ||
| assert_eq!(h1, h2); | ||
| let h1 = u64::get_hash(&1_u64, &hasher_build); | ||
| let h2 = <&u64>::get_hash(&&1_u64, &hasher_build); | ||
| assert_eq!(h1, h2); | ||
| let h1 = hasher_build.hash_one(1u128); | ||
| let h2 = hasher_build.hash_one(&1u128); | ||
| assert_eq!(h1, h2); | ||
| } | ||
| } |
@@ -16,3 +16,3 @@ use crate::convert::*; | ||
| #[inline(always)] | ||
| #[cfg(feature = "folded_multiply")] | ||
| #[cfg(folded_multiply)] | ||
| pub(crate) const fn folded_multiply(s: u64, by: u64) -> u64 { | ||
@@ -24,3 +24,3 @@ let result = (s as u128).wrapping_mul(by as u128); | ||
| #[inline(always)] | ||
| #[cfg(not(feature = "folded_multiply"))] | ||
| #[cfg(not(folded_multiply))] | ||
| pub(crate) const fn folded_multiply(s: u64, by: u64) -> u64 { | ||
@@ -369,7 +369,9 @@ let b1 = s.wrapping_mul(by.swap_bytes()); | ||
| fn test_add_length() { | ||
| let mut enc = (u64::MAX as u128) << 64 | 50; | ||
| let enc : [u64; 2] = [50, u64::MAX]; | ||
| let mut enc : u128 = enc.convert(); | ||
| add_in_length(&mut enc, u64::MAX); | ||
| assert_eq!(enc >> 64, u64::MAX as u128); | ||
| assert_eq!(enc as u64, 49); | ||
| let enc : [u64; 2] = enc.convert(); | ||
| assert_eq!(enc[1], u64::MAX); | ||
| assert_eq!(enc[0], 49); | ||
| } | ||
| } |
+12
-17
@@ -14,7 +14,2 @@ use core::hash::Hash; | ||
| cfg_if::cfg_if! { | ||
| if #[cfg(feature = "specialize")]{ | ||
| use crate::BuildHasherExt; | ||
| } | ||
| } | ||
| cfg_if::cfg_if! { | ||
| if #[cfg(feature = "std")] { | ||
@@ -28,3 +23,3 @@ extern crate std as alloc; | ||
| #[cfg(feature = "atomic-polyfill")] | ||
| use atomic_polyfill as atomic; | ||
| use portable_atomic as atomic; | ||
| #[cfg(not(feature = "atomic-polyfill"))] | ||
@@ -84,3 +79,3 @@ use core::sync::atomic; | ||
| let mut result: [u8; 64] = [0; 64]; | ||
| getrandom::getrandom(&mut result).expect("getrandom::getrandom() failed."); | ||
| getrandom::fill(&mut result).expect("getrandom::fill() failed."); | ||
| Box::new(result.convert()) | ||
@@ -400,12 +395,12 @@ }) | ||
| use std::hash::{Hasher, BuildHasher}; | ||
| let build_hasher = RandomState::new(); | ||
| let mut hasher_1 = build_hasher.build_hasher(); | ||
| let mut hasher_2 = build_hasher.build_hasher(); | ||
| hasher_1.write_u32(1234); | ||
| hasher_2.write_u32(1234); | ||
| assert_eq!(hasher_1.finish(), hasher_2.finish()); | ||
| let other_build_hasher = RandomState::new(); | ||
@@ -465,3 +460,3 @@ let mut different_hasher = other_build_hasher.build_hasher(); | ||
| /// [`Hasher`], not to call this method repeatedly and combine the results. | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| #[inline] | ||
@@ -473,6 +468,6 @@ fn hash_one<T: Hash>(&self, x: T) -> u64 { | ||
| #[cfg(feature = "specialize")] | ||
| impl BuildHasherExt for RandomState { | ||
| #[cfg(specialize)] | ||
| impl RandomState { | ||
| #[inline] | ||
| fn hash_as_u64<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| pub(crate) fn hash_as_u64<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| let mut hasher = AHasherU64 { | ||
@@ -487,3 +482,3 @@ buffer: self.k1, | ||
| #[inline] | ||
| fn hash_as_fixed_length<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| pub(crate) fn hash_as_fixed_length<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| let mut hasher = AHasherFixed(self.build_hasher()); | ||
@@ -495,3 +490,3 @@ value.hash(&mut hasher); | ||
| #[inline] | ||
| fn hash_as_str<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| pub(crate) fn hash_as_str<T: Hash + ?Sized>(&self, value: &T) -> u64 { | ||
| let mut hasher = AHasherStr(self.build_hasher()); | ||
@@ -498,0 +493,0 @@ value.hash(&mut hasher); |
+63
-67
@@ -0,1 +1,2 @@ | ||
| use crate::RandomState; | ||
| use core::hash::BuildHasher; | ||
@@ -10,7 +11,5 @@ use core::hash::Hash; | ||
| #[cfg(feature = "specialize")] | ||
| use crate::BuildHasherExt; | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| use alloc::string::String; | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| use alloc::vec::Vec; | ||
@@ -22,6 +21,6 @@ | ||
| pub(crate) trait CallHasher { | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64; | ||
| fn get_hash<H: Hash + ?Sized>(value: &H, random_state: &RandomState) -> u64; | ||
| } | ||
| #[cfg(not(feature = "specialize"))] | ||
| #[cfg(not(specialize))] | ||
| impl<T> CallHasher for T | ||
@@ -32,4 +31,4 @@ where | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| let mut hasher = build_hasher.build_hasher(); | ||
| fn get_hash<H: Hash + ?Sized>(value: &H, random_state: &RandomState) -> u64 { | ||
| let mut hasher = random_state.build_hasher(); | ||
| value.hash(&mut hasher); | ||
@@ -40,3 +39,3 @@ hasher.finish() | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl<T> CallHasher for T | ||
@@ -47,4 +46,4 @@ where | ||
| #[inline] | ||
| default fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| let mut hasher = build_hasher.build_hasher(); | ||
| default fn get_hash<H: Hash + ?Sized>(value: &H, random_state: &RandomState) -> u64 { | ||
| let mut hasher = random_state.build_hasher(); | ||
| value.hash(&mut hasher); | ||
@@ -55,9 +54,9 @@ hasher.finish() | ||
| macro_rules! call_hasher_impl { | ||
| macro_rules! call_hasher_impl_u64 { | ||
| ($typ:ty) => { | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl CallHasher for $typ { | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| build_hasher.hash_as_u64(value) | ||
| fn get_hash<H: Hash + ?Sized>(value: &H, random_state: &RandomState) -> u64 { | ||
| random_state.hash_as_u64(value) | ||
| } | ||
@@ -67,72 +66,69 @@ } | ||
| } | ||
| call_hasher_impl!(u8); | ||
| call_hasher_impl!(u16); | ||
| call_hasher_impl!(u32); | ||
| call_hasher_impl!(u64); | ||
| call_hasher_impl!(i8); | ||
| call_hasher_impl!(i16); | ||
| call_hasher_impl!(i32); | ||
| call_hasher_impl!(i64); | ||
| call_hasher_impl_u64!(u8); | ||
| call_hasher_impl_u64!(u16); | ||
| call_hasher_impl_u64!(u32); | ||
| call_hasher_impl_u64!(u64); | ||
| call_hasher_impl_u64!(i8); | ||
| call_hasher_impl_u64!(i16); | ||
| call_hasher_impl_u64!(i32); | ||
| call_hasher_impl_u64!(i64); | ||
| call_hasher_impl_u64!(&u8); | ||
| call_hasher_impl_u64!(&u16); | ||
| call_hasher_impl_u64!(&u32); | ||
| call_hasher_impl_u64!(&u64); | ||
| call_hasher_impl_u64!(&i8); | ||
| call_hasher_impl_u64!(&i16); | ||
| call_hasher_impl_u64!(&i32); | ||
| call_hasher_impl_u64!(&i64); | ||
| #[cfg(feature = "specialize")] | ||
| impl CallHasher for u128 { | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| build_hasher.hash_as_fixed_length(value) | ||
| } | ||
| macro_rules! call_hasher_impl_fixed_length{ | ||
| ($typ:ty) => { | ||
| #[cfg(specialize)] | ||
| impl CallHasher for $typ { | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized>(value: &H, random_state: &RandomState) -> u64 { | ||
| random_state.hash_as_fixed_length(value) | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| #[cfg(feature = "specialize")] | ||
| impl CallHasher for i128 { | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| build_hasher.hash_as_fixed_length(value) | ||
| } | ||
| } | ||
| call_hasher_impl_fixed_length!(u128); | ||
| call_hasher_impl_fixed_length!(i128); | ||
| call_hasher_impl_fixed_length!(usize); | ||
| call_hasher_impl_fixed_length!(isize); | ||
| call_hasher_impl_fixed_length!(&u128); | ||
| call_hasher_impl_fixed_length!(&i128); | ||
| call_hasher_impl_fixed_length!(&usize); | ||
| call_hasher_impl_fixed_length!(&isize); | ||
| #[cfg(feature = "specialize")] | ||
| impl CallHasher for usize { | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| build_hasher.hash_as_fixed_length(value) | ||
| } | ||
| } | ||
| #[cfg(feature = "specialize")] | ||
| impl CallHasher for isize { | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| build_hasher.hash_as_fixed_length(value) | ||
| } | ||
| } | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl CallHasher for [u8] { | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| build_hasher.hash_as_str(value) | ||
| fn get_hash<H: Hash + ?Sized>(value: &H, random_state: &RandomState) -> u64 { | ||
| random_state.hash_as_str(value) | ||
| } | ||
| } | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl CallHasher for Vec<u8> { | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| build_hasher.hash_as_str(value) | ||
| fn get_hash<H: Hash + ?Sized>(value: &H, random_state: &RandomState) -> u64 { | ||
| random_state.hash_as_str(value) | ||
| } | ||
| } | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| impl CallHasher for str { | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| build_hasher.hash_as_str(value) | ||
| fn get_hash<H: Hash + ?Sized>(value: &H, random_state: &RandomState) -> u64 { | ||
| random_state.hash_as_str(value) | ||
| } | ||
| } | ||
| #[cfg(all(feature = "specialize"))] | ||
| #[cfg(all(specialize))] | ||
| impl CallHasher for String { | ||
| #[inline] | ||
| fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 { | ||
| build_hasher.hash_as_str(value) | ||
| fn get_hash<H: Hash + ?Sized>(value: &H, random_state: &RandomState) -> u64 { | ||
| random_state.hash_as_str(value) | ||
| } | ||
@@ -147,3 +143,3 @@ } | ||
| #[test] | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| pub fn test_specialized_invoked() { | ||
@@ -200,3 +196,3 @@ let build_hasher = RandomState::with_seeds(1, 2, 3, 4); | ||
| ); | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| assert_eq!( | ||
@@ -221,3 +217,3 @@ str::get_hash(&"test", &build_hasher), | ||
| ); | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| assert_eq!( | ||
@@ -224,0 +220,0 @@ str::get_hash(&&"test", &build_hasher), |
+1
-1
@@ -1,2 +0,2 @@ | ||
| #![cfg_attr(feature = "specialize", feature(build_hasher_simple_hash_one))] | ||
| #![cfg_attr(specialize, feature(build_hasher_simple_hash_one))] | ||
@@ -3,0 +3,0 @@ use ahash::{AHasher, RandomState}; |
@@ -1,2 +0,2 @@ | ||
| #![cfg_attr(feature = "specialize", feature(build_hasher_simple_hash_one))] | ||
| #![cfg_attr(specialize, feature(build_hasher_simple_hash_one))] | ||
@@ -154,3 +154,3 @@ use std::hash::{BuildHasher, Hash, Hasher}; | ||
| #[cfg(feature = "specialize")] | ||
| #[cfg(specialize)] | ||
| #[allow(unused)] // False positive | ||
@@ -161,3 +161,3 @@ fn hash<H: Hash, B: BuildHasher>(b: &H, build_hasher: &B) -> u64 { | ||
| #[cfg(not(feature = "specialize"))] | ||
| #[cfg(not(specialize))] | ||
| #[allow(unused)] // False positive | ||
@@ -164,0 +164,0 @@ fn hash<H: Hash, B: BuildHasher>(b: &H, build_hasher: &B) -> u64 { |
Sorry, the diff of this file is not supported yet