]> git.proxmox.com Git - rustc.git/blame - src/libcore/hash/mod.rs
New upstream version 1.28.0~beta.14+dfsg1
[rustc.git] / src / libcore / hash / mod.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! Generic hashing support.
12//!
13//! This module provides a generic way to compute the hash of a value. The
14//! simplest way to make a type hashable is to use `#[derive(Hash)]`:
15//!
16//! # Examples
17//!
18//! ```rust
cc61c64b
XL
19//! use std::collections::hash_map::DefaultHasher;
20//! use std::hash::{Hash, Hasher};
1a4d82fc
JJ
21//!
22//! #[derive(Hash)]
23//! struct Person {
c34b1796 24//! id: u32,
1a4d82fc
JJ
25//! name: String,
26//! phone: u64,
27//! }
28//!
cc61c64b
XL
29//! let person1 = Person {
30//! id: 5,
31//! name: "Janet".to_string(),
32//! phone: 555_666_7777,
33//! };
34//! let person2 = Person {
35//! id: 5,
36//! name: "Bob".to_string(),
37//! phone: 555_666_7777,
38//! };
1a4d82fc 39//!
cc61c64b 40//! assert!(calculate_hash(&person1) != calculate_hash(&person2));
e9174d1e 41//!
cc61c64b
XL
42//! fn calculate_hash<T: Hash>(t: &T) -> u64 {
43//! let mut s = DefaultHasher::new();
e9174d1e
SL
44//! t.hash(&mut s);
45//! s.finish()
46//! }
1a4d82fc
JJ
47//! ```
48//!
49//! If you need more control over how a value is hashed, you need to implement
c30ab7b3
SL
50//! the [`Hash`] trait:
51//!
52//! [`Hash`]: trait.Hash.html
1a4d82fc
JJ
53//!
54//! ```rust
cc61c64b
XL
55//! use std::collections::hash_map::DefaultHasher;
56//! use std::hash::{Hash, Hasher};
1a4d82fc
JJ
57//!
58//! struct Person {
c34b1796 59//! id: u32,
cc61c64b 60//! # #[allow(dead_code)]
1a4d82fc
JJ
61//! name: String,
62//! phone: u64,
63//! }
64//!
85aaf69f
SL
65//! impl Hash for Person {
66//! fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc
JJ
67//! self.id.hash(state);
68//! self.phone.hash(state);
69//! }
70//! }
71//!
cc61c64b
XL
72//! let person1 = Person {
73//! id: 5,
74//! name: "Janet".to_string(),
75//! phone: 555_666_7777,
76//! };
77//! let person2 = Person {
78//! id: 5,
79//! name: "Bob".to_string(),
80//! phone: 555_666_7777,
81//! };
1a4d82fc 82//!
cc61c64b 83//! assert_eq!(calculate_hash(&person1), calculate_hash(&person2));
e9174d1e 84//!
cc61c64b
XL
85//! fn calculate_hash<T: Hash>(t: &T) -> u64 {
86//! let mut s = DefaultHasher::new();
e9174d1e
SL
87//! t.hash(&mut s);
88//! s.finish()
89//! }
1a4d82fc
JJ
90//! ```
91
85aaf69f
SL
92#![stable(feature = "rust1", since = "1.0.0")]
93
54a0048b 94use fmt;
9cc50fc6 95use marker;
85aaf69f 96use mem;
1a4d82fc 97
92a42be0 98#[stable(feature = "rust1", since = "1.0.0")]
9e0c209e 99#[allow(deprecated)]
1a4d82fc
JJ
100pub use self::sip::SipHasher;
101
0531ce1d 102#[unstable(feature = "hashmap_internals", issue = "0")]
9e0c209e 103#[allow(deprecated)]
0531ce1d
XL
104#[doc(hidden)]
105pub use self::sip::SipHasher13;
3157f602 106
1a4d82fc
JJ
107mod sip;
108
109/// A hashable type.
110///
cc61c64b
XL
111/// Types implementing `Hash` are able to be [`hash`]ed with an instance of
112/// [`Hasher`].
c34b1796 113///
cc61c64b 114/// ## Implementing `Hash`
c34b1796 115///
cc61c64b
XL
116/// You can derive `Hash` with `#[derive(Hash)]` if all fields implement `Hash`.
117/// The resulting hash will be the combination of the values from calling
118/// [`hash`] on each field.
92a42be0 119///
cc61c64b
XL
120/// ```
121/// #[derive(Hash)]
122/// struct Rustacean {
123/// name: String,
124/// country: String,
125/// }
126/// ```
3157f602 127///
cc61c64b
XL
128/// If you need more control over how a value is hashed, you can of course
129/// implement the `Hash` trait yourself:
3157f602
XL
130///
131/// ```
132/// use std::hash::{Hash, Hasher};
133///
134/// struct Person {
135/// id: u32,
136/// name: String,
137/// phone: u64,
138/// }
139///
140/// impl Hash for Person {
141/// fn hash<H: Hasher>(&self, state: &mut H) {
142/// self.id.hash(state);
143/// self.phone.hash(state);
144/// }
145/// }
146/// ```
c30ab7b3 147///
cc61c64b
XL
148/// ## `Hash` and `Eq`
149///
150/// When implementing both `Hash` and [`Eq`], it is important that the following
151/// property holds:
152///
153/// ```text
154/// k1 == k2 -> hash(k1) == hash(k2)
155/// ```
156///
157/// In other words, if two keys are equal, their hashes must also be equal.
158/// [`HashMap`] and [`HashSet`] both rely on this behavior.
159///
160/// Thankfully, you won't need to worry about upholding this property when
161/// deriving both [`Eq`] and `Hash` with `#[derive(PartialEq, Eq, Hash)]`.
162///
c30ab7b3 163/// [`Eq`]: ../../std/cmp/trait.Eq.html
cc61c64b 164/// [`Hasher`]: trait.Hasher.html
c30ab7b3
SL
165/// [`HashMap`]: ../../std/collections/struct.HashMap.html
166/// [`HashSet`]: ../../std/collections/struct.HashSet.html
cc61c64b 167/// [`hash`]: #tymethod.hash
85aaf69f
SL
168#[stable(feature = "rust1", since = "1.0.0")]
169pub trait Hash {
cc61c64b
XL
170 /// Feeds this value into the given [`Hasher`].
171 ///
172 /// # Examples
173 ///
174 /// ```
175 /// use std::collections::hash_map::DefaultHasher;
176 /// use std::hash::{Hash, Hasher};
177 ///
178 /// let mut hasher = DefaultHasher::new();
179 /// 7920.hash(&mut hasher);
180 /// println!("Hash is {:x}!", hasher.finish());
181 /// ```
182 ///
183 /// [`Hasher`]: trait.Hasher.html
85aaf69f
SL
184 #[stable(feature = "rust1", since = "1.0.0")]
185 fn hash<H: Hasher>(&self, state: &mut H);
186
cc61c64b
XL
187 /// Feeds a slice of this type into the given [`Hasher`].
188 ///
189 /// # Examples
190 ///
191 /// ```
192 /// use std::collections::hash_map::DefaultHasher;
193 /// use std::hash::{Hash, Hasher};
194 ///
195 /// let mut hasher = DefaultHasher::new();
196 /// let numbers = [6, 28, 496, 8128];
197 /// Hash::hash_slice(&numbers, &mut hasher);
198 /// println!("Hash is {:x}!", hasher.finish());
199 /// ```
200 ///
201 /// [`Hasher`]: trait.Hasher.html
c1a9b12d 202 #[stable(feature = "hash_slice", since = "1.3.0")]
b039eaaf
SL
203 fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
204 where Self: Sized
205 {
85aaf69f
SL
206 for piece in data {
207 piece.hash(state);
208 }
209 }
1a4d82fc
JJ
210}
211
cc61c64b
XL
212/// A trait for hashing an arbitrary stream of bytes.
213///
214/// Instances of `Hasher` usually represent state that is changed while hashing
215/// data.
216///
217/// `Hasher` provides a fairly basic interface for retrieving the generated hash
218/// (with [`finish`]), and writing integers as well as slices of bytes into an
219/// instance (with [`write`] and [`write_u8`] etc.). Most of the time, `Hasher`
220/// instances are used in conjunction with the [`Hash`] trait.
221///
222/// # Examples
223///
224/// ```
225/// use std::collections::hash_map::DefaultHasher;
226/// use std::hash::Hasher;
227///
228/// let mut hasher = DefaultHasher::new();
229///
230/// hasher.write_u32(1989);
231/// hasher.write_u8(11);
232/// hasher.write_u8(9);
233/// hasher.write(b"Huh?");
234///
235/// println!("Hash is {:x}!", hasher.finish());
236/// ```
237///
238/// [`Hash`]: trait.Hash.html
239/// [`finish`]: #tymethod.finish
240/// [`write`]: #tymethod.write
241/// [`write_u8`]: #method.write_u8
85aaf69f 242#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 243pub trait Hasher {
3b2f2976
XL
244 /// Returns the hash value for the values written so far.
245 ///
246 /// Despite its name, the method does not reset the hasher’s internal
247 /// state. Additional [`write`]s will continue from the current value.
248 /// If you need to start a fresh hash value, you will have to create
249 /// a new hasher.
cc61c64b
XL
250 ///
251 /// # Examples
252 ///
253 /// ```
254 /// use std::collections::hash_map::DefaultHasher;
255 /// use std::hash::Hasher;
256 ///
257 /// let mut hasher = DefaultHasher::new();
258 /// hasher.write(b"Cool!");
259 ///
260 /// println!("Hash is {:x}!", hasher.finish());
261 /// ```
3b2f2976 262 ///
abe05a73 263 /// [`write`]: #tymethod.write
c34b1796 264 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
265 fn finish(&self) -> u64;
266
c30ab7b3 267 /// Writes some data into this `Hasher`.
cc61c64b
XL
268 ///
269 /// # Examples
270 ///
271 /// ```
272 /// use std::collections::hash_map::DefaultHasher;
273 /// use std::hash::Hasher;
274 ///
275 /// let mut hasher = DefaultHasher::new();
276 /// let data = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
277 ///
278 /// hasher.write(&data);
279 ///
280 /// println!("Hash is {:x}!", hasher.finish());
281 /// ```
85aaf69f
SL
282 #[stable(feature = "rust1", since = "1.0.0")]
283 fn write(&mut self, bytes: &[u8]);
284
cc61c64b 285 /// Writes a single `u8` into this hasher.
85aaf69f 286 #[inline]
c1a9b12d 287 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
288 fn write_u8(&mut self, i: u8) {
289 self.write(&[i])
290 }
c30ab7b3 291 /// Writes a single `u16` into this hasher.
85aaf69f 292 #[inline]
c1a9b12d 293 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f
SL
294 fn write_u16(&mut self, i: u16) {
295 self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) })
296 }
c30ab7b3 297 /// Writes a single `u32` into this hasher.
85aaf69f 298 #[inline]
c1a9b12d 299 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f
SL
300 fn write_u32(&mut self, i: u32) {
301 self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) })
302 }
c30ab7b3 303 /// Writes a single `u64` into this hasher.
85aaf69f 304 #[inline]
c1a9b12d 305 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f
SL
306 fn write_u64(&mut self, i: u64) {
307 self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
308 }
32a655c1
SL
309 /// Writes a single `u128` into this hasher.
310 #[inline]
0531ce1d 311 #[stable(feature = "i128", since = "1.26.0")]
32a655c1
SL
312 fn write_u128(&mut self, i: u128) {
313 self.write(&unsafe { mem::transmute::<_, [u8; 16]>(i) })
314 }
c30ab7b3 315 /// Writes a single `usize` into this hasher.
85aaf69f 316 #[inline]
c1a9b12d 317 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f 318 fn write_usize(&mut self, i: usize) {
e9174d1e 319 let bytes = unsafe {
b039eaaf 320 ::slice::from_raw_parts(&i as *const usize as *const u8, mem::size_of::<usize>())
e9174d1e
SL
321 };
322 self.write(bytes);
85aaf69f
SL
323 }
324
c30ab7b3 325 /// Writes a single `i8` into this hasher.
85aaf69f 326 #[inline]
c1a9b12d 327 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
328 fn write_i8(&mut self, i: i8) {
329 self.write_u8(i as u8)
330 }
c30ab7b3 331 /// Writes a single `i16` into this hasher.
85aaf69f 332 #[inline]
c1a9b12d 333 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
334 fn write_i16(&mut self, i: i16) {
335 self.write_u16(i as u16)
336 }
c30ab7b3 337 /// Writes a single `i32` into this hasher.
85aaf69f 338 #[inline]
c1a9b12d 339 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
340 fn write_i32(&mut self, i: i32) {
341 self.write_u32(i as u32)
342 }
c30ab7b3 343 /// Writes a single `i64` into this hasher.
85aaf69f 344 #[inline]
c1a9b12d 345 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
346 fn write_i64(&mut self, i: i64) {
347 self.write_u64(i as u64)
348 }
32a655c1
SL
349 /// Writes a single `i128` into this hasher.
350 #[inline]
0531ce1d 351 #[stable(feature = "i128", since = "1.26.0")]
32a655c1
SL
352 fn write_i128(&mut self, i: i128) {
353 self.write_u128(i as u128)
354 }
c30ab7b3 355 /// Writes a single `isize` into this hasher.
85aaf69f 356 #[inline]
c1a9b12d 357 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
358 fn write_isize(&mut self, i: isize) {
359 self.write_usize(i as usize)
360 }
1a4d82fc
JJ
361}
362
ea8adc8c
XL
363#[stable(feature = "indirect_hasher_impl", since = "1.22.0")]
364impl<'a, H: Hasher + ?Sized> Hasher for &'a mut H {
365 fn finish(&self) -> u64 {
366 (**self).finish()
367 }
368 fn write(&mut self, bytes: &[u8]) {
369 (**self).write(bytes)
370 }
371 fn write_u8(&mut self, i: u8) {
372 (**self).write_u8(i)
373 }
374 fn write_u16(&mut self, i: u16) {
375 (**self).write_u16(i)
376 }
377 fn write_u32(&mut self, i: u32) {
378 (**self).write_u32(i)
379 }
380 fn write_u64(&mut self, i: u64) {
381 (**self).write_u64(i)
382 }
383 fn write_u128(&mut self, i: u128) {
384 (**self).write_u128(i)
385 }
386 fn write_usize(&mut self, i: usize) {
387 (**self).write_usize(i)
388 }
389 fn write_i8(&mut self, i: i8) {
390 (**self).write_i8(i)
391 }
392 fn write_i16(&mut self, i: i16) {
393 (**self).write_i16(i)
394 }
395 fn write_i32(&mut self, i: i32) {
396 (**self).write_i32(i)
397 }
398 fn write_i64(&mut self, i: i64) {
399 (**self).write_i64(i)
400 }
401 fn write_i128(&mut self, i: i128) {
402 (**self).write_i128(i)
403 }
404 fn write_isize(&mut self, i: isize) {
405 (**self).write_isize(i)
406 }
407}
408
cc61c64b
XL
409/// A trait for creating instances of [`Hasher`].
410///
411/// A `BuildHasher` is typically used (e.g. by [`HashMap`]) to create
412/// [`Hasher`]s for each key such that they are hashed independently of one
413/// another, since [`Hasher`]s contain state.
414///
415/// For each instance of `BuildHasher`, the [`Hasher`]s created by
416/// [`build_hasher`] should be identical. That is, if the same stream of bytes
417/// is fed into each hasher, the same output will also be generated.
418///
419/// # Examples
420///
421/// ```
422/// use std::collections::hash_map::RandomState;
423/// use std::hash::{BuildHasher, Hasher};
424///
425/// let s = RandomState::new();
426/// let mut hasher_1 = s.build_hasher();
427/// let mut hasher_2 = s.build_hasher();
9cc50fc6 428///
cc61c64b
XL
429/// hasher_1.write_u32(8128);
430/// hasher_2.write_u32(8128);
431///
432/// assert_eq!(hasher_1.finish(), hasher_2.finish());
433/// ```
434///
435/// [`build_hasher`]: #tymethod.build_hasher
436/// [`Hasher`]: trait.Hasher.html
437/// [`HashMap`]: ../../std/collections/struct.HashMap.html
9cc50fc6
SL
438#[stable(since = "1.7.0", feature = "build_hasher")]
439pub trait BuildHasher {
440 /// Type of the hasher that will be created.
441 #[stable(since = "1.7.0", feature = "build_hasher")]
442 type Hasher: Hasher;
443
444 /// Creates a new hasher.
5bcae85e 445 ///
cc61c64b
XL
446 /// Each call to `build_hasher` on the same instance should produce identical
447 /// [`Hasher`]s.
448 ///
5bcae85e
SL
449 /// # Examples
450 ///
451 /// ```
452 /// use std::collections::hash_map::RandomState;
453 /// use std::hash::BuildHasher;
454 ///
455 /// let s = RandomState::new();
456 /// let new_s = s.build_hasher();
457 /// ```
cc61c64b
XL
458 ///
459 /// [`Hasher`]: trait.Hasher.html
9cc50fc6
SL
460 #[stable(since = "1.7.0", feature = "build_hasher")]
461 fn build_hasher(&self) -> Self::Hasher;
462}
463
cc61c64b
XL
464/// Used to create a default [`BuildHasher`] instance for types that implement
465/// [`Hasher`] and [`Default`].
9cc50fc6 466///
cc61c64b
XL
467/// `BuildHasherDefault<H>` can be used when a type `H` implements [`Hasher`] and
468/// [`Default`], and you need a corresponding [`BuildHasher`] instance, but none is
469/// defined.
470///
471/// Any `BuildHasherDefault` is [zero-sized]. It can be created with
472/// [`default`][method.Default]. When using `BuildHasherDefault` with [`HashMap`] or
473/// [`HashSet`], this doesn't need to be done, since they implement appropriate
474/// [`Default`] instances themselves.
476ff2be
SL
475///
476/// # Examples
477///
478/// Using `BuildHasherDefault` to specify a custom [`BuildHasher`] for
479/// [`HashMap`]:
480///
481/// ```
482/// use std::collections::HashMap;
483/// use std::hash::{BuildHasherDefault, Hasher};
484///
485/// #[derive(Default)]
486/// struct MyHasher;
487///
488/// impl Hasher for MyHasher {
489/// fn write(&mut self, bytes: &[u8]) {
490/// // Your hashing algorithm goes here!
491/// unimplemented!()
492/// }
493///
494/// fn finish(&self) -> u64 {
495/// // Your hashing algorithm goes here!
496/// unimplemented!()
497/// }
498/// }
499///
500/// type MyBuildHasher = BuildHasherDefault<MyHasher>;
501///
502/// let hash_map = HashMap::<u32, u32, MyBuildHasher>::default();
503/// ```
504///
505/// [`BuildHasher`]: trait.BuildHasher.html
506/// [`Default`]: ../default/trait.Default.html
cc61c64b 507/// [method.default]: #method.default
476ff2be 508/// [`Hasher`]: trait.Hasher.html
32a655c1 509/// [`HashMap`]: ../../std/collections/struct.HashMap.html
cc61c64b
XL
510/// [`HashSet`]: ../../std/collections/struct.HashSet.html
511/// [zero-sized]: https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts
9cc50fc6
SL
512#[stable(since = "1.7.0", feature = "build_hasher")]
513pub struct BuildHasherDefault<H>(marker::PhantomData<H>);
514
54a0048b
SL
515#[stable(since = "1.9.0", feature = "core_impl_debug")]
516impl<H> fmt::Debug for BuildHasherDefault<H> {
517 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
518 f.pad("BuildHasherDefault")
519 }
520}
521
9cc50fc6
SL
522#[stable(since = "1.7.0", feature = "build_hasher")]
523impl<H: Default + Hasher> BuildHasher for BuildHasherDefault<H> {
524 type Hasher = H;
525
526 fn build_hasher(&self) -> H {
527 H::default()
528 }
529}
530
531#[stable(since = "1.7.0", feature = "build_hasher")]
532impl<H> Clone for BuildHasherDefault<H> {
533 fn clone(&self) -> BuildHasherDefault<H> {
534 BuildHasherDefault(marker::PhantomData)
535 }
536}
537
538#[stable(since = "1.7.0", feature = "build_hasher")]
539impl<H> Default for BuildHasherDefault<H> {
540 fn default() -> BuildHasherDefault<H> {
541 BuildHasherDefault(marker::PhantomData)
542 }
543}
544
1a4d82fc
JJ
545//////////////////////////////////////////////////////////////////////////////
546
1a4d82fc 547mod impls {
9cc50fc6 548 use mem;
85aaf69f
SL
549 use slice;
550 use super::*;
1a4d82fc 551
85aaf69f
SL
552 macro_rules! impl_write {
553 ($(($ty:ident, $meth:ident),)*) => {$(
554 #[stable(feature = "rust1", since = "1.0.0")]
555 impl Hash for $ty {
556 fn hash<H: Hasher>(&self, state: &mut H) {
557 state.$meth(*self)
558 }
559
560 fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
9cc50fc6 561 let newlen = data.len() * mem::size_of::<$ty>();
85aaf69f
SL
562 let ptr = data.as_ptr() as *const u8;
563 state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
1a4d82fc
JJ
564 }
565 }
85aaf69f 566 )*}
1a4d82fc
JJ
567 }
568
85aaf69f
SL
569 impl_write! {
570 (u8, write_u8),
571 (u16, write_u16),
572 (u32, write_u32),
573 (u64, write_u64),
574 (usize, write_usize),
575 (i8, write_i8),
576 (i16, write_i16),
577 (i32, write_i32),
578 (i64, write_i64),
579 (isize, write_isize),
32a655c1
SL
580 (u128, write_u128),
581 (i128, write_i128),
582 }
1a4d82fc 583
85aaf69f
SL
584 #[stable(feature = "rust1", since = "1.0.0")]
585 impl Hash for bool {
586 fn hash<H: Hasher>(&self, state: &mut H) {
587 state.write_u8(*self as u8)
1a4d82fc
JJ
588 }
589 }
590
85aaf69f
SL
591 #[stable(feature = "rust1", since = "1.0.0")]
592 impl Hash for char {
593 fn hash<H: Hasher>(&self, state: &mut H) {
594 state.write_u32(*self as u32)
1a4d82fc
JJ
595 }
596 }
597
85aaf69f
SL
598 #[stable(feature = "rust1", since = "1.0.0")]
599 impl Hash for str {
600 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc 601 state.write(self.as_bytes());
85aaf69f 602 state.write_u8(0xff)
1a4d82fc
JJ
603 }
604 }
605
94b46f34
XL
606 #[stable(feature = "never_hash", since = "1.29.0")]
607 impl Hash for ! {
608 fn hash<H: Hasher>(&self, _: &mut H) {
609 *self
610 }
611 }
612
1a4d82fc
JJ
613 macro_rules! impl_hash_tuple {
614 () => (
85aaf69f
SL
615 #[stable(feature = "rust1", since = "1.0.0")]
616 impl Hash for () {
617 fn hash<H: Hasher>(&self, _state: &mut H) {}
1a4d82fc
JJ
618 }
619 );
620
621 ( $($name:ident)+) => (
85aaf69f 622 #[stable(feature = "rust1", since = "1.0.0")]
041b39d2 623 impl<$($name: Hash),*> Hash for ($($name,)*) where last_type!($($name,)+): ?Sized {
1a4d82fc 624 #[allow(non_snake_case)]
85aaf69f
SL
625 fn hash<S: Hasher>(&self, state: &mut S) {
626 let ($(ref $name,)*) = *self;
627 $($name.hash(state);)*
1a4d82fc
JJ
628 }
629 }
630 );
631 }
632
041b39d2
XL
633 macro_rules! last_type {
634 ($a:ident,) => { $a };
635 ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
636 }
637
1a4d82fc
JJ
638 impl_hash_tuple! {}
639 impl_hash_tuple! { A }
640 impl_hash_tuple! { A B }
641 impl_hash_tuple! { A B C }
642 impl_hash_tuple! { A B C D }
643 impl_hash_tuple! { A B C D E }
644 impl_hash_tuple! { A B C D E F }
645 impl_hash_tuple! { A B C D E F G }
646 impl_hash_tuple! { A B C D E F G H }
647 impl_hash_tuple! { A B C D E F G H I }
648 impl_hash_tuple! { A B C D E F G H I J }
649 impl_hash_tuple! { A B C D E F G H I J K }
650 impl_hash_tuple! { A B C D E F G H I J K L }
651
85aaf69f
SL
652 #[stable(feature = "rust1", since = "1.0.0")]
653 impl<T: Hash> Hash for [T] {
654 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc 655 self.len().hash(state);
85aaf69f 656 Hash::hash_slice(self, state)
1a4d82fc
JJ
657 }
658 }
659
660
85aaf69f
SL
661 #[stable(feature = "rust1", since = "1.0.0")]
662 impl<'a, T: ?Sized + Hash> Hash for &'a T {
663 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc
JJ
664 (**self).hash(state);
665 }
666 }
667
85aaf69f
SL
668 #[stable(feature = "rust1", since = "1.0.0")]
669 impl<'a, T: ?Sized + Hash> Hash for &'a mut T {
670 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc
JJ
671 (**self).hash(state);
672 }
673 }
674
85aaf69f 675 #[stable(feature = "rust1", since = "1.0.0")]
abe05a73 676 impl<T: ?Sized> Hash for *const T {
85aaf69f 677 fn hash<H: Hasher>(&self, state: &mut H) {
abe05a73
XL
678 if mem::size_of::<Self>() == mem::size_of::<usize>() {
679 // Thin pointer
680 state.write_usize(*self as *const () as usize);
681 } else {
682 // Fat pointer
683 let (a, b) = unsafe {
684 *(self as *const Self as *const (usize, usize))
685 };
686 state.write_usize(a);
687 state.write_usize(b);
688 }
1a4d82fc
JJ
689 }
690 }
691
85aaf69f 692 #[stable(feature = "rust1", since = "1.0.0")]
abe05a73 693 impl<T: ?Sized> Hash for *mut T {
85aaf69f 694 fn hash<H: Hasher>(&self, state: &mut H) {
abe05a73
XL
695 if mem::size_of::<Self>() == mem::size_of::<usize>() {
696 // Thin pointer
697 state.write_usize(*self as *const () as usize);
698 } else {
699 // Fat pointer
700 let (a, b) = unsafe {
701 *(self as *const Self as *const (usize, usize))
702 };
703 state.write_usize(a);
704 state.write_usize(b);
705 }
1a4d82fc
JJ
706 }
707 }
708}