1use std::num::Wrapping;
2use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
3use std::ffi::OsStr;
4use std::hash::{BuildHasher, Hash};
5#[cfg(unix)]
6use std::os::unix::ffi::OsStrExt;
7#[cfg(windows)]
8use std::os::windows::ffi::OsStrExt;
9use std::path::Path;
10
11pub trait HashCode {
13 fn hash_code(&self) -> i32;
17}
18
19impl<T: HashCode> HashCode for &T {
20 fn hash_code(&self) -> i32 {
21 <T>::hash_code(self)
22 }
23}
24impl<T: HashCode> HashCode for &mut T {
25 fn hash_code(&self) -> i32 {
26 <T>::hash_code(self)
27 }
28}
29impl<T: HashCode> HashCode for Box<T> {
30 fn hash_code(&self) -> i32 {
31 <T>::hash_code(self)
32 }
33}
34impl<T> HashCode for *const T {
35 fn hash_code(&self) -> i32 {
36 (*self as usize).hash_code()
37 }
38}
39impl<T> HashCode for *mut T {
40 fn hash_code(&self) -> i32 {
41 (*self as usize).hash_code()
42 }
43}
44impl<Ret> HashCode for fn() -> Ret {
45 fn hash_code(&self) -> i32 {
46 (*self as usize).hash_code()
47 }
48}
49impl<Ret, A> HashCode for fn(A) -> Ret {
50 fn hash_code(&self) -> i32 {
51 (*self as usize).hash_code()
52 }
53}
54impl<Ret, A, B> HashCode for fn(A, B) -> Ret {
55 fn hash_code(&self) -> i32 {
56 (*self as usize).hash_code()
57 }
58}
59impl<Ret, A, B, C> HashCode for fn(A, B, C) -> Ret {
60 fn hash_code(&self) -> i32 {
61 (*self as usize).hash_code()
62 }
63}
64impl<Ret, A, B, C, D> HashCode for fn(A, B, C, D) -> Ret {
65 fn hash_code(&self) -> i32 {
66 (*self as usize).hash_code()
67 }
68}
69impl<Ret, A, B, C, D, E> HashCode for fn(A, B, C, D, E) -> Ret {
70 fn hash_code(&self) -> i32 {
71 (*self as usize).hash_code()
72 }
73}
74impl<Ret, A, B, C, D, E, F> HashCode for fn(A, B, C, D, E, F) -> Ret {
75 fn hash_code(&self) -> i32 {
76 (*self as usize).hash_code()
77 }
78}
79impl HashCode for () {
80 fn hash_code(&self) -> i32 {
81 0
82 }
83}
84impl<T: HashCode> HashCode for Option<&T> {
85 fn hash_code(&self) -> i32 {
86 self.map(|e| e.hash_code()).unwrap_or(0)
87 }
88}
89impl<T: HashCode, U: HashCode> HashCode for (T, U) {
90 fn hash_code(&self) -> i32 {
91 self.0.hash_code() ^ self.1.hash_code()
92 }
93}
94
95macro_rules! impl_for_iterable {
96 ($($type:ty:[ $( $i:tt: $($t:ident),*);+ ] )*) => (
97 $(
98 impl< $( $i: $($t+)* ),* > HashCode for $type {
99 fn hash_code(&self) -> i32 {
100 self.iter()
101 .fold(1, |hash_code, e| 31*hash_code + e.hash_code())
102 }
103 }
104 )*
105 );
106}
107
108impl_for_iterable!(&[T]:[T: HashCode]);
109
110impl_for_iterable! {
113 Vec<T>:[T: HashCode]
114 VecDeque<T>:[T: HashCode]
115 LinkedList<T>:[T: HashCode]
116 HashMap<K, V, H>:[K: HashCode, Eq, Hash; V: HashCode; H: BuildHasher]
117 BTreeMap<K, V>:[K: HashCode, Eq; V: HashCode]
118 HashSet<T, H>:[T: HashCode, Eq, Hash; H: BuildHasher]
119 BTreeSet<T>:[T: HashCode]
120 BinaryHeap<T>:[T: HashCode, Ord]
121}
122mod wrapping_pow;
125use self::wrapping_pow::WrapPow;
126
127impl HashCode for str {
128 fn hash_code(&self) -> i32 {
129 let n = self.chars().count() as u32;
130 self.chars()
131 .enumerate()
132 .map(|(i, c)| (i as u32, c as i32))
133 .map(|(i, c)| Wrapping(c.wrapping_mul(31i32.wrap_pow(n - i - 1))))
134 .sum::<Wrapping<_>>().0
135 }
136}
137
138#[cfg(windows)]
139impl HashCode for OsStr {
140 fn hash_code(&self) -> i32 {
141 let n = self.encode_wide().count() as u32;
142 self.encode_wide()
143 .enumerate()
144 .map(|(i, c)| (i as u32, i32::from(c)))
145 .map(|(i, c)| Wrapping(c.wrapping_mul(31i32.wrap_pow(n - i - 1))))
146 .sum::<Wrapping<_>>().0
147 }
148}
149#[cfg(unix)]
150impl HashCode for OsStr {
151 fn hash_code(&self) -> i32 {
152 self.as_bytes().hash_code()
153 }
154}
155
156#[cfg(any(unix, windows))]
157impl HashCode for Path {
158 fn hash_code(&self) -> i32 {
159 self.as_os_str().hash_code()
160 }
161}
162
163macro_rules! impl_for_prim_signed {
164 ($($type:ty)*) => (
165 $(
166 impl HashCode for $type {
167 fn hash_code(&self) -> i32 {
168 i32::from(*self)
169 }
170 }
171 )*
172 );
173}
174
175macro_rules! impl_for_prim_unsigned {
176 ($($u:ty, $i:ty)*) => (
177 $(
178 impl HashCode for $u {
179 fn hash_code(&self) -> i32 {
180 (*self as $i).hash_code()
181 }
182 }
183 )*
184 );
185}
186
187impl_for_prim_signed! {
188 i8
189 i16
190 i32
191}
192
193impl_for_prim_unsigned! {
194 u8, i8
195 u16, i16
196 u32, i32
197 u64, i64
198}
199
200impl HashCode for bool {
201 fn hash_code(&self) -> i32 {
202 if *self {
203 1231
204 } else {
205 1237
206 }
207 }
208}
209
210impl HashCode for char {
211 fn hash_code(&self) -> i32 {
212 *self as i32
213 }
214}
215
216impl HashCode for f32 {
217 fn hash_code(&self) -> i32 {
218 self.to_bits() as i32
219 }
220}
221
222impl HashCode for f64 {
223 fn hash_code(&self) -> i32 {
224 self.to_bits().hash_code()
225 }
226}
227
228impl HashCode for i64 {
229 fn hash_code(&self) -> i32 {
230 (*self ^ (*self >> 32)) as i32
231 }
232}
233
234#[cfg(target_pointer_width = "64")]
235impl HashCode for isize {
236 fn hash_code(&self) -> i32 {
237 (*self as u64).hash_code()
238 }
239}
240#[cfg(target_pointer_width = "64")]
241impl HashCode for usize {
242 fn hash_code(&self) -> i32 {
243 (*self as u64).hash_code()
244 }
245}
246#[cfg(not(target_pointer_width = "64"))]
247impl HashCode for isize {
248 fn hash_code(&self) -> i32 {
249 *self as i32
250 }
251}
252#[cfg(not(target_pointer_width = "64"))]
253impl HashCode for usize {
254 fn hash_code(&self) -> i32 {
255 *self as i32
256 }
257}