pub use const_num_traits::PrimInt;
use const_num_traits::{
BorrowingSub, CarryingAdd, OverflowingAdd, OverflowingSub, ToBytes, WideningMul,
};
c0nst::c0nst! {
pub c0nst trait ConstMachineWord:
[c0nst] PrimInt +
[c0nst] OverflowingAdd +
[c0nst] OverflowingSub +
[c0nst] CarryingAdd +
[c0nst] BorrowingSub +
[c0nst] ToBytes +
[c0nst] WideningMul +
[c0nst] core::ops::BitAndAssign +
[c0nst] core::ops::BitOrAssign +
[c0nst] core::ops::BitXorAssign +
[c0nst] core::ops::ShlAssign<usize> +
[c0nst] core::ops::ShrAssign<usize> +
[c0nst] core::ops::AddAssign +
[c0nst] core::ops::SubAssign +
[c0nst] From<u8>
{
type ConstDoubleWord: [c0nst] PrimInt
+ [c0nst] core::ops::BitAndAssign
+ [c0nst] core::ops::BitOrAssign
+ [c0nst] core::ops::AddAssign
+ [c0nst] core::ops::Mul<Output = Self::ConstDoubleWord>
+ [c0nst] core::ops::BitAnd<Output = Self::ConstDoubleWord>
+ [c0nst] core::ops::Shr<usize, Output = Self::ConstDoubleWord>;
fn to_double(self) -> Self::ConstDoubleWord;
fn from_double(word: Self::ConstDoubleWord) -> Self;
}
c0nst impl ConstMachineWord for u8 {
type ConstDoubleWord = u16;
fn to_double(self) -> u16 { self as u16 }
fn from_double(word: u16) -> u8 { word as u8 }
}
c0nst impl ConstMachineWord for u16 {
type ConstDoubleWord = u32;
fn to_double(self) -> u32 { self as u32 }
fn from_double(word: u32) -> u16 { word as u16 }
}
c0nst impl ConstMachineWord for u32 {
type ConstDoubleWord = u64;
fn to_double(self) -> u64 { self as u64 }
fn from_double(word: u64) -> u32 { word as u32 }
}
c0nst impl ConstMachineWord for u64 {
type ConstDoubleWord = u128;
fn to_double(self) -> u128 { self as u128 }
fn from_double(word: u128) -> u64 { word as u64 }
}
}
pub trait MachineWord:
ConstMachineWord<ConstDoubleWord = Self::DoubleWord>
+ core::hash::Hash
+ const_num_traits::ToPrimitive
{
type DoubleWord: PrimInt;
}
impl MachineWord for u8 {
type DoubleWord = u16;
}
impl MachineWord for u16 {
type DoubleWord = u32;
}
impl MachineWord for u32 {
type DoubleWord = u64;
}
impl MachineWord for u64 {
type DoubleWord = u128;
}
#[cfg(test)]
mod tests {
use super::*;
c0nst::c0nst! {
pub c0nst fn to_double<T: [c0nst] ConstMachineWord>(a: T) -> T::ConstDoubleWord {
a.to_double()
}
}
#[test]
fn test_constmachineword_ops() {
assert_eq!(to_double(200u8), 200u16);
#[cfg(feature = "nightly")]
{
const DOUBLE_RES: u16 = to_double(200u8);
assert_eq!(DOUBLE_RES, 200u16);
}
}
}