#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
macro_rules! bits_enum{
($t:ident) => {
crate::bits_enum::BitsEnum<
$t<u8>,
$t<u16>,
>
};
($t:ident, $extra_lifetime:lifetime) => {
crate::bits_enum::BitsEnum<
$t<$extra_lifetime, u8>,
$t<$extra_lifetime, u16>,
>
};
(impl $t:ident) => {
crate::bits_enum::BitsEnum<
impl $t<u8>,
impl $t<u16>,
>
};
($tu8:ty, $tu16:ty, $tu32:ty, $tu64:ty) => {
crate::bits_enum::BitsEnum<
$tu8,
$tu16,
>
};
}
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
macro_rules! common_strct{
($t:ident) => {
crate::common::Common<
$t<u8>,
$t<u16>,
>
};
($t:ident, $extra_lifetime:lifetime) => {
crate::common::Common<
$t<$extra_lifetime, u8>,
$t<$extra_lifetime, u16>,
>
};
($tu8:ty, $tu16:ty, $tu32:ty, $tu64:ty) => {
crate::common::Common<
$tu8,
$tu16,
>
};
}
#[cfg(target_pointer_width = "32")]
macro_rules! bits_enum{
($t:ident) => {
crate::bits_enum::BitsEnum<
$t<u8>,
$t<u16>,
$t<u32>,
>
};
($t:ident, $extra_lifetime:lifetime) => {
crate::bits_enum::BitsEnum<
$t<$extra_lifetime, u8>,
$t<$extra_lifetime, u16>,
$t<$extra_lifetime, u32>,
>
};
(impl $t:ident) => {
crate::bits_enum::BitsEnum<
impl $t<u8>,
impl $t<u16>,
impl $t<u32>,
>
};
($tu8:ty, $tu16:ty, $tu32:ty, $tu64:ty) => {
crate::bits_enum::BitsEnum<
$tu8,
$tu16,
$tu32,
>
};
}
#[cfg(target_pointer_width = "32")]
macro_rules! common_strct{
($t:ident) => {
crate::common::Common<
$t<u8>,
$t<u16>,
$t<u32>,
>
};
($t:ident, $extra_lifetime:lifetime) => {
crate::common::Common<
$t<$extra_lifetime, u8>,
$t<$extra_lifetime, u16>,
$t<$extra_lifetime, u32>,
>
};
($tu8:ty, $tu16:ty, $tu32:ty, $tu64:ty) => {
crate::common::Common<
$tu8,
$tu16,
$tu32,
>
};
}
#[cfg(target_pointer_width = "64")]
macro_rules! bits_enum{
($t:ident) => {
crate::bits_enum::BitsEnum<
$t<u8>,
$t<u16>,
$t<u32>,
$t<u64>,
>
};
($t:ident, $extra_lifetime:lifetime) => {
crate::bits_enum::BitsEnum<
$t<$extra_lifetime, u8>,
$t<$extra_lifetime, u16>,
$t<$extra_lifetime, u32>,
$t<$extra_lifetime, u64>,
>
};
(impl $t:ident) => {
crate::bits_enum::BitsEnum<
impl $t<u8>,
impl $t<u16>,
impl $t<u32>,
impl $t<u64>,
>
};
($tu8:ty, $tu16:ty, $tu32:ty, $tu64:ty) => {
crate::bits_enum::BitsEnum<
$tu8,
$tu16,
$tu32,
$tu64,
>
};
}
#[cfg(target_pointer_width = "64")]
macro_rules! common_strct{
($t:ident) => {
crate::common::Common<
$t<u8>,
$t<u16>,
$t<u32>,
$t<u64>,
>
};
($t:ident, $extra_lifetime:lifetime) => {
crate::common::Common<
$t<$extra_lifetime, u8>,
$t<$extra_lifetime, u16>,
$t<$extra_lifetime, u32>,
$t<$extra_lifetime, u64>,
>
};
($tu8:ty, $tu16:ty, $tu32:ty, $tu64:ty) => {
crate::common::Common<
$tu8,
$tu16,
$tu32,
$tu64,
>
};
}
macro_rules! for_current_bitness {
($this:expr; $matched:ident; $e:expr) => {
match $this {
crate::bits_enum::BitsEnum::U8($matched) => {
#[allow(unused)]
use crate::bits_enum::BitsEnum::U8 as CurrentBitness;
$e
}
crate::bits_enum::BitsEnum::U16($matched) => {
#[allow(unused)]
use crate::bits_enum::BitsEnum::U16 as CurrentBitness;
$e
}
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
crate::bits_enum::BitsEnum::U32($matched) => {
#[allow(unused)]
use crate::bits_enum::BitsEnum::U32 as CurrentBitness;
$e
}
#[cfg(target_pointer_width = "64")]
crate::bits_enum::BitsEnum::U64($matched) => {
#[allow(unused)]
use crate::bits_enum::BitsEnum::U64 as CurrentBitness;
$e
}
}
};
}
macro_rules! choose_by_size {
($size: expr, $e:expr) => {
{
#[allow(clippy::assertions_on_constants, clippy::cast_possible_truncation)]
const MAX_U8: usize = {
assert!(u8::BITS <= usize::BITS);
u8::MAX as usize
};
#[allow(clippy::assertions_on_constants, clippy::cast_possible_truncation)]
const MAX_U16: usize = {
assert!(u16::BITS <= usize::BITS);
u16::MAX as usize
};
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
#[allow(clippy::assertions_on_constants, clippy::cast_possible_truncation)]
const MAX_U32: usize = {
assert!(u32::BITS <= usize::BITS);
u32::MAX as usize
};
#[cfg(target_pointer_width = "64")]
#[allow(clippy::assertions_on_constants, clippy::cast_possible_truncation)]
const MAX_U64: usize = {
assert!(u64::BITS <= usize::BITS);
u64::MAX as usize
};
#[allow(clippy::match_overlapping_arm)]
match $size {
..=MAX_U8 => {
#[allow(unused)]
type ChosenTagType = u8;
crate::bits_enum::BitsEnum::U8($e)
},
..=MAX_U16 => {
#[allow(unused)]
type ChosenTagType = u16;
crate::bits_enum::BitsEnum::U16($e)
},
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
..=MAX_U32 => {
#[allow(unused)]
type ChosenTagType = u32;
crate::bits_enum::BitsEnum::U32($e)
},
#[cfg(target_pointer_width = "64")]
..=MAX_U64 => {
#[allow(unused)]
type ChosenTagType = u64;
crate::bits_enum::BitsEnum::U64($e)
},
_ => unreachable!("We checked all ranges of usize"),
}
}
};
}
macro_rules! check_bounds {
($storage:expr; $($idx:ident),+) => {
{
let lower_bound: usize = (& $storage).lower_bound();
let upper_bound: usize = (& $storage).upper_bound();
$(
assert!(
lower_bound <= $idx && $idx < upper_bound,
"{} ({}) is out of bounds {}..{}",
stringify!($idx),
$idx,
lower_bound,
upper_bound
);
)+
}
};
(multibit $storage:expr; $($idx:ident),+) => {
{
let (lower_bound, upper_bound): (usize, usize) =
crate::macros::for_current_bitness!(
(& $storage); s; (s.lower_bound(), s.upper_bound())
);
$(
assert!(
lower_bound <= $idx && $idx < upper_bound,
"{} ({}) is out of bounds {}..{}",
stringify!($idx),
$idx,
lower_bound,
upper_bound
);
)+
}
};
}
pub(crate) use bits_enum;
pub(crate) use check_bounds;
pub(crate) use choose_by_size;
pub(crate) use common_strct;
pub(crate) use for_current_bitness;
#[cfg(test)]
mod tests {
use crate::bits_enum::BitsEnum;
use crate::tag_type::TagType;
#[test]
fn choose_by_size() {
let v = choose_by_size!(255, ());
assert!(matches!(v, BitsEnum::U8(())));
let v = choose_by_size!(256, ());
assert!(matches!(v, BitsEnum::U16(())));
let v = choose_by_size!(65535, ());
assert!(matches!(v, BitsEnum::U16(())));
#[cfg(target_pointer_width = "32")]
{
let v = choose_by_size!(65536, ());
assert!(matches!(v, BitsEnum::U32(())));
let v = choose_by_size!(u32::MAX.as_u(), ());
assert!(matches!(v, BitsEnum::U32(())));
}
#[cfg(target_pointer_width = "64")]
{
let v = choose_by_size!(1 + u32::MAX.as_u(), ());
assert!(matches!(v, BitsEnum::U64(())));
let v = choose_by_size!(u64::MAX.as_u(), ());
assert!(matches!(v, BitsEnum::U64(())));
}
}
}