mod traits;
pub use self::traits::Integer;
use std::cmp::Ordering;
macro_rules! imp {
($lhs:expr, $rhs:expr, |$min:ident, $max:ident| $align:expr) => {{
let (lhs, rhs) = ($lhs, $rhs);
let (lhs, rhs, reversed) = if lhs.copy().lt(rhs.copy()) {
(rhs, lhs, true)
} else if lhs.copy().eq(rhs.copy()) {
return Ordering::Equal;
} else {
(lhs, rhs, false)
};
let lhs = match (lhs.copy(), rhs.copy()) {
($max, $min) => $align,
};
if lhs.lt(rhs) ^ reversed {
Ordering::Less
} else {
Ordering::Greater
}
}};
}
#[must_use]
pub fn cmp_int<T: Integer>(lhs: T, rhs: T, radix: u32) -> Ordering {
if radix == 0 {
panic!("`radix` must be greater than 0");
}
imp!(lhs, rhs, |min, max| max
.copy()
.invpow(radix, max.ilog(radix) - min.ilog(radix)))
}
#[must_use]
pub fn cmp_dec<T: Integer>(lhs: T, rhs: T) -> Ordering {
imp!(lhs, rhs, |min, max| max
.copy()
.invpow(10_u32, max.ilog10() - min.ilog10()))
}
#[cfg(test)]
mod tests {
#[cfg(not(feature = "alloc"))]
extern crate alloc;
use alloc::string::ToString;
use super::*;
#[test]
fn matches_str_cmp() {
#[track_caller]
fn check<T: Copy + Integer + Ord + ToString>(lhs: T, rhs: T) {
let expected = lhs.to_string().cmp(&rhs.to_string());
assert_eq!(cmp_int(lhs, rhs, 10), expected);
assert_eq!(cmp_int(rhs, lhs, 10), expected.reverse(), "reverse");
assert_eq!(cmp_dec(lhs, rhs), expected, "dec");
assert_eq!(cmp_dec(rhs, lhs), expected.reverse(), "dec,reverse");
assert_eq!(cmp_int(lhs, rhs, 1), lhs.cmp(&rhs));
assert_eq!(cmp_int(rhs, lhs, 1), rhs.cmp(&lhs));
}
check(0_u64, 0_u64);
check(1_u64, 0_u64);
check(10_u64, 0_u64);
check(42_u64, 0_u64);
check(1_u64, 1_u64);
check(1_u64, 4_u64);
check(2_u64, 42_u64);
check(4_u64, 42_u64);
check(5_u64, 42_u64);
check(2_u64, 40_u64);
check(4_u64, 40_u64);
check(5_u64, 40_u64);
check(42_u64, 24_u64);
check(42_u64, 20_u64);
check(42_u64, 42_u64);
check(42_u64, 40_u64);
check(42_u64, 41_u64);
check(42_u64, 43_u64);
check(42_u64, 52_u64);
check(42_u64, 50_u64);
check(42_u64, 200_u64);
check(42_u64, 240_u64);
check(42_u64, 241_u64);
check(42_u64, 2410_u64);
check(42_u64, 410_u64);
check(42_u64, 411_u64);
check(42_u64, 4100_u64);
check(42_u64, 4110_u64);
check(42_u64, 4111_u64);
check(42_u64, 420_u64);
check(42_u64, 421_u64);
check(42_u64, 4211_u64);
check(42_u64, 4200_u64);
check(42_u64, 4210_u64);
check(42_u64, 430_u64);
check(42_u64, 431_u64);
check(42_u64, 4300_u64);
check(42_u64, 4310_u64);
check(42_u64, 4311_u64);
check(42_u64, 500_u64);
check(42_u64, 540_u64);
check(42_u64, 542_u64);
check(42_u64, 5420_u64);
check(u8::MAX, 1);
check(u8::MAX, u8::MAX - 1);
check(u16::MAX, 1);
check(u16::MAX, u16::MAX - 1);
check(u32::MAX, 1);
check(u32::MAX, u32::MAX - 1);
check(u64::MAX, 1);
check(u64::MAX, u64::MAX - 1);
check(usize::MAX, 1);
check(usize::MAX, usize::MAX - 1);
check(u128::MAX, 1);
check(u128::MAX, u128::MAX - 1);
}
}