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;
const MAX: Self;
const BITS: u32;
fn checked_add(self, rhs: Self) -> Option<Self>;
fn wrapping_add(self, rhs: Self) -> Self;
fn is_odd(self) -> bool;
fn into_usize(self) -> Option<usize>;
unsafe fn into_usize_unchecked(self) -> usize;
fn from_usize(v: usize) -> Option<Self>;
unsafe fn from_usize_unchecked(v: usize) -> Self;
fn into_non_zero(self) -> Option<Self::NonZero>;
unsafe fn into_non_zero_unchecked(self) -> Self::NonZero;
fn from_non_zero(v: Self::NonZero) -> Self;
fn into_u128(self) -> u128;
fn from_u128(v: u128) -> Option<Self>;
unsafe fn from_u128_unchecked(v: u128) -> 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;
const MAX: Self = <$t>::MAX;
const BITS: u32 = <$t>::BITS;
#[inline]
fn checked_add(self, rhs: Self) -> Option<Self> {
<$t>::checked_add(self, rhs)
}
#[inline]
fn wrapping_add(self, rhs: Self) -> Self {
<$t>::wrapping_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]
unsafe fn into_usize_unchecked(self) -> usize {
debug_assert!(usize::try_from(self).is_ok());
self as usize
}
#[inline]
fn from_usize(v: usize) -> Option<Self> {
<$t>::try_from(v).ok()
}
#[inline]
unsafe fn from_usize_unchecked(v: usize) -> Self {
debug_assert!(<$t>::try_from(v).is_ok());
v as $t
}
#[inline]
fn into_non_zero(self) -> Option<Self::NonZero> {
NonZero::new(self)
}
#[inline]
unsafe fn into_non_zero_unchecked(self) -> Self::NonZero {
debug_assert!(self != 0);
unsafe { NonZero::new_unchecked(self) }
}
#[inline]
fn from_non_zero(v: Self::NonZero) -> Self {
v.get()
}
#[inline]
fn into_u128(self) -> u128 {
self as u128
}
#[inline]
fn from_u128(v: u128) -> Option<Self> {
<$t>::try_from(v).ok()
}
#[inline]
unsafe fn from_u128_unchecked(v: u128) -> Self {
debug_assert!(<$t>::try_from(v).is_ok());
v as $t
}
}
)*
};
}
impl_key_piece!(u8 u16 u32 u64 u128 usize);