pub mod op;
pub mod cast;
use cast::Cast;
use op::Operate;
use paste::item;
macro_rules! integer_list {
($target_macro:path $(=> $lead_tt:tt)?) => {
$target_macro!(
$($lead_tt as)?
8 16 32 64 128 size
);
};
}
macro_rules! impl_primitive_macros {
(
$(
$target_pospend:tt
)*
) => {
$crate::primitive::item! {
macro_rules! primitive_list {
($target_macro:path => $lead_tt:tt) => {
$target_macro!(
$lead_tt as
$(
[< u $target_pospend >]
[< i $target_pospend >]
)*
);
};
($target_macro:path) => {
$target_macro!(
$(
[< u $target_pospend >]
[< i $target_pospend >]
)*
);
};
}
macro_rules! signed {
$(
([< u $target_pospend >]) => { [< i $target_pospend >] };
)*
($target_type:ty) => { $target_type };
}
macro_rules! unsigned {
$(
([< i $target_pospend >]) => { [< u $target_pospend >] };
)*
($target_type:ty) => { $target_type };
}
macro_rules! is_signed {
$(
([< i $target_pospend >]) => { true };
([< u $target_pospend >]) => { false };
)*
}
#[allow(unused_macros)]
macro_rules! signed_list {
($target_macro:path => $lead_tt:tt) => {
$target_macro!(
$lead_tt as
$(
[< i $target_pospend >]
)*
);
};
($target_macro:path) => {
$target_macro!(
$(
[< i $target_pospend >]
)*
);
};
}
#[allow(unused_macros)]
macro_rules! unsigned_list {
($target_macro:path => $lead_tt:tt) => {
$target_macro!(
$lead_tt as
$(
[< u $target_pospend >]
)*
);
};
($target_macro:path) => {
$target_macro!(
$(
[< u $target_pospend >]
)*
);
};
}
}
pub(crate) use primitive_list;
pub(crate) use signed;
pub(crate) use unsigned;
pub(crate) use is_signed;
#[allow(unused_imports)]
pub(crate) use signed_list;
#[allow(unused_imports)]
pub(crate) use unsigned_list;
}
}
macro_rules! impl_primitive {
(
$target_trait:ty as
$(
$target_type:ident
)+
) => {
$(
impl $crate::private::Sealed for $target_type {}
impl $target_trait for $target_type {
type Signed = $crate::primitive::signed!($target_type);
type Unsigned = $crate::primitive::unsigned!($target_type);
const SIGNED: bool = $crate::primitive::is_signed!($target_type);
const MIN: Self = <$target_type>::MIN;
const MAX: Self = <$target_type>::MAX;
const BITS: u8 = <$target_type>::BITS as _;
}
)+
};
(
$(
$target_pospend:tt
)*
) => {
$crate::primitive::impl_primitive_macros! {
$(
$target_pospend
)*
}
$crate::primitive::primitive_list!($crate::primitive::impl_primitive => Primitive);
};
}
macro_rules! marker {
(
$target_trait:ident as $($target_type:ident)*
) => {
$(
impl $target_trait for $target_type {}
)*
};
}
pub(self) use impl_primitive;
pub(self) use impl_primitive_macros;
pub(self) use integer_list;
integer_list!(impl_primitive);
pub trait Signed: crate::private::Sealed {}
pub trait Unsigned: crate::private::Sealed {}
signed_list!(marker => Signed);
unsigned_list!(marker => Unsigned);
pub trait Primitive: Operate + crate::private::Sealed {
type Signed: Primitive + Cast<Self>;
type Unsigned: Primitive + Cast<Self>;
const SIGNED: bool;
const MIN: Self;
const MAX: Self;
const BITS: u8;
}