#![deny(rustdoc::broken_intra_doc_links)]
use crate::core::policies::{Native64RawRealStrictFinitePolicy, validate_in_debug};
use duplicate::duplicate_item;
pub trait Max: PartialOrd + Sized {
fn max_by_ref<'a>(&'a self, other: &'a Self) -> &'a Self {
if self >= other { self } else { other }
}
fn max_by_value(self, other: Self) -> Self {
if self >= other { self } else { other }
}
}
pub trait Min: PartialOrd + Sized {
fn min_by_ref<'a>(&'a self, other: &'a Self) -> &'a Self {
if self <= other { self } else { other }
}
fn min_by_value(self, other: Self) -> Self {
if self <= other { self } else { other }
}
}
#[duplicate_item(
trait_name func_by_ref func_by_value implementation;
[Max] [max_by_ref] [max_by_value] [if self >= other { self } else { other }];
[Min] [min_by_ref] [min_by_value] [if self <= other { self } else { other }];
)]
impl trait_name for f64 {
fn func_by_ref<'a>(&'a self, other: &'a Self) -> &'a Self {
validate_in_debug::<Native64RawRealStrictFinitePolicy>(self, "left");
validate_in_debug::<Native64RawRealStrictFinitePolicy>(other, "right");
implementation
}
fn func_by_value(self, other: Self) -> Self {
validate_in_debug::<Native64RawRealStrictFinitePolicy>(&self, "left");
validate_in_debug::<Native64RawRealStrictFinitePolicy>(&other, "right");
implementation
}
}
#[cfg(test)]
mod tests {
use super::*;
mod max {
use super::*;
mod native64 {
use super::*;
#[test]
fn test_f64_max_valid() {
let a = 3.0;
let b = 5.0;
let expected_result = 5.0;
assert_eq!(Max::max_by_ref(&a, &b), &expected_result);
assert_eq!(Max::max_by_value(a, b), expected_result);
}
#[test]
fn test_f64_max_equal_values() {
let a = 3.0;
let b = 3.0;
let expected_result = 3.0;
assert_eq!(Max::max_by_ref(&a, &b), &expected_result);
assert_eq!(Max::max_by_value(a, b), expected_result);
}
#[test]
fn test_f64_max_negative_values() {
let a = -3.0;
let b = -5.0;
let expected_result = -3.0;
assert_eq!(Max::max_by_ref(&a, &b), &expected_result);
assert_eq!(Max::max_by_value(a, b), expected_result);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "Debug validation of left value failed: Value is NaN")]
fn test_f64_max_nan_value() {
let a = f64::NAN;
let b = 5.0;
let _result = Max::max_by_ref(&a, &b);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "Debug validation of right value failed: Value is NaN")]
fn test_f64_max_nan_other() {
let a = 3.0;
let b = f64::NAN;
let _result = Max::max_by_ref(&a, &b);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(
expected = "Debug validation of left value failed: Value is positive infinity"
)]
fn test_f64_max_infinite_value() {
let a = f64::INFINITY;
let b = 5.0;
let _result = Max::max_by_ref(&a, &b);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(
expected = "Debug validation of right value failed: Value is positive infinity"
)]
fn test_f64_max_infinite_other() {
let a = 3.0;
let b = f64::INFINITY;
let _result = Max::max_by_ref(&a, &b);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(
expected = "Debug validation of left value failed: Value is negative infinity"
)]
fn test_f64_max_neg_infinite_value() {
let a = f64::NEG_INFINITY;
let b = 5.0;
let _result = Max::max_by_ref(&a, &b);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(
expected = "Debug validation of right value failed: Value is negative infinity"
)]
fn test_f64_max_neg_infinite_other() {
let a = 3.0;
let b = f64::NEG_INFINITY;
let _result = Max::max_by_ref(&a, &b);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "Debug validation of left value failed: Value is subnormal")]
fn test_f64_max_subnormal_value() {
let a = f64::MIN_POSITIVE / 2.0;
let b = 5.0;
let _result = Max::max_by_ref(&a, &b);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "Debug validation of right value failed: Value is subnormal")]
fn test_f64_max_subnormal_other() {
let a = 3.0;
let b = f64::MIN_POSITIVE / 2.0;
let _result = Max::max_by_ref(&a, &b);
}
}
mod native64_strict_finite {
use try_create::TryNew;
use super::*;
use crate::backends::native64::validated::RealNative64StrictFinite;
#[test]
fn test_f64_max_validated() {
let a = RealNative64StrictFinite::try_new(3.0).unwrap();
let b = RealNative64StrictFinite::try_new(5.0).unwrap();
let expected_result = RealNative64StrictFinite::try_new(5.0).unwrap();
assert_eq!(Max::max_by_ref(&a, &b), &expected_result);
assert_eq!(Max::max_by_value(a, b), expected_result);
}
#[test]
fn test_f64_max_validated_equal() {
let a = RealNative64StrictFinite::try_new(3.0).unwrap();
let b = RealNative64StrictFinite::try_new(3.0).unwrap();
let expected_result = RealNative64StrictFinite::try_new(3.0).unwrap();
assert_eq!(Max::max_by_ref(&a, &b), &expected_result);
assert_eq!(Max::max_by_value(a, b), expected_result);
}
}
}
mod min {
use super::*;
mod native64 {
use super::*;
#[test]
fn test_f64_min_valid() {
let a = 3.0;
let b = 5.0;
let expected_result = 3.0;
assert_eq!(Min::min_by_ref(&a, &b), &expected_result);
assert_eq!(Min::min_by_value(a, b), expected_result);
}
#[test]
fn test_f64_min_equal_values() {
let a = 3.0;
let b = 3.0;
let expected_result = 3.0;
assert_eq!(Min::min_by_ref(&a, &b), &expected_result);
assert_eq!(Min::min_by_value(a, b), expected_result);
}
#[test]
fn test_f64_min_negative_values() {
let a = -3.0;
let b = -5.0;
let expected_result = -5.0;
assert_eq!(Min::min_by_ref(&a, &b), &expected_result);
assert_eq!(Min::min_by_value(a, b), expected_result);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "Debug validation of left value failed: Value is NaN")]
fn test_f64_min_nan_value() {
let a = f64::NAN;
let b = 5.0;
let _result = Min::min_by_ref(&a, &b);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "Debug validation of right value failed: Value is NaN")]
fn test_f64_min_nan_other() {
let a = 3.0;
let b = f64::NAN;
let _result = Min::min_by_ref(&a, &b);
}
}
mod native64_strict_finite {
use try_create::TryNew;
use super::*;
use crate::backends::native64::validated::RealNative64StrictFinite;
#[test]
fn test_f64_min_validated() {
let a = RealNative64StrictFinite::try_new(3.0).unwrap();
let b = RealNative64StrictFinite::try_new(5.0).unwrap();
let expected_result = RealNative64StrictFinite::try_new(3.0).unwrap();
assert_eq!(Min::min_by_ref(&a, &b), &expected_result);
assert_eq!(Min::min_by_value(a, b), expected_result);
}
#[test]
fn test_f64_min_validated_equal() {
let a = RealNative64StrictFinite::try_new(3.0).unwrap();
let b = RealNative64StrictFinite::try_new(3.0).unwrap();
let expected_result = RealNative64StrictFinite::try_new(3.0).unwrap();
assert_eq!(Min::min_by_ref(&a, &b), &expected_result);
assert_eq!(Min::min_by_value(a, b), expected_result);
}
}
}
}