use super::*;
pub unsafe trait Contiguous: Copy + 'static {
type Int: Copy + Ord;
const MAX_VALUE: Self::Int;
const MIN_VALUE: Self::Int;
#[inline]
fn from_integer(value: Self::Int) -> Option<Self> {
assert!(size_of::<Self>() == size_of::<Self::Int>());
if Self::MIN_VALUE <= value && value <= Self::MAX_VALUE {
Some(unsafe { transmute!(value) })
} else {
None
}
}
#[inline]
fn into_integer(self) -> Self::Int {
assert!(size_of::<Self>() == size_of::<Self::Int>());
unsafe { transmute!(self) }
}
}
macro_rules! impl_contiguous {
($($src:ty as $repr:ident in [$min:expr, $max:expr];)*) => {$(
unsafe impl Contiguous for $src {
type Int = $repr;
const MAX_VALUE: $repr = $max;
const MIN_VALUE: $repr = $min;
}
)*};
}
impl_contiguous! {
bool as u8 in [0, 1];
u8 as u8 in [0, u8::max_value()];
u16 as u16 in [0, u16::max_value()];
u32 as u32 in [0, u32::max_value()];
u64 as u64 in [0, u64::max_value()];
u128 as u128 in [0, u128::max_value()];
usize as usize in [0, usize::max_value()];
i8 as i8 in [i8::min_value(), i8::max_value()];
i16 as i16 in [i16::min_value(), i16::max_value()];
i32 as i32 in [i32::min_value(), i32::max_value()];
i64 as i64 in [i64::min_value(), i64::max_value()];
i128 as i128 in [i128::min_value(), i128::max_value()];
isize as isize in [isize::min_value(), isize::max_value()];
NonZeroU8 as u8 in [1, u8::max_value()];
NonZeroU16 as u16 in [1, u16::max_value()];
NonZeroU32 as u32 in [1, u32::max_value()];
NonZeroU64 as u64 in [1, u64::max_value()];
NonZeroU128 as u128 in [1, u128::max_value()];
NonZeroUsize as usize in [1, usize::max_value()];
}