1#![cfg_attr(not(feature = "std"), no_std)]
13
14use core::{
17 fmt,
18 hash::{BuildHasherDefault, Hasher},
19 marker::PhantomData,
20};
21
22#[cfg(feature = "std")]
40pub type IntMap<K, V> = std::collections::HashMap<K, V, BuildIdentityHasher<K>>;
41
42#[cfg(feature = "std")]
60pub type IntSet<T> = std::collections::HashSet<T, BuildIdentityHasher<T>>;
61
62pub type BuildIdentityHasher<T> = BuildHasherDefault<IdentityHasher<T>>;
82
83#[cfg(debug_assertions)]
114pub struct IdentityHasher<T>(u64, bool, PhantomData<T>);
115
116#[cfg(not(debug_assertions))]
117pub struct IdentityHasher<T>(u64, PhantomData<T>);
118
119impl<T> fmt::Debug for IdentityHasher<T> {
120 #[cfg(debug_assertions)]
121 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122 f.debug_tuple("IdentityHasher")
123 .field(&self.0)
124 .field(&self.1)
125 .finish()
126 }
127
128 #[cfg(not(debug_assertions))]
129 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
130 f.debug_tuple("IdentityHasher").field(&self.0).finish()
131 }
132}
133
134impl<T> Default for IdentityHasher<T> {
135 #[cfg(debug_assertions)]
136 fn default() -> Self {
137 IdentityHasher(0, false, PhantomData)
138 }
139
140 #[cfg(not(debug_assertions))]
141 fn default() -> Self {
142 IdentityHasher(0, PhantomData)
143 }
144}
145
146impl<T> Clone for IdentityHasher<T> {
147 #[cfg(debug_assertions)]
148 fn clone(&self) -> Self {
149 IdentityHasher(self.0, self.1, self.2)
150 }
151
152 #[cfg(not(debug_assertions))]
153 fn clone(&self) -> Self {
154 IdentityHasher(self.0, self.1)
155 }
156}
157
158impl<T> Copy for IdentityHasher<T> {}
159
160pub trait IdentityHashable {}
196
197impl IdentityHashable for u8 {}
198
199impl IdentityHashable for u16 {}
200
201impl IdentityHashable for u32 {}
202
203impl IdentityHashable for u64 {}
204
205impl IdentityHashable for usize {}
206
207impl IdentityHashable for i8 {}
208
209impl IdentityHashable for i16 {}
210
211impl IdentityHashable for i32 {}
212
213impl IdentityHashable for i64 {}
214
215impl IdentityHashable for isize {}
216
217#[cfg(not(debug_assertions))]
218impl<T: IdentityHashable> Hasher for IdentityHasher<T> {
219 fn write(&mut self, _: &[u8]) {
220 panic!("Invalid use of IdentityHasher")
221 }
222
223 fn write_u8(&mut self, n: u8) {
224 self.0 = u64::from(n)
225 }
226 fn write_u16(&mut self, n: u16) {
227 self.0 = u64::from(n)
228 }
229 fn write_u32(&mut self, n: u32) {
230 self.0 = u64::from(n)
231 }
232 fn write_u64(&mut self, n: u64) {
233 self.0 = n
234 }
235 fn write_usize(&mut self, n: usize) {
236 self.0 = n as u64
237 }
238
239 fn write_i8(&mut self, n: i8) {
240 self.0 = n as u64
241 }
242 fn write_i16(&mut self, n: i16) {
243 self.0 = n as u64
244 }
245 fn write_i32(&mut self, n: i32) {
246 self.0 = n as u64
247 }
248 fn write_i64(&mut self, n: i64) {
249 self.0 = n as u64
250 }
251 fn write_isize(&mut self, n: isize) {
252 self.0 = n as u64
253 }
254
255 fn finish(&self) -> u64 {
256 self.0
257 }
258}
259
260#[cfg(debug_assertions)]
261impl<T: IdentityHashable> Hasher for IdentityHasher<T> {
262 fn write(&mut self, _: &[u8]) {
263 panic!("Invalid use of IdentityHasher")
264 }
265
266 fn write_u8(&mut self, n: u8) {
267 assert!(!self.1, "IdentityHasher: second write attempt detected.");
268 self.0 = u64::from(n);
269 self.1 = true
270 }
271
272 fn write_u16(&mut self, n: u16) {
273 assert!(!self.1, "IdentityHasher: second write attempt detected.");
274 self.0 = u64::from(n);
275 self.1 = true
276 }
277
278 fn write_u32(&mut self, n: u32) {
279 assert!(!self.1, "IdentityHasher: second write attempt detected.");
280 self.0 = u64::from(n);
281 self.1 = true
282 }
283
284 fn write_u64(&mut self, n: u64) {
285 assert!(!self.1, "IdentityHasher: second write attempt detected.");
286 self.0 = n;
287 self.1 = true
288 }
289
290 fn write_usize(&mut self, n: usize) {
291 assert!(!self.1, "IdentityHasher: second write attempt detected.");
292 self.0 = n as u64;
293 self.1 = true
294 }
295
296 fn write_i8(&mut self, n: i8) {
297 assert!(!self.1, "IdentityHasher: second write attempt detected.");
298 self.0 = n as u64;
299 self.1 = true
300 }
301
302 fn write_i16(&mut self, n: i16) {
303 assert!(!self.1, "IdentityHasher: second write attempt detected.");
304 self.0 = n as u64;
305 self.1 = true
306 }
307
308 fn write_i32(&mut self, n: i32) {
309 assert!(!self.1, "IdentityHasher: second write attempt detected.");
310 self.0 = n as u64;
311 self.1 = true
312 }
313
314 fn write_i64(&mut self, n: i64) {
315 assert!(!self.1, "IdentityHasher: second write attempt detected.");
316 self.0 = n as u64;
317 self.1 = true
318 }
319
320 fn write_isize(&mut self, n: isize) {
321 assert!(!self.1, "IdentityHasher: second write attempt detected.");
322 self.0 = n as u64;
323 self.1 = true
324 }
325
326 fn finish(&self) -> u64 {
327 self.0
328 }
329}
330
331#[cfg(test)]
332mod tests {
333 use super::*;
334
335 #[test]
336 fn ok() {
337 let mut h1 = IdentityHasher::<u8>::default();
338 h1.write_u8(42);
339 assert_eq!(42, h1.finish());
340
341 let mut h2 = IdentityHasher::<u16>::default();
342 h2.write_u16(42);
343 assert_eq!(42, h2.finish());
344
345 let mut h3 = IdentityHasher::<u32>::default();
346 h3.write_u32(42);
347 assert_eq!(42, h3.finish());
348
349 let mut h4 = IdentityHasher::<u64>::default();
350 h4.write_u64(42);
351 assert_eq!(42, h4.finish());
352
353 let mut h5 = IdentityHasher::<usize>::default();
354 h5.write_usize(42);
355 assert_eq!(42, h5.finish());
356
357 let mut h6 = IdentityHasher::<i8>::default();
358 h6.write_i8(42);
359 assert_eq!(42, h6.finish());
360
361 let mut h7 = IdentityHasher::<i16>::default();
362 h7.write_i16(42);
363 assert_eq!(42, h7.finish());
364
365 let mut h8 = IdentityHasher::<i32>::default();
366 h8.write_i32(42);
367 assert_eq!(42, h8.finish());
368
369 let mut h9 = IdentityHasher::<i64>::default();
370 h9.write_i64(42);
371 assert_eq!(42, h9.finish());
372
373 let mut h10 = IdentityHasher::<isize>::default();
374 h10.write_isize(42);
375 assert_eq!(42, h10.finish())
376 }
377
378 #[cfg(debug_assertions)]
379 #[test]
380 #[should_panic]
381 fn u8_double_usage() {
382 let mut h = IdentityHasher::<u8>::default();
383 h.write_u8(42);
384 h.write_u8(43);
385 }
386
387 #[cfg(debug_assertions)]
388 #[test]
389 #[should_panic]
390 fn u16_double_usage() {
391 let mut h = IdentityHasher::<u16>::default();
392 h.write_u16(42);
393 h.write_u16(43);
394 }
395
396 #[cfg(debug_assertions)]
397 #[test]
398 #[should_panic]
399 fn u32_double_usage() {
400 let mut h = IdentityHasher::<u32>::default();
401 h.write_u32(42);
402 h.write_u32(43);
403 }
404
405 #[cfg(debug_assertions)]
406 #[test]
407 #[should_panic]
408 fn u64_double_usage() {
409 let mut h = IdentityHasher::<u64>::default();
410 h.write_u64(42);
411 h.write_u64(43);
412 }
413
414 #[cfg(debug_assertions)]
415 #[test]
416 #[should_panic]
417 fn usize_double_usage() {
418 let mut h = IdentityHasher::<usize>::default();
419 h.write_usize(42);
420 h.write_usize(43);
421 }
422
423 #[cfg(debug_assertions)]
424 #[test]
425 #[should_panic]
426 fn i8_double_usage() {
427 let mut h = IdentityHasher::<i8>::default();
428 h.write_i8(42);
429 h.write_i8(43);
430 }
431
432 #[cfg(debug_assertions)]
433 #[test]
434 #[should_panic]
435 fn i16_double_usage() {
436 let mut h = IdentityHasher::<i16>::default();
437 h.write_i16(42);
438 h.write_i16(43);
439 }
440
441 #[cfg(debug_assertions)]
442 #[test]
443 #[should_panic]
444 fn i32_double_usage() {
445 let mut h = IdentityHasher::<i32>::default();
446 h.write_i32(42);
447 h.write_i32(43);
448 }
449
450 #[cfg(debug_assertions)]
451 #[test]
452 #[should_panic]
453 fn i64_double_usage() {
454 let mut h = IdentityHasher::<i64>::default();
455 h.write_i64(42);
456 h.write_i64(43);
457 }
458
459 #[cfg(debug_assertions)]
460 #[test]
461 #[should_panic]
462 fn isize_double_usage() {
463 let mut h = IdentityHasher::<isize>::default();
464 h.write_isize(42);
465 h.write_isize(43);
466 }
467}