#[allow(non_snake_case)]
pub fn Less<T: PartialOrd>(x: &T, y: &T) -> bool {
if let Some(o) = x.partial_cmp(y) {
return o == std::cmp::Ordering::Less;
}
x != x && y == y
}
#[allow(non_snake_case)]
pub fn Compare<T: PartialOrd>(x: &T, y: &T) -> crate::types::int {
let x_nan = x != x;
let y_nan = y != y;
if x_nan {
return if y_nan { 0 } else { -1 };
}
if y_nan {
return 1;
}
match x.partial_cmp(y) {
Some(std::cmp::Ordering::Less) => -1,
Some(std::cmp::Ordering::Greater) => 1,
_ => 0,
}
}
#[allow(non_snake_case)]
pub fn Or<T: PartialEq + Default + Clone>(vals: &[T]) -> T {
let zero = T::default();
for v in vals {
if *v != zero {
return v.clone();
}
}
zero
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn less_int() {
assert!(Less(&1, &2));
assert!(!Less(&2, &1));
assert!(!Less(&1, &1));
}
#[test]
fn less_float_nan() {
assert!(Less(&f64::NAN, &0.0));
assert!(!Less(&0.0, &f64::NAN));
assert!(!Less(&f64::NAN, &f64::NAN));
}
#[test]
fn compare_int() {
assert_eq!(Compare(&1, &2), -1);
assert_eq!(Compare(&2, &1), 1);
assert_eq!(Compare(&5, &5), 0);
}
#[test]
fn compare_float_nan() {
assert_eq!(Compare(&f64::NAN, &f64::NAN), 0);
assert_eq!(Compare(&f64::NAN, &1.0), -1);
assert_eq!(Compare(&1.0, &f64::NAN), 1);
}
#[test]
fn or_picks_first_nonzero() {
assert_eq!(Or(&[0i64, 0, 42, 100]), 42);
assert_eq!(Or::<i64>(&[0, 0, 0]), 0);
assert_eq!(Or::<String>(&[String::new(), "hi".into()]), "hi");
}
}