#[doc(no_inline)]
pub use bytemuck::Contiguous;
use typewit::TypeEq;
#[cfg(feature = "debug_checks")]
use crate::const_panic::PanicVal;
#[inline(always)]
pub const fn into_integer<T: Contiguous>(value: T) -> T::Int {
unsafe { __priv_transmute!(T, T::Int, value) }
}
macro_rules! declare_from_int_fns {
($(($fn_name:ident, $variant:ident, $Int:ident))*) => (
pub trait Integer: Copy + 'static {
#[doc(hidden)]
const __WITNESS: __IntegerWit<Self>;
}
#[allow(missing_debug_implementations)]
#[doc(hidden)]
#[non_exhaustive]
pub enum __IntegerWit<W> {
$(
$variant(TypeEq<W, $Int>),
)*
}
$(
impl Integer for $Int {
#[doc(hidden)]
const __WITNESS: __IntegerWit<$Int> = __IntegerWit::$variant(TypeEq::NEW);
}
)*
#[cold]
#[inline(never)]
#[track_caller]
#[cfg(feature = "debug_checks")]
const fn panic_impossible_bounds(min_value: PanicVal, max_value: PanicVal) -> ! {
crate::const_panic::concat_panic(&[&[
PanicVal::write_str("\n\
`T` implements `Contiguous` where \
`T::MIN_VALUE` is larger than `T::MAX_VALUE`\
"),
PanicVal::write_str("\nT::MIN_VALUE: "),
min_value,
PanicVal::write_str("\nT::MAX_VALUE: "),
max_value,
]])
}
#[track_caller]
pub const fn from_integer<T: Contiguous>(integer: T::Int) -> Option<T>
where
T::Int: Integer
{
match <T::Int>::__WITNESS {
$(
__IntegerWit::$variant(te) => {
let integer = te.to_right(integer);
let min_value = te.to_right(T::MIN_VALUE);
let max_value = te.to_right(T::MAX_VALUE);
#[cfg(feature = "debug_checks")]
if min_value > max_value {
use crate::const_panic::{FmtArg as FA};
panic_impossible_bounds(
PanicVal::$fn_name(min_value, FA::DEBUG),
PanicVal::$fn_name(max_value, FA::DEBUG),
);
}
if integer < min_value || max_value < integer {
return None;
}
}
)*
}
unsafe { Some(__priv_transmute_from_copy!(T::Int, T, integer)) }
}
);
}
declare_from_int_fns! {
(from_i8, I8, i8)
(from_i16, I16, i16)
(from_i32, I32, i32)
(from_i64, I64, i64)
(from_i128, I128, i128)
(from_isize, Isize, isize)
(from_u8, U8, u8)
(from_u16, U16, u16)
(from_u32, U32, u32)
(from_u64, U64, u64)
(from_u128, U128, u128)
(from_usize, Usize, usize)
}