#![allow(unused_must_use)]
use prelude::*;
use borrow::{Cow, ToOwned};
use intrinsics::TypeId;
use mem;
use num::Int;
pub use self::sip::hash as hash;
pub mod sip;
pub trait Hash<S = sip::SipState> {
fn hash(&self, state: &mut S);
}
pub trait Hasher<S> {
fn hash<T: ?Sized + Hash<S>>(&self, value: &T) -> u64;
}
#[allow(missing_docs)]
pub trait Writer {
fn write(&mut self, bytes: &[u8]);
}
macro_rules! impl_hash {
($ty:ident, $uty:ident) => {
impl<S: Writer> Hash<S> for $ty {
#[inline]
fn hash(&self, state: &mut S) {
let a: [u8; ::$ty::BYTES] = unsafe {
mem::transmute((*self as $uty).to_le() as $ty)
};
state.write(a.as_slice())
}
}
}
}
impl_hash! { u8, u8 }
impl_hash! { u16, u16 }
impl_hash! { u32, u32 }
impl_hash! { u64, u64 }
impl_hash! { uint, uint }
impl_hash! { i8, u8 }
impl_hash! { i16, u16 }
impl_hash! { i32, u32 }
impl_hash! { i64, u64 }
impl_hash! { int, uint }
impl<S: Writer> Hash<S> for bool {
#[inline]
fn hash(&self, state: &mut S) {
(*self as u8).hash(state);
}
}
impl<S: Writer> Hash<S> for char {
#[inline]
fn hash(&self, state: &mut S) {
(*self as u32).hash(state);
}
}
impl<S: Writer> Hash<S> for str {
#[inline]
fn hash(&self, state: &mut S) {
state.write(self.as_bytes());
0xffu8.hash(state)
}
}
macro_rules! impl_hash_tuple {
() => (
impl<S: Writer> Hash<S> for () {
#[inline]
fn hash(&self, state: &mut S) {
state.write(&[]);
}
}
);
( $($name:ident)+) => (
impl<S: Writer, $($name: Hash<S>),*> Hash<S> for ($($name,)*) {
#[inline]
#[allow(non_snake_case)]
fn hash(&self, state: &mut S) {
match *self {
($(ref $name,)*) => {
$(
$name.hash(state);
)*
}
}
}
}
);
}
impl_hash_tuple! {}
impl_hash_tuple! { A }
impl_hash_tuple! { A B }
impl_hash_tuple! { A B C }
impl_hash_tuple! { A B C D }
impl_hash_tuple! { A B C D E }
impl_hash_tuple! { A B C D E F }
impl_hash_tuple! { A B C D E F G }
impl_hash_tuple! { A B C D E F G H }
impl_hash_tuple! { A B C D E F G H I }
impl_hash_tuple! { A B C D E F G H I J }
impl_hash_tuple! { A B C D E F G H I J K }
impl_hash_tuple! { A B C D E F G H I J K L }
impl<S: Writer, T: Hash<S>> Hash<S> for [T] {
#[inline]
fn hash(&self, state: &mut S) {
self.len().hash(state);
for elt in self.iter() {
elt.hash(state);
}
}
}
impl<'a, S: Writer, T: ?Sized + Hash<S>> Hash<S> for &'a T {
#[inline]
fn hash(&self, state: &mut S) {
(**self).hash(state);
}
}
impl<'a, S: Writer, T: ?Sized + Hash<S>> Hash<S> for &'a mut T {
#[inline]
fn hash(&self, state: &mut S) {
(**self).hash(state);
}
}
impl<S: Writer, T> Hash<S> for *const T {
#[inline]
fn hash(&self, state: &mut S) {
(*self as uint).hash(state);
}
}
impl<S: Writer, T> Hash<S> for *mut T {
#[inline]
fn hash(&self, state: &mut S) {
(*self as uint).hash(state);
}
}
impl<S: Writer> Hash<S> for TypeId {
#[inline]
fn hash(&self, state: &mut S) {
self.hash().hash(state)
}
}
impl<'a, T, B: ?Sized, S> Hash<S> for Cow<'a, T, B> where B: Hash<S> + ToOwned<T> {
#[inline]
fn hash(&self, state: &mut S) {
Hash::hash(&**self, state)
}
}