use float_ord::FloatOrd;
use num::traits::Zero;
use std::{
cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
hash::{Hash, Hasher},
ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign},
};
#[derive(Clone, Copy, Debug)]
pub struct Cost<Num>(pub Num);
macro_rules! cost_impl {
($f:ident) => {
impl Cost<$f> {
fn convert(self) -> FloatOrd<$f> {
FloatOrd(self.0)
}
}
impl PartialEq for Cost<$f> {
fn eq(&self, other: &Self) -> bool {
self.convert() == other.convert()
}
}
impl Eq for Cost<$f> {}
impl PartialOrd for Cost<$f> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.convert().partial_cmp(&other.convert())
}
}
impl Ord for Cost<$f> {
fn cmp(&self, other: &Self) -> Ordering {
self.convert().cmp(&other.convert())
}
}
impl Hash for Cost<$f> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.convert().hash(state);
}
}
impl Add for Cost<$f> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Cost(self.0 + rhs.0)
}
}
impl AddAssign for Cost<$f> {
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0;
}
}
impl Sub for Cost<$f> {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Cost(self.0 - rhs.0)
}
}
impl SubAssign for Cost<$f> {
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0;
}
}
impl Mul for Cost<$f> {
type Output = Self;
fn mul(self, rhs: Self) -> Self {
Cost(self.0 * rhs.0)
}
}
impl MulAssign for Cost<$f> {
fn mul_assign(&mut self, rhs: Self) {
self.0 *= rhs.0;
}
}
impl Div for Cost<$f> {
type Output = Self;
fn div(self, rhs: Self) -> Self {
Cost(self.0 / rhs.0)
}
}
impl DivAssign for Cost<$f> {
fn div_assign(&mut self, rhs: Self) {
self.0 /= rhs.0;
}
}
impl Zero for Cost<$f> {
fn zero() -> Self {
Cost(0.0)
}
fn set_zero(&mut self) {
self.0 = 0.0
}
fn is_zero(&self) -> bool {
self.0 == 0.0
}
}
};
}
cost_impl!(f32);
cost_impl!(f64);