]> git.proxmox.com Git - rustc.git/blame - src/libcore/hash/mod.rs
Imported Upstream version 1.10.0+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
e9174d1e 19//! use std::hash::{Hash, SipHasher, Hasher};
1a4d82fc
JJ
20//!
21//! #[derive(Hash)]
22//! struct Person {
c34b1796 23//! id: u32,
1a4d82fc
JJ
24//! name: String,
25//! phone: u64,
26//! }
27//!
28//! let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
29//! let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
30//!
e9174d1e
SL
31//! assert!(hash(&person1) != hash(&person2));
32//!
33//! fn hash<T: Hash>(t: &T) -> u64 {
34//! let mut s = SipHasher::new();
35//! t.hash(&mut s);
36//! s.finish()
37//! }
1a4d82fc
JJ
38//! ```
39//!
40//! If you need more control over how a value is hashed, you need to implement
41//! the trait `Hash`:
42//!
43//! ```rust
e9174d1e 44//! use std::hash::{Hash, Hasher, SipHasher};
1a4d82fc
JJ
45//!
46//! struct Person {
c34b1796 47//! id: u32,
92a42be0 48//! # #[allow(dead_code)]
1a4d82fc
JJ
49//! name: String,
50//! phone: u64,
51//! }
52//!
85aaf69f
SL
53//! impl Hash for Person {
54//! fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc
JJ
55//! self.id.hash(state);
56//! self.phone.hash(state);
57//! }
58//! }
59//!
60//! let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
61//! let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
62//!
e9174d1e
SL
63//! assert_eq!(hash(&person1), hash(&person2));
64//!
65//! fn hash<T: Hash>(t: &T) -> u64 {
66//! let mut s = SipHasher::new();
67//! t.hash(&mut s);
68//! s.finish()
69//! }
1a4d82fc
JJ
70//! ```
71
85aaf69f
SL
72#![stable(feature = "rust1", since = "1.0.0")]
73
e9174d1e 74use prelude::v1::*;
1a4d82fc 75
54a0048b 76use fmt;
9cc50fc6 77use marker;
85aaf69f 78use mem;
1a4d82fc 79
92a42be0 80#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
81pub use self::sip::SipHasher;
82
83mod sip;
84
85/// A hashable type.
86///
87/// The `H` type parameter is an abstract hash state that is used by the `Hash`
c34b1796
AL
88/// to compute the hash.
89///
90/// If you are also implementing `Eq`, there is an additional property that
91/// is important:
92///
93/// ```text
94/// k1 == k2 -> hash(k1) == hash(k2)
95/// ```
96///
97/// In other words, if two keys are equal, their hashes should also be equal.
98/// `HashMap` and `HashSet` both rely on this behavior.
92a42be0
SL
99///
100/// This trait can be used with `#[derive]`.
85aaf69f
SL
101#[stable(feature = "rust1", since = "1.0.0")]
102pub trait Hash {
1a4d82fc 103 /// Feeds this value into the state given, updating the hasher as necessary.
85aaf69f
SL
104 #[stable(feature = "rust1", since = "1.0.0")]
105 fn hash<H: Hasher>(&self, state: &mut H);
106
107 /// Feeds a slice of this type into the state provided.
c1a9b12d 108 #[stable(feature = "hash_slice", since = "1.3.0")]
b039eaaf
SL
109 fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
110 where Self: Sized
111 {
85aaf69f
SL
112 for piece in data {
113 piece.hash(state);
114 }
115 }
1a4d82fc
JJ
116}
117
1a4d82fc 118/// A trait which represents the ability to hash an arbitrary stream of bytes.
85aaf69f 119#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 120pub trait Hasher {
85aaf69f 121 /// Completes a round of hashing, producing the output hash generated.
c34b1796 122 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
123 fn finish(&self) -> u64;
124
125 /// Writes some data into this `Hasher`
85aaf69f
SL
126 #[stable(feature = "rust1", since = "1.0.0")]
127 fn write(&mut self, bytes: &[u8]);
128
129 /// Write a single `u8` into this hasher
85aaf69f 130 #[inline]
c1a9b12d 131 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
132 fn write_u8(&mut self, i: u8) {
133 self.write(&[i])
134 }
85aaf69f 135 /// Write a single `u16` into this hasher.
85aaf69f 136 #[inline]
c1a9b12d 137 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f
SL
138 fn write_u16(&mut self, i: u16) {
139 self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) })
140 }
141 /// Write a single `u32` into this hasher.
85aaf69f 142 #[inline]
c1a9b12d 143 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f
SL
144 fn write_u32(&mut self, i: u32) {
145 self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) })
146 }
147 /// Write a single `u64` into this hasher.
85aaf69f 148 #[inline]
c1a9b12d 149 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f
SL
150 fn write_u64(&mut self, i: u64) {
151 self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
152 }
153 /// Write a single `usize` into this hasher.
85aaf69f 154 #[inline]
c1a9b12d 155 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f 156 fn write_usize(&mut self, i: usize) {
e9174d1e 157 let bytes = unsafe {
b039eaaf 158 ::slice::from_raw_parts(&i as *const usize as *const u8, mem::size_of::<usize>())
e9174d1e
SL
159 };
160 self.write(bytes);
85aaf69f
SL
161 }
162
163 /// Write a single `i8` into this hasher.
85aaf69f 164 #[inline]
c1a9b12d 165 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
166 fn write_i8(&mut self, i: i8) {
167 self.write_u8(i as u8)
168 }
85aaf69f 169 /// Write a single `i16` into this hasher.
85aaf69f 170 #[inline]
c1a9b12d 171 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
172 fn write_i16(&mut self, i: i16) {
173 self.write_u16(i as u16)
174 }
85aaf69f 175 /// Write a single `i32` into this hasher.
85aaf69f 176 #[inline]
c1a9b12d 177 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
178 fn write_i32(&mut self, i: i32) {
179 self.write_u32(i as u32)
180 }
85aaf69f 181 /// Write a single `i64` into this hasher.
85aaf69f 182 #[inline]
c1a9b12d 183 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
184 fn write_i64(&mut self, i: i64) {
185 self.write_u64(i as u64)
186 }
85aaf69f 187 /// Write a single `isize` into this hasher.
85aaf69f 188 #[inline]
c1a9b12d 189 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
190 fn write_isize(&mut self, i: isize) {
191 self.write_usize(i as usize)
192 }
1a4d82fc
JJ
193}
194
9cc50fc6
SL
195/// A `BuildHasher` is typically used as a factory for instances of `Hasher`
196/// which a `HashMap` can then use to hash keys independently.
197///
7453a54e
SL
198/// Note that for each instance of `BuildHasher`, the created hashers should be
199/// identical. That is, if the same stream of bytes is fed into each hasher, the
9cc50fc6
SL
200/// same output will also be generated.
201#[stable(since = "1.7.0", feature = "build_hasher")]
202pub trait BuildHasher {
203 /// Type of the hasher that will be created.
204 #[stable(since = "1.7.0", feature = "build_hasher")]
205 type Hasher: Hasher;
206
207 /// Creates a new hasher.
208 #[stable(since = "1.7.0", feature = "build_hasher")]
209 fn build_hasher(&self) -> Self::Hasher;
210}
211
212/// A structure which implements `BuildHasher` for all `Hasher` types which also
213/// implement `Default`.
214///
215/// This struct is 0-sized and does not need construction.
216#[stable(since = "1.7.0", feature = "build_hasher")]
217pub struct BuildHasherDefault<H>(marker::PhantomData<H>);
218
54a0048b
SL
219#[stable(since = "1.9.0", feature = "core_impl_debug")]
220impl<H> fmt::Debug for BuildHasherDefault<H> {
221 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
222 f.pad("BuildHasherDefault")
223 }
224}
225
9cc50fc6
SL
226#[stable(since = "1.7.0", feature = "build_hasher")]
227impl<H: Default + Hasher> BuildHasher for BuildHasherDefault<H> {
228 type Hasher = H;
229
230 fn build_hasher(&self) -> H {
231 H::default()
232 }
233}
234
235#[stable(since = "1.7.0", feature = "build_hasher")]
236impl<H> Clone for BuildHasherDefault<H> {
237 fn clone(&self) -> BuildHasherDefault<H> {
238 BuildHasherDefault(marker::PhantomData)
239 }
240}
241
242#[stable(since = "1.7.0", feature = "build_hasher")]
243impl<H> Default for BuildHasherDefault<H> {
244 fn default() -> BuildHasherDefault<H> {
245 BuildHasherDefault(marker::PhantomData)
246 }
247}
248
1a4d82fc
JJ
249//////////////////////////////////////////////////////////////////////////////
250
1a4d82fc 251mod impls {
e9174d1e 252 use prelude::v1::*;
1a4d82fc 253
9cc50fc6 254 use mem;
85aaf69f
SL
255 use slice;
256 use super::*;
1a4d82fc 257
85aaf69f
SL
258 macro_rules! impl_write {
259 ($(($ty:ident, $meth:ident),)*) => {$(
260 #[stable(feature = "rust1", since = "1.0.0")]
261 impl Hash for $ty {
262 fn hash<H: Hasher>(&self, state: &mut H) {
263 state.$meth(*self)
264 }
265
266 fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
9cc50fc6 267 let newlen = data.len() * mem::size_of::<$ty>();
85aaf69f
SL
268 let ptr = data.as_ptr() as *const u8;
269 state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
1a4d82fc
JJ
270 }
271 }
85aaf69f 272 )*}
1a4d82fc
JJ
273 }
274
85aaf69f
SL
275 impl_write! {
276 (u8, write_u8),
277 (u16, write_u16),
278 (u32, write_u32),
279 (u64, write_u64),
280 (usize, write_usize),
281 (i8, write_i8),
282 (i16, write_i16),
283 (i32, write_i32),
284 (i64, write_i64),
285 (isize, write_isize),
286 }
1a4d82fc 287
85aaf69f
SL
288 #[stable(feature = "rust1", since = "1.0.0")]
289 impl Hash for bool {
290 fn hash<H: Hasher>(&self, state: &mut H) {
291 state.write_u8(*self as u8)
1a4d82fc
JJ
292 }
293 }
294
85aaf69f
SL
295 #[stable(feature = "rust1", since = "1.0.0")]
296 impl Hash for char {
297 fn hash<H: Hasher>(&self, state: &mut H) {
298 state.write_u32(*self as u32)
1a4d82fc
JJ
299 }
300 }
301
85aaf69f
SL
302 #[stable(feature = "rust1", since = "1.0.0")]
303 impl Hash for str {
304 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc 305 state.write(self.as_bytes());
85aaf69f 306 state.write_u8(0xff)
1a4d82fc
JJ
307 }
308 }
309
310 macro_rules! impl_hash_tuple {
311 () => (
85aaf69f
SL
312 #[stable(feature = "rust1", since = "1.0.0")]
313 impl Hash for () {
314 fn hash<H: Hasher>(&self, _state: &mut H) {}
1a4d82fc
JJ
315 }
316 );
317
318 ( $($name:ident)+) => (
85aaf69f
SL
319 #[stable(feature = "rust1", since = "1.0.0")]
320 impl<$($name: Hash),*> Hash for ($($name,)*) {
1a4d82fc 321 #[allow(non_snake_case)]
85aaf69f
SL
322 fn hash<S: Hasher>(&self, state: &mut S) {
323 let ($(ref $name,)*) = *self;
324 $($name.hash(state);)*
1a4d82fc
JJ
325 }
326 }
327 );
328 }
329
330 impl_hash_tuple! {}
331 impl_hash_tuple! { A }
332 impl_hash_tuple! { A B }
333 impl_hash_tuple! { A B C }
334 impl_hash_tuple! { A B C D }
335 impl_hash_tuple! { A B C D E }
336 impl_hash_tuple! { A B C D E F }
337 impl_hash_tuple! { A B C D E F G }
338 impl_hash_tuple! { A B C D E F G H }
339 impl_hash_tuple! { A B C D E F G H I }
340 impl_hash_tuple! { A B C D E F G H I J }
341 impl_hash_tuple! { A B C D E F G H I J K }
342 impl_hash_tuple! { A B C D E F G H I J K L }
343
85aaf69f
SL
344 #[stable(feature = "rust1", since = "1.0.0")]
345 impl<T: Hash> Hash for [T] {
346 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc 347 self.len().hash(state);
85aaf69f 348 Hash::hash_slice(self, state)
1a4d82fc
JJ
349 }
350 }
351
352
85aaf69f
SL
353 #[stable(feature = "rust1", since = "1.0.0")]
354 impl<'a, T: ?Sized + Hash> Hash for &'a T {
355 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc
JJ
356 (**self).hash(state);
357 }
358 }
359
85aaf69f
SL
360 #[stable(feature = "rust1", since = "1.0.0")]
361 impl<'a, T: ?Sized + Hash> Hash for &'a mut T {
362 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc
JJ
363 (**self).hash(state);
364 }
365 }
366
85aaf69f
SL
367 #[stable(feature = "rust1", since = "1.0.0")]
368 impl<T> Hash for *const T {
369 fn hash<H: Hasher>(&self, state: &mut H) {
370 state.write_usize(*self as usize)
1a4d82fc
JJ
371 }
372 }
373
85aaf69f
SL
374 #[stable(feature = "rust1", since = "1.0.0")]
375 impl<T> Hash for *mut T {
376 fn hash<H: Hasher>(&self, state: &mut H) {
377 state.write_usize(*self as usize)
1a4d82fc
JJ
378 }
379 }
380}