use crate::scalar::MaterializableScalar;
pub trait VeScalar: MaterializableScalar + sealed::Sealed {
fn to_raw_bits(self) -> u32;
fn from_raw_bits(bits: u32) -> Self;
fn lt_scalar(self, other: Self) -> bool;
fn reinterpret<D2: VeScalar>(self) -> D2 {
D2::from_raw_bits(self.to_raw_bits())
}
}
mod sealed {
pub trait Sealed {}
impl Sealed for i32 {}
impl Sealed for f32 {}
}
impl VeScalar for i32 {
fn to_raw_bits(self) -> u32 {
self as u32
}
fn from_raw_bits(bits: u32) -> Self {
bits as i32
}
fn lt_scalar(self, other: Self) -> bool {
self < other
}
}
impl VeScalar for f32 {
fn to_raw_bits(self) -> u32 {
self.to_bits()
}
fn from_raw_bits(bits: u32) -> Self {
Self::from_bits(bits)
}
fn lt_scalar(self, other: Self) -> bool {
self < other
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn reinterpret_preserves_the_bits() {
for bits in [0u32, 0x8000_0000, 0x7fff_ffff, 0x0080_0000, 1, 0x7fc0_0000] {
let x = f32::from_raw_bits(bits);
assert_eq!(x.reinterpret::<i32>(), bits as i32);
assert_eq!(x.reinterpret::<i32>().reinterpret::<f32>().to_raw_bits(), bits);
assert_eq!(x.reinterpret::<f32>().to_raw_bits(), bits);
}
assert_eq!(i32::MIN.reinterpret::<f32>().to_raw_bits(), 0x8000_0000);
assert_eq!((-1i32).reinterpret::<f32>().to_raw_bits(), u32::MAX);
}
}