#![no_std]
#[cfg(any(test, feature = "std"))]
extern crate std;
#[macro_use]
extern crate cfg_if;
use core::hash::{BuildHasherDefault, Hasher};
mod bits;
mod nightly;
mod t1ha0;
mod t1ha1;
mod t1ha2;
pub use t1ha0::{t1ha0_32be, t1ha0_32le};
pub use t1ha1::{t1ha1_be, t1ha1_le};
pub use t1ha2::{t1ha2_atonce, t1ha2_atonce128, T1ha2Hasher};
cfg_if! {
if #[cfg(target_endian = "little")] {
pub use t1ha0::t1ha0_32le as t1ha0_32;
pub use t1ha1::t1ha1_le as t1ha1;
} else {
pub use t1ha0::t1ha0_32be as t1ha0_32;
pub use t1ha1::t1ha1_be as t1ha1;
}
}
cfg_if! {
if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
cfg_if! {
if #[cfg(any(target_feature = "aes", target_feature = "avx", target_feature = "avx2"))] {
mod t1ha0_aes;
}
}
cfg_if! {
if #[cfg(target_feature = "aes")] {
pub use t1ha0_aes::t1ha0_ia32aes as t1ha0_ia32aes_noavx;
}
}
cfg_if! {
if #[cfg(target_feature = "avx")] {
pub use t1ha0_aes::t1ha0_ia32aes as t1ha0_ia32aes_avx;
}
}
cfg_if! {
if #[cfg(target_feature = "avx2")] {
pub use t1ha0_aes::t1ha0_ia32aes_avx2;
}
}
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct T1haHasher(u64);
impl T1haHasher {
#[inline]
pub fn with_seed(seed: u64) -> Self {
Self(seed)
}
}
impl Hasher for T1haHasher {
#[inline]
fn finish(&self) -> u64 {
self.0
}
#[inline]
fn write(&mut self, bytes: &[u8]) {
*self = T1haHasher(t1ha0(bytes, self.0));
}
}
pub type T1haBuildHasher = BuildHasherDefault<T1haHasher>;
cfg_if! {
if #[cfg(feature = "std")] {
use std::collections::{HashMap, HashSet};
pub type T1haHashMap<K, V> = HashMap<K, V, T1haBuildHasher>;
pub type T1haHashSet<T> = HashSet<T, T1haBuildHasher>;
}
}
pub fn t1ha0(data: &[u8], seed: u64) -> u64 {
prefer::HASH(data, seed)
}
mod prefer {
cfg_if! {
if #[cfg(target_pointer_width = "64")] {
pub use super::t1ha1 as t1ha0_fallback;
} else {
pub use super::t1ha0_32 as t1ha0_fallback;
}
}
cfg_if! {
if #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), feature = "runtime_select", feature = "std"))] {
use std::is_x86_feature_detected;
use lazy_static::lazy_static;
use super::*;
lazy_static! {
pub static ref HASH: fn(data: &[u8], seed: u64) -> u64 = t1ha0_resolve();
}
#[cfg(not(target_feature = "aes"))]
pub use self::t1ha0_fallback as t1ha0_ia32aes_noavx;
#[cfg(not(target_feature = "avx"))]
pub use self::t1ha0_fallback as t1ha0_ia32aes_avx;
#[cfg(not(target_feature = "avx2"))]
pub use self::t1ha0_fallback as t1ha0_ia32aes_avx2;
fn t1ha0_resolve() -> fn(&[u8], u64) -> u64 {
if is_x86_feature_detected!("avx2") {
t1ha0_ia32aes_avx2
} else if is_x86_feature_detected!("avx") {
t1ha0_ia32aes_avx
} else if is_x86_feature_detected!("aes") {
t1ha0_ia32aes_noavx
} else {
t1ha0_fallback
}
}
} else {
pub use self::t1ha0_fallback as HASH;
}
}
}
#[cfg(test)]
mod selfcheck;