11use crate :: RandomState ;
2+ use core:: any:: TypeId ;
23use core:: hash:: BuildHasher ;
34use core:: hash:: Hash ;
45use core:: hash:: Hasher ;
@@ -8,122 +9,70 @@ extern crate alloc;
89#[ cfg( feature = "std" ) ]
910extern crate std as alloc;
1011
11- #[ cfg( feature = "specialize" ) ]
1212use alloc:: string:: String ;
13- #[ cfg( feature = "specialize" ) ]
1413use alloc:: vec:: Vec ;
1514
15+ #[ inline]
16+ fn is < Generic , Expected > ( ) -> bool
17+ where
18+ Generic : ?Sized ,
19+ Expected : ?Sized + ' static ,
20+ {
21+ typeid:: of :: < Generic > ( ) == TypeId :: of :: < Expected > ( )
22+ }
23+
1624/// Provides a way to get an optimized hasher for a given data type.
1725/// Rather than using a Hasher generically which can hash any value, this provides a way to get a specialized hash
1826/// for a specific type. So this may be faster for primitive types.
1927pub ( crate ) trait CallHasher {
2028 fn get_hash < H : Hash + ?Sized > ( value : & H , random_state : & RandomState ) -> u64 ;
2129}
2230
23- #[ cfg( not( feature = "specialize" ) ) ]
2431impl < T > CallHasher for T
2532where
2633 T : Hash + ?Sized ,
2734{
2835 #[ inline]
2936 fn get_hash < H : Hash + ?Sized > ( value : & H , random_state : & RandomState ) -> u64 {
30- let mut hasher = random_state. build_hasher ( ) ;
31- value. hash ( & mut hasher) ;
32- hasher. finish ( )
33- }
34- }
35-
36- #[ cfg( feature = "specialize" ) ]
37- impl < T > CallHasher for T
38- where
39- T : Hash + ?Sized ,
40- {
41- #[ inline]
42- default fn get_hash < H : Hash + ?Sized > ( value : & H , random_state : & RandomState ) -> u64 {
43- let mut hasher = random_state. build_hasher ( ) ;
44- value. hash ( & mut hasher) ;
45- hasher. finish ( )
46- }
47- }
48-
49- macro_rules! call_hasher_impl_u64 {
50- ( $typ: ty) => {
51- #[ cfg( feature = "specialize" ) ]
52- impl CallHasher for $typ {
53- #[ inline]
54- fn get_hash<H : Hash + ?Sized >( value: & H , random_state: & RandomState ) -> u64 {
55- random_state. hash_as_u64( value)
56- }
57- }
58- } ;
59- }
60- call_hasher_impl_u64 ! ( u8 ) ;
61- call_hasher_impl_u64 ! ( u16 ) ;
62- call_hasher_impl_u64 ! ( u32 ) ;
63- call_hasher_impl_u64 ! ( u64 ) ;
64- call_hasher_impl_u64 ! ( i8 ) ;
65- call_hasher_impl_u64 ! ( i16 ) ;
66- call_hasher_impl_u64 ! ( i32 ) ;
67- call_hasher_impl_u64 ! ( i64 ) ;
68- call_hasher_impl_u64 ! ( & u8 ) ;
69- call_hasher_impl_u64 ! ( & u16 ) ;
70- call_hasher_impl_u64 ! ( & u32 ) ;
71- call_hasher_impl_u64 ! ( & u64 ) ;
72- call_hasher_impl_u64 ! ( & i8 ) ;
73- call_hasher_impl_u64 ! ( & i16 ) ;
74- call_hasher_impl_u64 ! ( & i32 ) ;
75- call_hasher_impl_u64 ! ( & i64 ) ;
76-
77- macro_rules! call_hasher_impl_fixed_length{
78- ( $typ: ty) => {
79- #[ cfg( feature = "specialize" ) ]
80- impl CallHasher for $typ {
81- #[ inline]
82- fn get_hash<H : Hash + ?Sized >( value: & H , random_state: & RandomState ) -> u64 {
83- random_state. hash_as_fixed_length( value)
84- }
37+ if is :: < T , u8 > ( )
38+ || is :: < T , u16 > ( )
39+ || is :: < T , u32 > ( )
40+ || is :: < T , u64 > ( )
41+ || is :: < T , i8 > ( )
42+ || is :: < T , i16 > ( )
43+ || is :: < T , i32 > ( )
44+ || is :: < T , i64 > ( )
45+ || is :: < T , & u8 > ( )
46+ || is :: < T , & u16 > ( )
47+ || is :: < T , & u32 > ( )
48+ || is :: < T , & u64 > ( )
49+ || is :: < T , & i8 > ( )
50+ || is :: < T , & i16 > ( )
51+ || is :: < T , & i32 > ( )
52+ || is :: < T , & i64 > ( )
53+ {
54+ random_state. hash_as_u64 ( value)
55+ } else if is :: < T , u128 > ( )
56+ || is :: < T , i128 > ( )
57+ || is :: < T , usize > ( )
58+ || is :: < T , isize > ( )
59+ || is :: < T , & u128 > ( )
60+ || is :: < T , & i128 > ( )
61+ || is :: < T , & usize > ( )
62+ || is :: < T , & isize > ( )
63+ {
64+ random_state. hash_as_fixed_length ( value)
65+ } else if is :: < T , [ u8 ] > ( )
66+ || is :: < T , Vec < u8 > > ( )
67+ || is :: < T , str > ( )
68+ || is :: < T , String > ( )
69+ {
70+ random_state. hash_as_str ( value)
71+ } else {
72+ let mut hasher = random_state. build_hasher ( ) ;
73+ value. hash ( & mut hasher) ;
74+ hasher. finish ( )
8575 }
86- } ;
87- }
88-
89- call_hasher_impl_fixed_length ! ( u128 ) ;
90- call_hasher_impl_fixed_length ! ( i128 ) ;
91- call_hasher_impl_fixed_length ! ( usize ) ;
92- call_hasher_impl_fixed_length ! ( isize ) ;
93- call_hasher_impl_fixed_length ! ( & u128 ) ;
94- call_hasher_impl_fixed_length ! ( & i128 ) ;
95- call_hasher_impl_fixed_length ! ( & usize ) ;
96- call_hasher_impl_fixed_length ! ( & isize ) ;
97-
98- #[ cfg( feature = "specialize" ) ]
99- impl CallHasher for [ u8 ] {
100- #[ inline]
101- fn get_hash < H : Hash + ?Sized > ( value : & H , random_state : & RandomState ) -> u64 {
102- random_state. hash_as_str ( value)
103- }
104- }
105-
106- #[ cfg( feature = "specialize" ) ]
107- impl CallHasher for Vec < u8 > {
108- #[ inline]
109- fn get_hash < H : Hash + ?Sized > ( value : & H , random_state : & RandomState ) -> u64 {
110- random_state. hash_as_str ( value)
111- }
112- }
113-
114- #[ cfg( feature = "specialize" ) ]
115- impl CallHasher for str {
116- #[ inline]
117- fn get_hash < H : Hash + ?Sized > ( value : & H , random_state : & RandomState ) -> u64 {
118- random_state. hash_as_str ( value)
119- }
120- }
121-
122- #[ cfg( all( feature = "specialize" ) ) ]
123- impl CallHasher for String {
124- #[ inline]
125- fn get_hash < H : Hash + ?Sized > ( value : & H , random_state : & RandomState ) -> u64 {
126- random_state. hash_as_str ( value)
12776 }
12877}
12978
0 commit comments