use super::{FixedUInt, MachineWord};
use crate::const_numtraits::ConstMidpoint;
use crate::machineword::ConstMachineWord;
c0nst::c0nst! {
impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> c0nst ConstMidpoint for FixedUInt<T, N> {
fn midpoint(self, rhs: Self) -> Self {
(self & rhs) + ((self ^ rhs) >> 1usize)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_midpoint() {
type U16 = FixedUInt<u8, 2>;
assert_eq!(
ConstMidpoint::midpoint(U16::from(0u8), U16::from(10u8)),
U16::from(5u8)
);
assert_eq!(
ConstMidpoint::midpoint(U16::from(10u8), U16::from(0u8)),
U16::from(5u8)
);
assert_eq!(
ConstMidpoint::midpoint(U16::from(0u8), U16::from(9u8)),
U16::from(4u8)
);
assert_eq!(
ConstMidpoint::midpoint(U16::from(42u8), U16::from(42u8)),
U16::from(42u8)
);
let max = U16::from(0xFFFFu16);
assert_eq!(ConstMidpoint::midpoint(max, max), max);
assert_eq!(
ConstMidpoint::midpoint(U16::from(0u8), max),
U16::from(0x7FFFu16)
);
}
c0nst::c0nst! {
pub c0nst fn const_midpoint<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(
a: FixedUInt<T, N>,
b: FixedUInt<T, N>,
) -> FixedUInt<T, N> {
ConstMidpoint::midpoint(a, b)
}
}
#[test]
fn test_const_midpoint() {
type U16 = FixedUInt<u8, 2>;
assert_eq!(
const_midpoint(U16::from(0u8), U16::from(10u8)),
U16::from(5u8)
);
#[cfg(feature = "nightly")]
{
const A: U16 = FixedUInt { array: [0, 0] };
const B: U16 = FixedUInt { array: [10, 0] };
const MID: U16 = const_midpoint(A, B);
assert_eq!(MID, FixedUInt { array: [5, 0] });
const MAX: U16 = FixedUInt {
array: [0xFF, 0xFF],
};
const MID_MAX: U16 = const_midpoint(MAX, MAX);
assert_eq!(MID_MAX, MAX);
}
}
#[test]
fn test_midpoint_polymorphic() {
fn test_mid<T>(a: T, b: T, expected: T)
where
T: ConstMidpoint + Eq + core::fmt::Debug + Copy,
{
assert_eq!(ConstMidpoint::midpoint(a, b), expected);
assert_eq!(ConstMidpoint::midpoint(b, a), expected); }
type U8x2 = FixedUInt<u8, 2>;
type U8x4 = FixedUInt<u8, 4>;
type U16x2 = FixedUInt<u16, 2>;
test_mid(U8x2::from(0u8), U8x2::from(100u8), U8x2::from(50u8));
test_mid(U8x4::from(0u8), U8x4::from(100u8), U8x4::from(50u8));
test_mid(U16x2::from(0u8), U16x2::from(100u8), U16x2::from(50u8));
test_mid(0u8, 100u8, 50u8);
test_mid(0u16, 100u16, 50u16);
test_mid(0u32, 100u32, 50u32);
test_mid(U8x2::from(0u8), U8x2::from(99u8), U8x2::from(49u8));
test_mid(0u8, 99u8, 49u8);
let max_u16 = U8x2::from(0xFFFFu16);
test_mid(max_u16, max_u16, max_u16);
test_mid(u16::MAX, u16::MAX, u16::MAX);
}
}