use std::num::{
NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU16, NonZeroU32,
NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
};
use crate::Int;
pub trait IntKey: Copy {
type Int: Int;
const PRIME: Self::Int;
fn into_int(self) -> Self::Int;
}
macro_rules! impl_int_key_for_int {
($self:ident, $prime:expr) => {
impl IntKey for $self {
type Int = $self;
const PRIME: Self::Int = $prime;
fn into_int(self) -> Self::Int {
self
}
}
};
}
const U8_PRIME_MAX: u8 = u8::MAX - 4; const U16_PRIME_MAX: u16 = u16::MAX - 14; const U32_PRIME_MAX: u32 = u32::MAX - 4; const U64_PRIME_MAX: u64 = u64::MAX - 58; const U128_PRIME_MAX: u128 = u128::MAX - 158;
impl_int_key_for_int!(u8, U8_PRIME_MAX);
impl_int_key_for_int!(u16, U16_PRIME_MAX);
impl_int_key_for_int!(u32, U32_PRIME_MAX);
impl_int_key_for_int!(u64, U64_PRIME_MAX);
impl_int_key_for_int!(u128, U128_PRIME_MAX);
#[cfg(target_pointer_width = "16")]
impl_int_key_for_int!(usize, U16_PRIME_MAX as usize);
#[cfg(target_pointer_width = "32")]
impl_int_key_for_int!(usize, U32_PRIME_MAX as usize);
#[cfg(target_pointer_width = "64")]
impl_int_key_for_int!(usize, U64_PRIME_MAX as usize);
macro_rules! impl_int_key_for_signed_int {
($self:ident, $unsigned:ident) => {
impl IntKey for $self {
type Int = $unsigned;
const PRIME: Self::Int = $unsigned::PRIME;
fn into_int(self) -> Self::Int {
self as $unsigned
}
}
};
}
impl_int_key_for_signed_int!(i8, u8);
impl_int_key_for_signed_int!(i16, u16);
impl_int_key_for_signed_int!(i32, u32);
impl_int_key_for_signed_int!(i64, u64);
impl_int_key_for_signed_int!(i128, u128);
impl_int_key_for_signed_int!(isize, usize);
macro_rules! impl_int_key_for_non_zero_int {
($non_zero_int:ident, $int:ident) => {
impl IntKey for $non_zero_int {
type Int = <$int as IntKey>::Int;
const PRIME: Self::Int = $int::PRIME;
fn into_int(self) -> Self::Int {
self.get().into_int()
}
}
};
}
impl_int_key_for_non_zero_int!(NonZeroU8, u8);
impl_int_key_for_non_zero_int!(NonZeroU16, u16);
impl_int_key_for_non_zero_int!(NonZeroU32, u32);
impl_int_key_for_non_zero_int!(NonZeroU64, u64);
impl_int_key_for_non_zero_int!(NonZeroUsize, usize);
impl_int_key_for_non_zero_int!(NonZeroI8, i8);
impl_int_key_for_non_zero_int!(NonZeroI16, i16);
impl_int_key_for_non_zero_int!(NonZeroI32, i32);
impl_int_key_for_non_zero_int!(NonZeroI64, i64);
impl_int_key_for_non_zero_int!(NonZeroIsize, isize);
impl<K: IntKey> IntKey for Wrapping<K> {
type Int = K::Int;
const PRIME: Self::Int = K::PRIME;
fn into_int(self) -> Self::Int {
self.0.into_int()
}
}
impl IntKey for std::net::Ipv4Addr {
type Int = u32;
const PRIME: Self::Int = u32::PRIME;
fn into_int(self) -> Self::Int {
u32::from_be_bytes(self.octets())
}
}
impl IntKey for std::net::Ipv6Addr {
type Int = u128;
const PRIME: Self::Int = u128::PRIME;
fn into_int(self) -> Self::Int {
u128::from_be_bytes(self.octets())
}
}