use core::fmt::Debug;
use core::hash::Hash;
use core::num::NonZero;
pub unsafe trait KeyPiece: Copy + Eq + Ord + Hash + Debug + Send + Sync + 'static {
type NonZero: Copy + Eq + Ord + Hash + Debug + Send + Sync + 'static;
const ZERO: Self;
const ONE: Self;
fn checked_add(self, rhs: Self) -> Option<Self>;
fn is_odd(self) -> bool;
fn into_usize(self) -> Option<usize>;
fn from_usize(v: usize) -> Option<Self>;
fn into_non_zero(self) -> Option<Self::NonZero>;
fn from_non_zero(v: Self::NonZero) -> Self;
}
macro_rules! impl_key_piece {
($($t:ty)*) => {
$(
unsafe impl KeyPiece for $t {
type NonZero = NonZero<$t>;
const ZERO: Self = 0;
const ONE: Self = 1;
#[inline]
fn checked_add(self, rhs: Self) -> Option<Self> {
<$t>::checked_add(self, rhs)
}
#[inline]
fn is_odd(self) -> bool {
self & 1 == 1
}
#[inline]
fn into_usize(self) -> Option<usize> {
usize::try_from(self).ok()
}
#[inline]
fn from_usize(v: usize) -> Option<Self> {
<$t>::try_from(v).ok()
}
#[inline]
fn into_non_zero(self) -> Option<Self::NonZero> {
NonZero::new(self)
}
#[inline]
fn from_non_zero(v: Self::NonZero) -> Self {
v.get()
}
}
)*
};
}
impl_key_piece!(u8 u16 u32 u64 u128 usize);